From 7bae300fd2e8a3e7d3df07233493328f775f1ef7 Mon Sep 17 00:00:00 2001 From: Benjamin Brummer Date: Mon, 13 Jan 2025 12:20:03 +0000 Subject: [PATCH 1/8] disable preload for artisan tinker --- debian/scripts/init.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/scripts/init.sh b/debian/scripts/init.sh index 8acc15d..4385791 100755 --- a/debian/scripts/init.sh +++ b/debian/scripts/init.sh @@ -62,7 +62,7 @@ if [ "$*" = 'supervisord -c /etc/supervisor/conf.d/supervisord.conf' ]; then # If first IN run, it needs to be initialized echo "Checking initialization status..." - IN_INIT=$(php artisan tinker --execute='echo Schema::hasTable("accounts") && !App\Models\Account::all()->first();') + IN_INIT=$(php -d opcache.preload='' artisan tinker --execute='echo Schema::hasTable("accounts") && !App\Models\Account::all()->first();') echo "IN_INIT value: $IN_INIT" if [ "$IN_INIT" = "1" ]; then From 44b460bf13bc0af1fd85417d2b7eba88826a048b Mon Sep 17 00:00:00 2001 From: Benjamin Brummer Date: Mon, 13 Jan 2025 12:22:01 +0000 Subject: [PATCH 2/8] php optimization opcache and realpath --- debian/php/php.ini | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/debian/php/php.ini b/debian/php/php.ini index 35c9074..2defb8d 100644 --- a/debian/php/php.ini +++ b/debian/php/php.ini @@ -1,15 +1,23 @@ [core] -# https://www.php.net/manual/en/ini.core.php -post_max_size = 10M -upload_max_filesize = 10M +; https://www.php.net/manual/en/ini.core.php +post_max_size=10M +upload_max_filesize=10M [opcache] -# https://www.php.net/manual/en/opcache.installation.php#opcache.installation.recommended +; https://www.php.net/manual/en/opcache.installation.php#opcache.installation.recommended opcache.enable_cli=1 -opcache.max_accelerated_files=4000 -opcache.revalidate_freq=60 [jit] -# https://wiki.php.net/rfc/jit_config_defaults +; https://wiki.php.net/rfc/jit_config_defaults opcache.jit=tracing opcache.jit_buffer_size=64M + +[extra] +; http://symfony.com/doc/current/performance.html +opcache.memory_consumption=256 +opcache.max_accelerated_files=20000 +opcache.preload=/var/www/html/preload.php +opcache.preload_user=www-data +opcache.validate_timestamps=0 +realpath_cache_size = 4096K +realpath_cache_ttl = 600 From 31eb278f0dde550a9e4f638e31f85b45d36a1561 Mon Sep 17 00:00:00 2001 From: Benjamin Brummer Date: Mon, 13 Jan 2025 12:30:06 +0000 Subject: [PATCH 3/8] prefer files from image --- debian/Dockerfile | 6 +++++- debian/docker-compose.yml | 6 +++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/debian/Dockerfile b/debian/Dockerfile index 2be80b5..6832427 100644 --- a/debian/Dockerfile +++ b/debian/Dockerfile @@ -43,7 +43,11 @@ RUN ( curl -sSLf https://github.com/mlocati/docker-php-extension-installer/relea @composer # Configure PHP -RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" +RUN ln -s "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" + +COPY php/php.ini /usr/local/etc/php/conf.d/invoiceninja.ini + +COPY php/php-fpm.ini /usr/local/etc/php-fpm.d/invoiceninja.conf # Copy scripts COPY rootfs / diff --git a/debian/docker-compose.yml b/debian/docker-compose.yml index e643610..7a9a0df 100644 --- a/debian/docker-compose.yml +++ b/debian/docker-compose.yml @@ -14,9 +14,9 @@ services: - ./.env volumes: - ./.env:/var/www/html/.env - - ./php/php.ini:/usr/local/etc/php/conf.d/zzz-php.ini:ro - - ./php/php-fpm.conf:/usr/local/etc/php-fpm.d/zzz-php-fpm.conf:ro - - ./supervisor/supervisord.conf:/etc/supervisor/conf.d/supervisord.conf:ro + # - ./php/php.ini:/usr/local/etc/php/conf.d/invoiceninja.ini:ro + # - ./php/php-fpm.conf:/usr/local/etc/php-fpm.d/invoiceninja.conf:ro + # - ./supervisor/supervisord.conf:/etc/supervisor/conf.d/supervisord.conf:ro - app_cache:/var/www/html/bootstrap/cache - app_public:/var/www/html/public - app_storage:/var/www/html/storage From d60bf3995076486c3e6e59611ddb8bde0676caeb Mon Sep 17 00:00:00 2001 From: Benjamin Brummer Date: Mon, 13 Jan 2025 12:52:28 +0000 Subject: [PATCH 4/8] set correct file-extension --- debian/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/Dockerfile b/debian/Dockerfile index 6832427..c6cd97f 100644 --- a/debian/Dockerfile +++ b/debian/Dockerfile @@ -47,7 +47,7 @@ RUN ln -s "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" COPY php/php.ini /usr/local/etc/php/conf.d/invoiceninja.ini -COPY php/php-fpm.ini /usr/local/etc/php-fpm.d/invoiceninja.conf +COPY php/php-fpm.conf /usr/local/etc/php-fpm.d/invoiceninja.conf # Copy scripts COPY rootfs / From 029bc57faca7e7decdddbf184b859b2e6ea3bcf6 Mon Sep 17 00:00:00 2001 From: Benjamin Brummer Date: Mon, 13 Jan 2025 13:09:33 +0000 Subject: [PATCH 5/8] download invoiceninja.tar.gz --- debian/Dockerfile | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/debian/Dockerfile b/debian/Dockerfile index c6cd97f..62422f0 100644 --- a/debian/Dockerfile +++ b/debian/Dockerfile @@ -16,15 +16,15 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ xfonts-wqy \ # Install google-chrome-stable(amd64)/chromium(arm64) && if [ "$(dpkg --print-architecture)" = "amd64" ]; then \ - mkdir -p /etc/apt/keyrings \ - && curl -fsSL https://dl.google.com/linux/linux_signing_key.pub | \ - gpg --dearmor -o /etc/apt/keyrings/google.gpg \ - && echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/google.gpg] https://dl.google.com/linux/chrome/deb/ stable main" > /etc/apt/sources.list.d/google-chrome.list \ - && apt-get update \ - && apt-get install -y --no-install-recommends google-chrome-stable; \ + mkdir -p /etc/apt/keyrings \ + && curl -fsSL https://dl.google.com/linux/linux_signing_key.pub | \ + gpg --dearmor -o /etc/apt/keyrings/google.gpg \ + && echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/google.gpg] https://dl.google.com/linux/chrome/deb/ stable main" > /etc/apt/sources.list.d/google-chrome.list \ + && apt-get update \ + && apt-get install -y --no-install-recommends google-chrome-stable; \ elif [ "$(dpkg --print-architecture)" = "arm64" ]; then \ - apt-get install -y --no-install-recommends \ - chromium; \ + apt-get install -y --no-install-recommends \ + chromium; \ fi \ # Create config directory for chromium/google-chrome-stable && mkdir /var/www/.config \ @@ -37,10 +37,10 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ # Install PHP extensions RUN ( curl -sSLf https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions -o - || echo 'return 1' ) | sh -s \ - ${php_require} \ - ${php_suggest} \ - ${php_extra} \ - @composer + ${php_require} \ + ${php_suggest} \ + ${php_extra} \ + @composer # Configure PHP RUN ln -s "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" @@ -58,10 +58,10 @@ WORKDIR /var/www/html # Setup InvoiceNinja RUN curl -s "https://api.github.com/repos/invoiceninja/invoiceninja/releases/latest" | \ - grep -o '"browser_download_url": "[^"]*invoiceninja.tar"' | \ - cut -d '"' -f 4 | \ - xargs curl -sL | \ - tar -oxz -C /var/www/html \ + grep -o '"browser_download_url": "[^"]*invoiceninja.tar.gz"' | \ + cut -d '"' -f 4 | \ + xargs curl -sL | \ + tar -xz --strip-components=1 -C /var/www/html \ && cp /var/www/html/resources/views/react/index.blade.php /var/www/html/public/index.html \ # File permissions && find /var/www/html/ -type f -exec chmod 644 {} \; \ From f2c5a1f8424beb95cef033a5f98c43303ad35fa2 Mon Sep 17 00:00:00 2001 From: Benjamin Brummer Date: Mon, 13 Jan 2025 13:11:50 +0000 Subject: [PATCH 6/8] composer is not needed, permissions are already correct in the image --- debian/Dockerfile | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/debian/Dockerfile b/debian/Dockerfile index 62422f0..5b7ac4d 100644 --- a/debian/Dockerfile +++ b/debian/Dockerfile @@ -39,8 +39,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ RUN ( curl -sSLf https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions -o - || echo 'return 1' ) | sh -s \ ${php_require} \ ${php_suggest} \ - ${php_extra} \ - @composer + ${php_extra} # Configure PHP RUN ln -s "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" @@ -62,14 +61,7 @@ RUN curl -s "https://api.github.com/repos/invoiceninja/invoiceninja/releases/lat cut -d '"' -f 4 | \ xargs curl -sL | \ tar -xz --strip-components=1 -C /var/www/html \ - && cp /var/www/html/resources/views/react/index.blade.php /var/www/html/public/index.html \ - # File permissions - && find /var/www/html/ -type f -exec chmod 644 {} \; \ - # Directory permissions - && find /var/www/html/ -type d -exec chmod 755 {} \; \ - # Install dependencies - && composer install --no-dev --no-scripts --no-autoloader \ - && composer dump-autoload --optimize \ + && ln -s /var/www/html/resources/views/react/index.blade.php /var/www/html/public/index.html \ && php artisan optimize \ && php artisan storage:link \ # Workaround for application updates From cb4120fc54d6d255bcb74754df6705aee3efda15 Mon Sep 17 00:00:00 2001 From: Benjamin Brummer Date: Mon, 13 Jan 2025 16:31:39 +0000 Subject: [PATCH 7/8] Multistage, single init.sh --- debian/Dockerfile | 47 +++++++++--------- .../docker-entrypoint-init.d/10-init-in.sh | 14 ------ debian/scripts/init.sh | 49 +++++-------------- debian/supervisor/supervisord.conf | 2 +- 4 files changed, 37 insertions(+), 75 deletions(-) delete mode 100644 debian/rootfs/docker-entrypoint-init.d/10-init-in.sh diff --git a/debian/Dockerfile b/debian/Dockerfile index 5b7ac4d..2979d6b 100644 --- a/debian/Dockerfile +++ b/debian/Dockerfile @@ -1,5 +1,25 @@ -FROM php:8.3-fpm AS base +ARG PHP=8.3 +FROM php:${PHP}-fpm AS prepare-app + +USER www-data + +RUN curl -s "https://api.github.com/repos/invoiceninja/invoiceninja/releases/latest" | \ + grep -o '"browser_download_url": "[^"]*invoiceninja.tar.gz"' | \ + cut -d '"' -f 4 | \ + xargs curl -sL | \ + tar -xz --strip-components=1 -C /var/www/html \ + && ln -s /var/www/html/resources/views/react/index.blade.php /var/www/html/public/index.html \ + && php -d opcache.preload='' artisan storage:link \ + # Workaround for application updates + && mv /var/www/html/public /tmp/public + +# ================== +# InvoiceNinja image +# ================== +FROM php:${PHP}-fpm + +# PHP modules ARG php_require="bcmath gd pdo_mysql zip" ARG php_suggest="exif imagick intl pcntl soap saxon-12.5.0" ARG php_extra="opcache" @@ -48,29 +68,12 @@ COPY php/php.ini /usr/local/etc/php/conf.d/invoiceninja.ini COPY php/php-fpm.conf /usr/local/etc/php-fpm.d/invoiceninja.conf -# Copy scripts -COPY rootfs / - -USER www-data - -WORKDIR /var/www/html +# Setup supervisor --chown=www-data:www-data +COPY supervisor/supervisord.conf /etc/supervisor/conf.d/supervisord.conf # Setup InvoiceNinja -RUN curl -s "https://api.github.com/repos/invoiceninja/invoiceninja/releases/latest" | \ - grep -o '"browser_download_url": "[^"]*invoiceninja.tar.gz"' | \ - cut -d '"' -f 4 | \ - xargs curl -sL | \ - tar -xz --strip-components=1 -C /var/www/html \ - && ln -s /var/www/html/resources/views/react/index.blade.php /var/www/html/public/index.html \ - && php artisan optimize \ - && php artisan storage:link \ - # Workaround for application updates - && mv /var/www/html/public /tmp/public - -USER root - -# Setup supervisor -COPY supervisor/supervisord.conf /etc/supervisor/conf.d/supervisord.conf +COPY --from=prepare-app /var/www/html /var/www/html +COPY --from=prepare-app /tmp/public /tmp/public # Add initialization script COPY --chmod=0755 scripts/init.sh /usr/local/bin/init.sh diff --git a/debian/rootfs/docker-entrypoint-init.d/10-init-in.sh b/debian/rootfs/docker-entrypoint-init.d/10-init-in.sh deleted file mode 100644 index 6c03b9d..0000000 --- a/debian/rootfs/docker-entrypoint-init.d/10-init-in.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -php artisan db:seed --force - -# Build up array of arguments... -if [ ! -z "${IN_USER_EMAIL}" ]; then - email="--email ${IN_USER_EMAIL}" -fi - -if [ ! -z "${IN_PASSWORD}" ]; then - password="--password ${IN_PASSWORD}" -fi - -php artisan ninja:create-account $email $password diff --git a/debian/scripts/init.sh b/debian/scripts/init.sh index 4385791..30ebc72 100755 --- a/debian/scripts/init.sh +++ b/debian/scripts/init.sh @@ -1,33 +1,4 @@ -#!/bin/sh -set -e - -in_log() { - local type="$1" - shift - printf '%s [%s] [Entrypoint]: %s\n' "$(date -u '+%Y-%m-%dT%H:%M:%SZ')" "$type" "$*" -} - -docker_process_init_files() { - echo - local f - for f; do - case "$f" in - *.sh) - # https://github.com/docker-library/postgres/issues/450#issuecomment-393167936 - # https://github.com/docker-library/postgres/pull/452 - if [ -x "$f" ]; then - in_log INFO "$0: running $f" - "$f" - else - in_log INFO "$0: sourcing $f" - . "$f" - fi - ;; - *) in_log INFO "$0: ignoring $f" ;; - esac - echo - done -} +#!/bin/sh -eu if [ "$*" = 'supervisord -c /etc/supervisor/conf.d/supervisord.conf' ]; then # Workaround for application updates @@ -61,18 +32,20 @@ if [ "$*" = 'supervisord -c /etc/supervisor/conf.d/supervisord.conf' ]; then runuser -u www-data -- php artisan migrate --force # If first IN run, it needs to be initialized - echo "Checking initialization status..." - IN_INIT=$(php -d opcache.preload='' artisan tinker --execute='echo Schema::hasTable("accounts") && !App\Models\Account::all()->first();') - echo "IN_INIT value: $IN_INIT" + if [ "$(php -d opcache.preload='' artisan tinker --execute='echo Schema::hasTable("accounts") && !App\Models\Account::all()->first();')" = "1" ]; then + echo "Running initialization..." - if [ "$IN_INIT" = "1" ]; then - echo "Running initialization scripts..." - docker_process_init_files /docker-entrypoint-init.d/* + php artisan db:seed --force + + if [ -n "${IN_USER_EMAIL}" ] && [ -n "${IN_PASSWORD}" ]; then + php artisan ninja:create-account --email "${IN_USER_EMAIL}" --password "${IN_PASSWORD}" + else + echo "Initialization failed - Set IN_USER_EMAIL and IN_PASSWORD in .env" + exit 1 + fi fi echo "Production setup completed" - echo "IN_INIT value: $IN_INIT" - fi echo "Starting supervisord..." diff --git a/debian/supervisor/supervisord.conf b/debian/supervisor/supervisord.conf index ffa858a..cf97afe 100644 --- a/debian/supervisor/supervisord.conf +++ b/debian/supervisor/supervisord.conf @@ -39,7 +39,7 @@ stderr_logfile=/var/log/php-worker.err.log stopwaitsecs=3600 [program:scheduler] -command=/bin/sh -c "while [ true ]; do (php /var/www/html/artisan schedule:run --verbose --no-interaction &); sleep 60; done" +command=php /var/www/html/artisan schedule:work --verbose --no-interaction autostart=true autorestart=true user=www-data From c00d44380c4ca09735464707e9a1c1704225fb58 Mon Sep 17 00:00:00 2001 From: Benjamin Brummer Date: Mon, 13 Jan 2025 16:34:49 +0000 Subject: [PATCH 8/8] log worker to stdout/stderr --- debian/supervisor/supervisord.conf | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/debian/supervisor/supervisord.conf b/debian/supervisor/supervisord.conf index cf97afe..c2aecfd 100644 --- a/debian/supervisor/supervisord.conf +++ b/debian/supervisor/supervisord.conf @@ -34,8 +34,10 @@ killasgroup=true user=www-data numprocs=2 environment=HOME="/var/www" -stdout_logfile=/var/log/php-worker.log -stderr_logfile=/var/log/php-worker.err.log +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +stderr_logfile=/dev/stderr +stderr_logfile_maxbytes=0 stopwaitsecs=3600 [program:scheduler]