From ccadad41eaa76c46b9d1d4b9899d0b446ca7524f Mon Sep 17 00:00:00 2001 From: Johannes Hauschild Date: Fri, 15 May 2026 14:07:20 +0200 Subject: [PATCH 1/9] add update-db-migration.sh script --- Dockerfile | 4 ++-- scripts/docker-entrypoint.sh | 9 +++++++- scripts/update-db-migration.sh | 40 ++++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 3 deletions(-) create mode 100755 scripts/update-db-migration.sh diff --git a/Dockerfile b/Dockerfile index 51b5990..a69bfe9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -121,7 +121,7 @@ RUN sed -i "s/user = nobody/user = phpbb/g" /etc/php${PHP_VERSION}/php-fpm.d/www chown phpbb:phpbb /run/nginx.pid # Copy scripts and configurations -COPY scripts/install-phpbb.sh scripts/docker-entrypoint.sh scripts/install-from-yml.sh /opt/.docker/ +COPY scripts/install-phpbb.sh scripts/docker-entrypoint.sh scripts/install-from-yml.sh scripts/update-db-migration.sh /opt/.docker/ COPY config/nginx.conf /etc/nginx/http.d/default.conf # Download and install phpBB during the build @@ -190,4 +190,4 @@ HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 \ USER phpbb ENTRYPOINT ["/opt/.docker/docker-entrypoint.sh"] -CMD ["nginx", "-g", "daemon off;"] \ No newline at end of file +CMD ["nginx", "-g", "daemon off;"] diff --git a/scripts/docker-entrypoint.sh b/scripts/docker-entrypoint.sh index f04e4fb..db584d4 100755 --- a/scripts/docker-entrypoint.sh +++ b/scripts/docker-entrypoint.sh @@ -88,10 +88,17 @@ configure_phpbb() { fi else log "phpBB already configured, skipping installation" + # Even if installation was skipped, ensure the install directory is removed INSTALL_DIR="${PHPBB_ROOT:-/opt/phpbb}/phpbb/install" if [ -d "$INSTALL_DIR" ]; then + log "install directory found: might be a persistent DB with a new docker image and mounted subvolumes only -> update database migration" + if ! /opt/.docker/update-db-migration.sh; then + log "ERROR: Failed to update and run database migration." + return 1 + fi + log "SECURITY: Removing phpBB install directory..." if rm -rf "$INSTALL_DIR"; then log "SECURITY: Successfully removed phpBB install directory" @@ -288,4 +295,4 @@ main() { } # Execute main function -main "$@" \ No newline at end of file +main "$@" diff --git a/scripts/update-db-migration.sh b/scripts/update-db-migration.sh new file mode 100755 index 0000000..f03c3d3 --- /dev/null +++ b/scripts/update-db-migration.sh @@ -0,0 +1,40 @@ +#!/bin/sh +set -eu +log() { echo "[$(hostname)] $1"; } +trap 'log "ERROR at line $LINENO"; [ -n "${TEMP_DIR:-}" ] && rm -rf "$TEMP_DIR"' ERR + +# Check required vars and fail fast +PHPBB_ROOT="${PHPBB_ROOT:-/opt/phpbb}" + +# Find PHP and create temp dir +PHP_EXECUTABLE=$(command -v "php${PHP_VERSION:-}" 2>/dev/null || command -v php || { log "ERROR: PHP not found"; exit 1; }) +TEMP_DIR=$(mktemp -d) && chmod 700 "$TEMP_DIR" && CONFIG_YML="${TEMP_DIR}/update-config.yml" + +# Generate YAML config - more readable format +cat > "$CONFIG_YML" << EOF +updater: + type: db_only + +EOF +chmod 600 "$CONFIG_YML" + +# Run installer & cleanup +cd "${PHPBB_ROOT}/phpbb" || { log "ERROR: Cannot access ${PHPBB_ROOT}/phpbb"; exit 1; } +[ ! -f "install/phpbbcli.php" ] && log "ERROR: CLI installer missing" && exit 1 + +$PHP_EXECUTABLE install/phpbbcli.php update "$CONFIG_YML" +RESULT=$? + +# Check if config file was properly created +if [ ! $RESULT -eq 0 ]; then + log "ERROR: 'php install/phpbbcli.php update $CONFIG_YML' failed with return code $RESULT" +fi + +# Only remove install directory if installation was successful +if [ $RESULT -eq 0 ] && [ -d "install" ]; then + rm -rf "install" + log "SECURITY: Removed install dir after successful installation" +fi + +[ -n "${TEMP_DIR:-}" ] && rm -rf "$TEMP_DIR" +exit $RESULT From f6e34388d670c97c8eefd253d79fea07b9332dcb Mon Sep 17 00:00:00 2001 From: Johannes Hauschild Date: Fri, 15 May 2026 15:11:06 +0200 Subject: [PATCH 2/9] explain upgradepath in readme --- README.md | 38 ++++++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 3cc28fe..08304b1 100644 --- a/README.md +++ b/README.md @@ -100,7 +100,9 @@ persisted. ## Environment Variables -The following environment variables can be used to configure the phpBB installation: +The following environment variables can be used to configure the initial phpBB installation. +Note that only the PHP configuration variables have any effect if you already have +an existing `config.php` (with database connection information) and database from a previous installation. ### Forum Configuration @@ -166,7 +168,7 @@ The following environment variables can be used to configure the phpBB installat There are two main approaches to persist your phpBB data: -### 1. Simple Volume Mounting (Recommended) +### 1. Simple Volume Mounting Mount a single volume to keep everything in one place: @@ -182,24 +184,44 @@ docker run -d \ evandarwin/phpbb:latest ``` -### 2. Granular Control with Multiple Volumes +### 2. Granular Control with Multiple Volumes (Upgrade Path) For more control over specific data directories: ```bash docker run -d \ -p 8080:8080 \ - -v phpbb_config:/opt/phpbb/config \ - -v phpbb_store:/opt/phpbb/store \ - -v phpbb_files:/opt/phpbb/files \ - -v phpbb_images:/opt/phpbb/images \ - -v phpbb_ext:/opt/phpbb/ext \ + -v ./config.php:/opt/phpbb/phpbb/config.php \ + -v phpbb_store:/opt/phpbb/phpbb/store \ + -v phpbb_files:/opt/phpbb/phpbb/files \ + -v phpbb_images:/opt/phpbb/phpbb/images \ + -v phpbb_ext:/opt/phpbb/phpbb/ext \ + -v phpbb_style:/opt/phpbb/phpbb/styles \ -e PHPBB_DATABASE_HOST="db" \ -e PHPBB_DATABASE_NAME="phpbb" \ -e PHPBB_DATABASE_USER="phpbb" \ -e PHPBB_DATABASE_PASSWORD="secret" \ evandarwin/phpbb:latest ``` +The `store`, `files` and `images` folders should be persisted; adding `ext` and `styles` folders gives you the option to install custom extensions and styles. + + +The `config.php` needs to be a local file with initial write permissions for the first setup. The write permissions need to be for the phpbb user in the container, likely UID 100, GUID 101, see also [Issue #3](https://github.com/EvanDarwin/phpbb-docker/issues/3). +Once the initial installation ran and setup created the database tables and `config.php`, the `config.php` can also be mounted read-only: +```bash +docker ... -v ./config.php:/opt/phpbb/phpbb/config.php:ro ... +``` + +If you have (a backup of) an existing installation with database and config.php, you can restore these folders and the database from there. + + +## Upgrade path +If you mount the full `/opt/phpbb` folder persistently (option 1 above), the docker container will not upgrade to new versions correctly (at least as of now). + +However, if you choose option 2 to mount only the `config.php` and folders `store`, `files` and `images` persistently, and optionally `ext` and `styles`, +then upgrading the docker volume is equivalent to a [full upgrade](https://www.phpbb.com/support/docs/en/3.3/ug/upgradeguide/update_full/). + +In that case, upgrading the docker container will also perform the database migration automatically. ## Custom PHP Configuration From 578f0aa5f400074e5668015fc4583fb0fbae143b Mon Sep 17 00:00:00 2001 From: Johannes Hauschild Date: Fri, 15 May 2026 16:59:06 +0200 Subject: [PATCH 3/9] fill emtpy subfolder volumes if needed --- Dockerfile | 1 + scripts/docker-entrypoint.sh | 7 ++++- scripts/install-phpbb.sh | 51 ++++++++++++++++++++++++++---------- 3 files changed, 44 insertions(+), 15 deletions(-) diff --git a/Dockerfile b/Dockerfile index a69bfe9..a68a54f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -80,6 +80,7 @@ RUN apk update && \ apk add --no-cache \ nginx \ curl \ + rsync \ unzip \ libcap \ ca-certificates \ diff --git a/scripts/docker-entrypoint.sh b/scripts/docker-entrypoint.sh index db584d4..ae2df35 100755 --- a/scripts/docker-entrypoint.sh +++ b/scripts/docker-entrypoint.sh @@ -67,7 +67,12 @@ setup_php_version() { # Install phpBB if not already installed install_phpbb() { - if [ ! -f "${PHPBB_ROOT:-/opt/phpbb}/phpbb/index.php" ]; then + if [ ! -f "${PHPBB_ROOT:-/opt/phpbb}/phpbb/index.php" ] || \ + [ ! -f "${PHPBB_ROOT:-/opt/phpbb}/store/index.htm" ] || \ + [ ! -f "${PHPBB_ROOT:-/opt/phpbb}/files/index.htm" ] || \ + [ ! -f "${PHPBB_ROOT:-/opt/phpbb}/images/index.htm" ] || \ + [ ! -f "${PHPBB_ROOT:-/opt/phpbb}/ext/index.htm" ] || \ + [ ! -d "${PHPBB_ROOT:-/opt/phpbb}/styles/all/" ] ; then log "phpBB files not found at ${PHPBB_ROOT:-/opt/phpbb}/phpbb, running install script..." if ! /opt/.docker/install-phpbb.sh "${PHPBB_VERSION}"; then log "ERROR: Failed to install phpBB. Exiting container." diff --git a/scripts/install-phpbb.sh b/scripts/install-phpbb.sh index 796392a..9c5e135 100755 --- a/scripts/install-phpbb.sh +++ b/scripts/install-phpbb.sh @@ -144,31 +144,54 @@ extract_phpbb_files() { return 0 } -# Move phpBB files to the destination directory with better error handling -move_files_to_destination() { - log "Moving files to destination directory: $PHPBB_ROOT/phpbb" - - # Ensure destination directory exists - mkdir -p "$PHPBB_ROOT/phpbb" || { log "ERROR: Failed to create phpBB root directory"; return 1; } - +robust_copy () { # Move files to destination with rsync if available for better handling of existing files + log "copy from $1 to $2" if command -v rsync >/dev/null 2>&1; then - log "Using rsync to copy files..." - if ! rsync -a "$TMP_DIR/phpBB3/" "$PHPBB_ROOT/phpbb/"; then + if ! rsync -a "$1" "$2"; then log "ERROR: Failed to rsync phpBB files to destination directory" return 1 fi else # Fallback to cp if rsync is not available - log "Rsync not available, using cp..." - if ! cp -a "$TMP_DIR/phpBB3/"* "$PHPBB_ROOT/phpbb/"; then + log "Rsync not available, using cp -a ..." + if ! cp -a "${1%/}" "${2%/}"; then log "ERROR: Failed to copy phpBB files to destination directory" return 1 fi fi +} + +# Move phpBB files to the destination directory with better error handling +move_files_to_destination() { + log "Moving files to destination directory: $PHPBB_ROOT/phpbb" + + # Ensure destination directory exists + mkdir -p "$PHPBB_ROOT/phpbb" || { log "ERROR: Failed to create phpBB root directory"; return 1; } + + if [ ! -f "$PHPBB_ROOT/phpbb/index.php" ] ; then + robust_copy "$TMP_DIR/phpBB3/" "$PHPBB_ROOT/phpbb/" + else + # check for docker volumes mounted to subfolders that need to be populated + if [ ! -f "$PHPBB_ROOT/store/index.htm" ] ; then + robust_copy "$TMP_DIR/phpBB3/store/" "$PHPBB_ROOT/phpbb/store/" + fi + if [ ! -f "$PHPBB_ROOT/files/index.htm" ] ; then + robust_copy "$TMP_DIR/phpBB3/files/" "$PHPBB_ROOT/phpbb/files/" + fi + if [ ! -f "$PHPBB_ROOT/images/index.htm" ] ; then + robust_copy "$TMP_DIR/phpBB3/images/" "$PHPBB_ROOT/phpbb/images/" + fi + if [ ! -f "$PHPBB_ROOT/ext/index.htm" ] ; then + robust_copy "$TMP_DIR/phpBB3/ext/" "$PHPBB_ROOT/phpbb/ext/" + fi + if [ ! -d "$PHPBB_ROOT/styles/all/" ] ; then + robust_copy "$TMP_DIR/phpBB3/styles/" "$PHPBB_ROOT/phpbb/styles/" + fi + fi - # Create config directory and empty config.php file - mkdir -p "$PHPBB_ROOT/phpbb/config" || { log "ERROR: Failed to create config directory"; return 1; } + # Create empty config.php file to ensure we can set permissions + # (config folder needs to to be overwritten) touch "$PHPBB_ROOT/phpbb/config/config.php" || { log "ERROR: Failed to create config.php file"; return 1; } log "Files moved successfully to $PHPBB_ROOT/phpbb" @@ -261,4 +284,4 @@ main() { } # Execute main function with proper error handling and all arguments -main "$@" \ No newline at end of file +main "$@" From 3cda2b2e5e7114c3409718fb4769aae1b27ae5c7 Mon Sep 17 00:00:00 2001 From: Johannes Hauschild Date: Fri, 15 May 2026 19:04:37 +0200 Subject: [PATCH 4/9] allow to keep config.php in a separate directory and copy to/from there --- Dockerfile | 5 +-- README.md | 16 ++++----- docker-compose.yml | 68 ++++++++++++++++++++++++++++++++++++ scripts/build.sh | 4 +-- scripts/docker-entrypoint.sh | 52 ++++++++++++++++++++------- scripts/install-from-yml.sh | 5 ++- 6 files changed, 124 insertions(+), 26 deletions(-) create mode 100644 docker-compose.yml diff --git a/Dockerfile b/Dockerfile index a68a54f..b78383f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -146,7 +146,7 @@ RUN if [ -z "${PHPBB_VERSION}" ]; then \ mkdir -p ${PHPBB_ROOT}/phpbb && \ mv "phpBB3"/* ${PHPBB_ROOT}/phpbb/ && \ rm -rf "phpBB3" && \ - mkdir -p ${PHPBB_ROOT}/phpbb/config && \ + mkdir -p ${PHPBB_ROOT}/config && \ touch ${PHPBB_ROOT}/phpbb/config/config.php && \ chown -R phpbb:phpbb ${PHPBB_ROOT} && \ # Set base permissions @@ -154,7 +154,8 @@ RUN if [ -z "${PHPBB_VERSION}" ]; then \ mkdir -p ${PHPBB_ROOT}/phpbb/images/avatars/uploads && \ # Set writable directory permissions chmod -v 0770 ${PHPBB_ROOT}/phpbb/store ${PHPBB_ROOT}/phpbb/cache ${PHPBB_ROOT}/phpbb/files ${PHPBB_ROOT}/phpbb/images/avatars/uploads/ && \ - chmod 0640 ${PHPBB_ROOT}/phpbb/config/config.php && \ + chmod -v 0640 ${PHPBB_ROOT}/config && \ + chmod -v 0640 ${PHPBB_ROOT}/phpbb/config/config.php && \ # Set subdirectory permissions find ${PHPBB_ROOT}/phpbb/cache -type d -exec chmod 750 {} \; && \ find ${PHPBB_ROOT}/phpbb/store -type d -exec chmod 750 {} \; 2>/dev/null || true && \ diff --git a/README.md b/README.md index 08304b1..453bc33 100644 --- a/README.md +++ b/README.md @@ -191,7 +191,7 @@ For more control over specific data directories: ```bash docker run -d \ -p 8080:8080 \ - -v ./config.php:/opt/phpbb/phpbb/config.php \ + -v phpbb_config:/opt/phpbb/config \ -v phpbb_store:/opt/phpbb/phpbb/store \ -v phpbb_files:/opt/phpbb/phpbb/files \ -v phpbb_images:/opt/phpbb/phpbb/images \ @@ -203,17 +203,17 @@ docker run -d \ -e PHPBB_DATABASE_PASSWORD="secret" \ evandarwin/phpbb:latest ``` +Here, the /opt/phpbb/config directory is used to persist the `config.php` file only, it is copied to/from there during container startup/installation. The `store`, `files` and `images` folders should be persisted; adding `ext` and `styles` folders gives you the option to install custom extensions and styles. - -The `config.php` needs to be a local file with initial write permissions for the first setup. The write permissions need to be for the phpbb user in the container, likely UID 100, GUID 101, see also [Issue #3](https://github.com/EvanDarwin/phpbb-docker/issues/3). -Once the initial installation ran and setup created the database tables and `config.php`, the `config.php` can also be mounted read-only: +The `config.php` needs to be a local file with initial write permissions for the first setup. +The write permissions need to be for the phpbb user in the container, likely UID 100, GUID 101, see also [Issue #3](https://github.com/EvanDarwin/phpbb-docker/issues/3). +Once the initial installation ran and setup created the database tables and `config.php`, the `config` folder can also be mounted read-only: ```bash -docker ... -v ./config.php:/opt/phpbb/phpbb/config.php:ro ... +docker ... -v phpbb_config:/opt/phpbb/config:ro ... ``` -If you have (a backup of) an existing installation with database and config.php, you can restore these folders and the database from there. - +If you have (a backup of) an existing installation with database and config.php, you can restore these folders and the database from the backup. ## Upgrade path If you mount the full `/opt/phpbb` folder persistently (option 1 above), the docker container will not upgrade to new versions correctly (at least as of now). @@ -519,7 +519,7 @@ Kubernetes, or Docker Compose with health checks. 2. **Permission Issues**: - If mounting volumes, ensure they have the correct ownership and permissions - - The container uses a non-root user with UID/GID different from the host + - The container uses a non-root user with UID/GID different from the host, by default 100/101. 3. **PHP Configuration**: diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..7dce68b --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,68 @@ +volumes: + phpbb_config: + phpbb_files: + phpbb_store: + phpbb_images: + phpbb_ext: + phpbb_styles: + mysql_data: + +networks: + phpbb_net: + +services: + phpbb: + image: evandarwin/phpbb:latest + ports: + - '8080:8080' + environment: + - PHPBB_FORUM_NAME=My Amazing Forum + - PHPBB_FORUM_DESCRIPTION=Welcome to my phpBB forum + - PHPBB_USERNAME=admin + - PHPBB_PASSWORD=secure_password # <- CHANGE THIS! + - PHPBB_EMAIL=admin@example.com + - PHPBB_DATABASE_DRIVER=mysqli + - PHPBB_DATABASE_HOST=mysql + - PHPBB_DATABASE_NAME=phpbb + - PHPBB_DATABASE_USER=phpbb + - PHPBB_DATABASE_PASSWORD=mysql_password # <- CHANGE THIS! + - SERVER_NAME=forums.example.com + - COOKIE_SECURE=false + volumes: + - phpbb_config:/opt/phpbb/config # other path: no typo! should only contain config.php + - phpbb_files:/opt/phpbb/phpbb/files + - phpbb_store:/opt/phpbb/phpbb/store + - phpbb_images:/opt/phpbb/phpbb/images + - phpbb_ext:/opt/phpbb/phpbb/ext # optional + - phpbb_styles:/opt/phpbb/phpbb/styles # optional + depends_on: + - mysql + networks: + - phpbb_net + restart: unless-stopped + healthcheck: + test: ['CMD', 'curl', '-f', 'http://localhost:8080/'] + interval: 30s + timeout: 5s + retries: 3 + start_period: 30s + + mysql: + image: mysql:8.0 + environment: + - MYSQL_ROOT_PASSWORD=root_password # <- CHANGE THIS! + - MYSQL_DATABASE=phpbb + - MYSQL_USER=phpbb + - MYSQL_PASSWORD=mysql_password # <- CHANGE THIS! + volumes: + - mysql_data:/var/lib/mysql + networks: + - phpbb_net + restart: unless-stopped + healthcheck: + test: + ['CMD', 'mysqladmin', 'ping', '-h', 'localhost', '-u', 'root', '-p${MYSQL_ROOT_PASSWORD}'] + interval: 10s + timeout: 5s + retries: 3 + start_period: 30s diff --git a/scripts/build.sh b/scripts/build.sh index 3c6e818..bf53af5 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -101,5 +101,5 @@ log "==> Build complete!" # Display success message log "==> All builds complete!" -log "To run the container: docker run -p 80:80 $DOCKER_IMAGE:" -log "Available tags: $VERSION, $MINOR_VERSION, $MAJOR_VERSION, latest" \ No newline at end of file +log "To run the container: docker run -p 8080:8080 $DOCKER_IMAGE:" +log "Available tags: $VERSION, $MINOR_VERSION, $MAJOR_VERSION, latest" diff --git a/scripts/docker-entrypoint.sh b/scripts/docker-entrypoint.sh index ae2df35..452eba9 100755 --- a/scripts/docker-entrypoint.sh +++ b/scripts/docker-entrypoint.sh @@ -1,6 +1,8 @@ #!/bin/sh set -eu +PHPBB_ROOT=$PHPBB_ROOT + log() { echo "[$(hostname)] $1" } @@ -35,7 +37,7 @@ validate_environment() { fi # Conditionally required variables - if [ ! -f "${PHPBB_ROOT:-/opt/phpbb}/phpbb/index.php" ] && [ -z "${PHPBB_VERSION:-}" ]; then + if [ ! -f "${PHPBB_ROOT}/phpbb/index.php" ] && [ -z "${PHPBB_VERSION:-}" ]; then log "ERROR: PHPBB_VERSION environment variable is required for initial installation" missing_vars=$((missing_vars + 1)) fi @@ -67,13 +69,13 @@ setup_php_version() { # Install phpBB if not already installed install_phpbb() { - if [ ! -f "${PHPBB_ROOT:-/opt/phpbb}/phpbb/index.php" ] || \ - [ ! -f "${PHPBB_ROOT:-/opt/phpbb}/store/index.htm" ] || \ - [ ! -f "${PHPBB_ROOT:-/opt/phpbb}/files/index.htm" ] || \ - [ ! -f "${PHPBB_ROOT:-/opt/phpbb}/images/index.htm" ] || \ - [ ! -f "${PHPBB_ROOT:-/opt/phpbb}/ext/index.htm" ] || \ - [ ! -d "${PHPBB_ROOT:-/opt/phpbb}/styles/all/" ] ; then - log "phpBB files not found at ${PHPBB_ROOT:-/opt/phpbb}/phpbb, running install script..." + if [ ! -f "$PHPBB_ROOT/phpbb/index.php" ] || \ + [ ! -f "$PHPBB_ROOT/phpbb/store/index.htm" ] || \ + [ ! -f "$PHPBB_ROOT/phpbb/files/index.htm" ] || \ + [ ! -f "$PHPBB_ROOT/phpbb/images/index.htm" ] || \ + [ ! -f "$PHPBB_ROOT/phpbb/ext/index.htm" ] || \ + [ ! -d "$PHPBB_ROOT/phpbb/styles/all/" ] ; then + log "phpBB files not found at $PHPBB_ROOT/phpbb, running install script..." if ! /opt/.docker/install-phpbb.sh "${PHPBB_VERSION}"; then log "ERROR: Failed to install phpBB. Exiting container." return 1 @@ -82,10 +84,34 @@ install_phpbb() { return 0 } +# allow to keep config.php in separate $PHPBB_ROOT/config folder +# copying from there at startup and copying back in `install-from-yml.sh` +copy_config_php() { + mkdir -p "$PHPBB_ROOT/phpbb" + if [ -f "$PHPBB_ROOT/config/config.php" ] ; then + log "copy $PHPBB_ROOT/config/config.php to phpbb installation" + # Double-check config/config.php permissions + chmod 640 "$PHPBB_ROOT/config/config.php" || { + log "ERROR: Failed to set $PHPBB_ROOT/phpbb/config.php permissions" + return 1 + } + if ! cp "$PHPBB_ROOT/config/config.php" "$PHPBB_ROOT/phpbb/config.php" ; then + log "ERROR: couldn't copy $PHPBB_ROOT config/config.php to phpbb/config.php" + return 1 + fi + # Double-check phpbb/config.php permissions again + chmod 640 "$PHPBB_ROOT/phpbb/config.php" || { + log "ERROR: Failed to set $PHPBB_ROOT/phpbb/config.php permissions" + return 1 + } + fi + return 0 +} + # Configure phpBB if not already configured configure_phpbb() { # Check if config.php exists and is not empty - if [ ! -f "${PHPBB_ROOT:-/opt/phpbb}/phpbb/config.php" ] || [ ! -s "${PHPBB_ROOT:-/opt/phpbb}/phpbb/config.php" ]; then + if [ ! -f "$PHPBB_ROOT/phpbb/config.php" ] || [ ! -s "$PHPBB_ROOT/phpbb/config.php" ]; then log "Configuration file not found or is empty, running YML-based installer..." if ! /opt/.docker/install-from-yml.sh; then log "ERROR: Failed to configure phpBB. Exiting container." @@ -94,14 +120,13 @@ configure_phpbb() { else log "phpBB already configured, skipping installation" - # Even if installation was skipped, ensure the install directory is removed - INSTALL_DIR="${PHPBB_ROOT:-/opt/phpbb}/phpbb/install" + INSTALL_DIR="$PHPBB_ROOT/phpbb/install" if [ -d "$INSTALL_DIR" ]; then - log "install directory found: might be a persistent DB with a new docker image and mounted subvolumes only -> update database migration" + log "install directory found: likely a new docker image/installation and mounted subvolumes only -> update database migration" if ! /opt/.docker/update-db-migration.sh; then log "ERROR: Failed to update and run database migration." - return 1 + return 1 fi log "SECURITY: Removing phpBB install directory..." @@ -284,6 +309,7 @@ main() { # Install and configure phpBB install_phpbb || exit 1 + copy_config_php || exit 1 configure_phpbb || exit 1 apply_custom_php_ini || exit 1 diff --git a/scripts/install-from-yml.sh b/scripts/install-from-yml.sh index 66d7719..496ebd3 100755 --- a/scripts/install-from-yml.sh +++ b/scripts/install-from-yml.sh @@ -285,6 +285,9 @@ if [ $RESULT -eq 0 ] && [ ! -s "$CONFIG_FILE" ]; then log "ERROR: Installation completed but config/config.php is empty or missing" log " This indicates that the installation process failed to write configuration data" RESULT=1 +else + # copy config.php to $PHPBB_ROOT/config/ folder that was possibly mounted as persistent + cp -p "${PHPBB_ROOT}/phpbb/config.php" "${PHPBB_ROOT}/config/config.php" fi # Only remove install directory if installation was successful @@ -294,4 +297,4 @@ if [ $RESULT -eq 0 ] && [ -d "install" ]; then fi [ -n "${TEMP_DIR:-}" ] && rm -rf "$TEMP_DIR" -exit $RESULT \ No newline at end of file +exit $RESULT From b851ea4ee427e54ce4eceb2cd8da0bb1bf8798c1 Mon Sep 17 00:00:00 2001 From: Johannes Hauschild Date: Sat, 16 May 2026 03:08:45 +0200 Subject: [PATCH 5/9] fix config dir permissions --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index b78383f..c13f2fc 100644 --- a/Dockerfile +++ b/Dockerfile @@ -154,7 +154,7 @@ RUN if [ -z "${PHPBB_VERSION}" ]; then \ mkdir -p ${PHPBB_ROOT}/phpbb/images/avatars/uploads && \ # Set writable directory permissions chmod -v 0770 ${PHPBB_ROOT}/phpbb/store ${PHPBB_ROOT}/phpbb/cache ${PHPBB_ROOT}/phpbb/files ${PHPBB_ROOT}/phpbb/images/avatars/uploads/ && \ - chmod -v 0640 ${PHPBB_ROOT}/config && \ + chmod -v 0750 ${PHPBB_ROOT}/config && \ chmod -v 0640 ${PHPBB_ROOT}/phpbb/config/config.php && \ # Set subdirectory permissions find ${PHPBB_ROOT}/phpbb/cache -type d -exec chmod 750 {} \; && \ From f248fdbffbc9c7b01e0c0874437345407aa53a9c Mon Sep 17 00:00:00 2001 From: Johannes Hauschild Date: Sat, 16 May 2026 03:22:23 +0200 Subject: [PATCH 6/9] check db connection before install: it's needed for initial setup give it a second chance during install-from-yml.sh --- scripts/docker-entrypoint.sh | 5 +++-- scripts/install-from-yml.sh | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/scripts/docker-entrypoint.sh b/scripts/docker-entrypoint.sh index 452eba9..b83fb48 100755 --- a/scripts/docker-entrypoint.sh +++ b/scripts/docker-entrypoint.sh @@ -307,14 +307,15 @@ main() { validate_environment || exit 1 setup_php_version || exit 1 + # Check database connectivity + check_database_connectivity || exit 1 + # Install and configure phpBB install_phpbb || exit 1 copy_config_php || exit 1 configure_phpbb || exit 1 apply_custom_php_ini || exit 1 - # Check database connectivity - check_database_connectivity || exit 1 # Setup logging and start services setup_log_forwarding || exit 1 diff --git a/scripts/install-from-yml.sh b/scripts/install-from-yml.sh index 496ebd3..9721f92 100755 --- a/scripts/install-from-yml.sh +++ b/scripts/install-from-yml.sh @@ -227,7 +227,7 @@ COOKIE_SECURE="${COOKIE_SECURE:-false}" # Validate database config and test connection before installation validate_db_config || exit 1 -test_db_connection || exit 1 +test_db_connection || sleep 10 && test_db_connection || exit 1 # Generate YAML config - more readable format cat > "$CONFIG_YML" << EOF From 64f36d9f3d5fe9e806c03791c45acbcbc54c0139 Mon Sep 17 00:00:00 2001 From: Johannes Hauschild Date: Sat, 16 May 2026 03:36:01 +0200 Subject: [PATCH 7/9] update README and add working example docker-compose.yml file --- README.md | 81 ++++++++++++++++++++++++++-------------------- docker-compose.yml | 53 ++++++++++++++---------------- 2 files changed, 70 insertions(+), 64 deletions(-) diff --git a/README.md b/README.md index 453bc33..2273a3e 100644 --- a/README.md +++ b/README.md @@ -216,12 +216,12 @@ docker ... -v phpbb_config:/opt/phpbb/config:ro ... If you have (a backup of) an existing installation with database and config.php, you can restore these folders and the database from the backup. ## Upgrade path -If you mount the full `/opt/phpbb` folder persistently (option 1 above), the docker container will not upgrade to new versions correctly (at least as of now). +If you mount the full `/opt/phpbb` folder persistently (option 1 above), the docker container will not upgrade to new versions correctly (at least as of now), since the volume mount hides the updated forum files of the container. However, if you choose option 2 to mount only the `config.php` and folders `store`, `files` and `images` persistently, and optionally `ext` and `styles`, then upgrading the docker volume is equivalent to a [full upgrade](https://www.phpbb.com/support/docs/en/3.3/ug/upgradeguide/update_full/). -In that case, upgrading the docker container will also perform the database migration automatically. +In that case, the container is setup to automatically perform database migrations as well on startup. ## Custom PHP Configuration @@ -329,7 +329,18 @@ specify a version. Here's a complete example using Docker Compose with MySQL: ```yaml -version: '3.8' +volumes: + phpbb_config: + phpbb_files: + phpbb_store: + phpbb_images: + phpbb_ext: + phpbb_styles: + mysql_data: + +networks: + phpbb-net: + driver: bridge services: phpbb: @@ -337,20 +348,25 @@ services: ports: - '8080:8080' environment: - - PHPBB_FORUM_NAME=My Amazing Forum - - PHPBB_FORUM_DESCRIPTION=Welcome to my phpBB forum - - PHPBB_USERNAME=admin - - PHPBB_PASSWORD=secure_password - - PHPBB_EMAIL=admin@example.com - - PHPBB_DATABASE_DRIVER=mysqli - - PHPBB_DATABASE_HOST=mysql - - PHPBB_DATABASE_NAME=phpbb - - PHPBB_DATABASE_USER=phpbb - - PHPBB_DATABASE_PASSWORD=mysql_password - - SERVER_NAME=forums.example.com - - COOKIE_SECURE=false + PHPBB_FORUM_NAME: My Amazing Forum + PHPBB_FORUM_DESCRIPTION: Welcome to my phpBB forum + PHPBB_USERNAME: admin + PHPBB_PASSWORD: secure_password # <- CHANGE THIS! + PHPBB_EMAIL: admin@example.com + PHPBB_DATABASE_DRIVER: mysqli + PHPBB_DATABASE_HOST: mysql + PHPBB_DATABASE_NAME: phpbb + PHPBB_DATABASE_USER: phpbb + PHPBB_DATABASE_PASSWORD: mysql_password # <- CHANGE THIS! + SERVER_NAME: forums.example.com + COOKIE_SECURE: false volumes: - - phpbb_data:/opt/phpbb + - phpbb_config:/opt/phpbb/config # other path: no typo! should only contain config.php + - phpbb_files:/opt/phpbb/phpbb/files + - phpbb_store:/opt/phpbb/phpbb/store + - phpbb_images:/opt/phpbb/phpbb/images + - phpbb_ext:/opt/phpbb/phpbb/ext # optional + - phpbb_styles:/opt/phpbb/phpbb/styles # optional depends_on: - mysql restart: unless-stopped @@ -360,28 +376,21 @@ services: timeout: 5s retries: 3 start_period: 30s + networks: + - phpbb-net mysql: - image: mysql:8.0 + image: mariadb:latest environment: - - MYSQL_ROOT_PASSWORD=root_password - - MYSQL_DATABASE=phpbb - - MYSQL_USER=phpbb - - MYSQL_PASSWORD=mysql_password + MARIADB_RANDOM_ROOT_PASSWORD: yes + MARIADB_DATABASE: phpbb + MARIADB_USER: phpbb + MARIADB_PASSWORD: mysql_password # <- CHANGE THIS! volumes: - mysql_data:/var/lib/mysql restart: unless-stopped - healthcheck: - test: - ['CMD', 'mysqladmin', 'ping', '-h', 'localhost', '-u', 'root', '-p${MYSQL_ROOT_PASSWORD}'] - interval: 10s - timeout: 5s - retries: 3 - start_period: 30s - -volumes: - phpbb_data: - mysql_data: + networks: + - phpbb-net ``` For PostgreSQL, replace the MySQL service with: @@ -390,9 +399,9 @@ For PostgreSQL, replace the MySQL service with: postgres: image: postgres:15 environment: - - POSTGRES_PASSWORD=postgres_password - - POSTGRES_USER=phpbb - - POSTGRES_DB=phpbb + POSTGRES_PASSWORD: postgres_password + POSTGRES_USER: phpbb + POSTGRES_DB: phpbb volumes: - postgres_data:/var/lib/postgresql/data restart: unless-stopped @@ -520,6 +529,8 @@ Kubernetes, or Docker Compose with health checks. - If mounting volumes, ensure they have the correct ownership and permissions - The container uses a non-root user with UID/GID different from the host, by default 100/101. + - Docker populates *empty* volumes (but not mounts!) with the pre-existing folders. + - Use a different entrypoint, e.g. `docker compose run --entrypoint sh -it phpbb` to trouble-shoot permissions in the volumes. 3. **PHP Configuration**: diff --git a/docker-compose.yml b/docker-compose.yml index 7dce68b..5818f6e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -8,7 +8,8 @@ volumes: mysql_data: networks: - phpbb_net: + phpbb-net: + driver: bridge services: phpbb: @@ -16,18 +17,18 @@ services: ports: - '8080:8080' environment: - - PHPBB_FORUM_NAME=My Amazing Forum - - PHPBB_FORUM_DESCRIPTION=Welcome to my phpBB forum - - PHPBB_USERNAME=admin - - PHPBB_PASSWORD=secure_password # <- CHANGE THIS! - - PHPBB_EMAIL=admin@example.com - - PHPBB_DATABASE_DRIVER=mysqli - - PHPBB_DATABASE_HOST=mysql - - PHPBB_DATABASE_NAME=phpbb - - PHPBB_DATABASE_USER=phpbb - - PHPBB_DATABASE_PASSWORD=mysql_password # <- CHANGE THIS! - - SERVER_NAME=forums.example.com - - COOKIE_SECURE=false + PHPBB_FORUM_NAME: My Amazing Forum + PHPBB_FORUM_DESCRIPTION: Welcome to my phpBB forum + PHPBB_USERNAME: admin + PHPBB_PASSWORD: secure_password # <- CHANGE THIS! + PHPBB_EMAIL: admin@example.com + PHPBB_DATABASE_DRIVER: mysqli + PHPBB_DATABASE_HOST: mysql + PHPBB_DATABASE_NAME: phpbb + PHPBB_DATABASE_USER: phpbb + PHPBB_DATABASE_PASSWORD: mysql_password # <- CHANGE THIS! + SERVER_NAME: forums.example.com + COOKIE_SECURE: false volumes: - phpbb_config:/opt/phpbb/config # other path: no typo! should only contain config.php - phpbb_files:/opt/phpbb/phpbb/files @@ -37,8 +38,6 @@ services: - phpbb_styles:/opt/phpbb/phpbb/styles # optional depends_on: - mysql - networks: - - phpbb_net restart: unless-stopped healthcheck: test: ['CMD', 'curl', '-f', 'http://localhost:8080/'] @@ -46,23 +45,19 @@ services: timeout: 5s retries: 3 start_period: 30s + networks: + - phpbb-net mysql: - image: mysql:8.0 + image: mariadb:latest environment: - - MYSQL_ROOT_PASSWORD=root_password # <- CHANGE THIS! - - MYSQL_DATABASE=phpbb - - MYSQL_USER=phpbb - - MYSQL_PASSWORD=mysql_password # <- CHANGE THIS! + MARIADB_RANDOM_ROOT_PASSWORD: yes + MARIADB_DATABASE: phpbb + MARIADB_USER: phpbb + MARIADB_PASSWORD: mysql_password # <- CHANGE THIS! volumes: - mysql_data:/var/lib/mysql - networks: - - phpbb_net restart: unless-stopped - healthcheck: - test: - ['CMD', 'mysqladmin', 'ping', '-h', 'localhost', '-u', 'root', '-p${MYSQL_ROOT_PASSWORD}'] - interval: 10s - timeout: 5s - retries: 3 - start_period: 30s + networks: + - phpbb-net + From 933c45d99ed10289f34ac33cba2c38b8a7640270 Mon Sep 17 00:00:00 2001 From: Johannes Hauschild Date: Sat, 16 May 2026 03:47:04 +0200 Subject: [PATCH 8/9] replace deprecated mysql command with mariadb command in the existing image, calling `mysql` gives the warning `mysql: Deprecated program name. It will be removed in a future release, use '/usr/bin/mariadb' instead` --- scripts/docker-entrypoint.sh | 4 ++-- scripts/install-from-yml.sh | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/scripts/docker-entrypoint.sh b/scripts/docker-entrypoint.sh index b83fb48..cf529a5 100755 --- a/scripts/docker-entrypoint.sh +++ b/scripts/docker-entrypoint.sh @@ -236,9 +236,9 @@ check_database_connectivity() { fi # Try connecting to MySQL with appropriate arguments - if command -v mysql >/dev/null 2>&1; then + if command -v mariadb >/dev/null 2>&1; then log "Testing MySQL connection to $db_host..." - if ! mysql -h "$db_host" ${db_port:+-P "$db_port"} -u "$db_user" ${db_pass:+-p"$db_pass"} -e "SELECT 1" >/dev/null 2>&1; then + if ! mariadb -h "$db_host" ${db_port:+-P "$db_port"} -u "$db_user" ${db_pass:+-p"$db_pass"} -e "SELECT 1" >/dev/null 2>&1; then log "WARNING: Could not connect to MySQL server at $db_host. phpBB may not function correctly!" result=0 # Don't fail the container, just warn else diff --git a/scripts/install-from-yml.sh b/scripts/install-from-yml.sh index 9721f92..d8273ca 100755 --- a/scripts/install-from-yml.sh +++ b/scripts/install-from-yml.sh @@ -95,21 +95,21 @@ test_db_connection() { # Set default MySQL port if not specified [ -z "$port" ] && port="3306" - if command -v mysql > /dev/null 2>&1; then + if command -v mariadb > /dev/null 2>&1; then log "Testing MySQL connection to $host:$port..." - if ! mysql -h "$host" -P "$port" -u "$user" ${pass:+-p"$pass"} -e "SELECT 1" > /dev/null 2>&1; then + if ! mariadb -h "$host" -P "$port" -u "$user" ${pass:+-p"$pass"} -e "SELECT 1" > /dev/null 2>&1; then log "ERROR: Failed to connect to MySQL database" return 1 fi # Test if database exists or we can create it - if ! mysql -h "$host" -P "$port" -u "$user" ${pass:+-p"$pass"} -e "USE \`$name\`" > /dev/null 2>&1; then + if ! mariadb -h "$host" -P "$port" -u "$user" ${pass:+-p"$pass"} -e "USE \`$name\`" > /dev/null 2>&1; then log "Database '$name' doesn't exist, will be created during installation" fi log "MySQL connection successful" else - log "WARNING: mysql client not found, skipping connection test" + log "WARNING: mariadb client not found, skipping connection test" fi ;; From f57ebc9c4a27316d04e250ba2581c8893cd3f596 Mon Sep 17 00:00:00 2001 From: Johannes Hauschild Date: Sun, 17 May 2026 14:24:20 +0200 Subject: [PATCH 9/9] allow to keep robots.txt in config dir as well --- scripts/docker-entrypoint.sh | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/scripts/docker-entrypoint.sh b/scripts/docker-entrypoint.sh index cf529a5..7116970 100755 --- a/scripts/docker-entrypoint.sh +++ b/scripts/docker-entrypoint.sh @@ -84,26 +84,28 @@ install_phpbb() { return 0 } -# allow to keep config.php in separate $PHPBB_ROOT/config folder +# allow to keep config.php and robots.txt in separate $PHPBB_ROOT/config folder # copying from there at startup and copying back in `install-from-yml.sh` copy_config_php() { mkdir -p "$PHPBB_ROOT/phpbb" if [ -f "$PHPBB_ROOT/config/config.php" ] ; then - log "copy $PHPBB_ROOT/config/config.php to phpbb installation" - # Double-check config/config.php permissions - chmod 640 "$PHPBB_ROOT/config/config.php" || { - log "ERROR: Failed to set $PHPBB_ROOT/phpbb/config.php permissions" - return 1 - } - if ! cp "$PHPBB_ROOT/config/config.php" "$PHPBB_ROOT/phpbb/config.php" ; then - log "ERROR: couldn't copy $PHPBB_ROOT config/config.php to phpbb/config.php" - return 1 - fi - # Double-check phpbb/config.php permissions again - chmod 640 "$PHPBB_ROOT/phpbb/config.php" || { - log "ERROR: Failed to set $PHPBB_ROOT/phpbb/config.php permissions" - return 1 - } + for CONFIGFILE in config.php robots.txt ; do + log "copy $PHPBB_ROOT/config/$CONFIGFILE to phpbb installation" + # update permissions + chmod 640 "$PHPBB_ROOT/config/$CONFIGFILE" || { + log "ERROR: Failed to set $PHPBB_ROOT/phpbb/$CONFIGFILE permissions" + return 1 + } + if ! cp "$PHPBB_ROOT/config/$CONFIGFILE" "$PHPBB_ROOT/phpbb/$CONFIGFILE" ; then + log "ERROR: couldn't copy $PHPBB_ROOT config/$CONFIGFILE to phpbb/$CONFIGFILE" + return 1 + fi + # Double-check permissions again + chmod 640 "$PHPBB_ROOT/phpbb/$CONFIGFILE" || { + log "ERROR: Failed to set $PHPBB_ROOT/phpbb/$CONFIGFILE permissions" + return 1 + } + done fi return 0 }