diff --git a/alpine/5/Dockerfile b/alpine/5/Dockerfile index d66a086..cf5dea6 100644 --- a/alpine/5/Dockerfile +++ b/alpine/5/Dockerfile @@ -1,60 +1,65 @@ -ARG PHP_VERSION=8.3 -ARG ALPINE_VERSION=3.20 +ARG PHP_VERSION=8.2 ARG BAK_STORAGE_PATH=/var/www/app/docker-backup-storage/ ARG BAK_PUBLIC_PATH=/var/www/app/docker-backup-public/ # Get Invoice Ninja and install nodejs packages -FROM --platform=$BUILDPLATFORM php:${PHP_VERSION}-fpm-alpine${ALPINE_VERSION} AS nodebuild +FROM --platform=$BUILDPLATFORM node:lts-alpine as nodebuild # Download Invoice Ninja ARG INVOICENINJA_VERSION ARG REPOSITORY=invoiceninja/invoiceninja ARG FILENAME=invoiceninja.tar -RUN mkdir -p /var/www/app +RUN set -eux; apk add curl unzip grep + +RUN DOWNLOAD_URL=$(curl -s "https://api.github.com/repos/invoiceninja/invoiceninja/releases/latest" | grep -o '"browser_download_url": "[^"]*invoiceninja.tar"' | cut -d '"' -f 4) && \ + curl -LJO "$DOWNLOAD_URL" && \ + mv invoiceninja.tar /tmp/ninja.tar # Extract Invoice Ninja -RUN apk add --no-cache curl \ - && 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/app/ \ - && apk --purge del curl - -RUN mkdir -p /var/www/app/public/logo /var/www/app/storage - +RUN mkdir -p /var/www/app \ + && tar -xvf /tmp/ninja.tar -C /var/www/app/ \ + && mkdir -p /var/www/app/public/logo /var/www/app/storage + WORKDIR /var/www/app # Prepare php image -FROM php:${PHP_VERSION}-fpm-alpine${ALPINE_VERSION} AS phpbuild +FROM php:${PHP_VERSION}-fpm-alpine as phpbuild LABEL maintainer="David Bomba " -ARG php_require="bcmath gd pdo_mysql zip" -ARG php_suggest="exif imagick intl pcntl soap" -ARG php_extra="opcache" +# Adding caching_sha2_password.so +# With this we get native support for caching_sha2_password +RUN apk add --no-cache mariadb-connector-c -RUN ln -s "${PHP_INI_DIR}/php.ini-production" "${PHP_INI_DIR}/php.ini" +RUN mv /usr/local/etc/php/php.ini-production /usr/local/etc/php/php.ini + +# Install PHP extensions +# https://hub.docker.com/r/mlocati/php-extension-installer/tags +COPY --from=mlocati/php-extension-installer /usr/bin/install-php-extensions /usr/local/bin/ # Install chromium RUN set -eux; \ apk add --no-cache \ font-isas-misc \ supervisor \ - mariadb-client \ - mariadb-connector-c \ + mysql-client \ chromium \ - # font-noto-cjk-extra \ - # font-wqy-zenhei \ ttf-freefont \ ttf-dejavu -# 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} +RUN install-php-extensions \ + bcmath \ + exif \ + gd \ + gmp \ + mysqli \ + opcache \ + pdo_mysql \ + zip \ + intl \ + @composer \ + && rm /usr/local/bin/install-php-extensions # Copy files COPY rootfs / @@ -82,6 +87,8 @@ ENV BAK_STORAGE_PATH $BAK_STORAGE_PATH ENV BAK_PUBLIC_PATH $BAK_PUBLIC_PATH COPY --from=nodebuild --chown=$INVOICENINJA_USER:$INVOICENINJA_USER /var/www/app /var/www/app +RUN rm -rf /var/www/app/ui + USER $UID WORKDIR /var/www/app @@ -99,7 +106,7 @@ ARG BAK_PUBLIC_PATH RUN mv /var/www/app/storage $BAK_STORAGE_PATH \ && mv /var/www/app/public $BAK_PUBLIC_PATH -FROM phpbuild AS prod +FROM phpbuild as prod COPY --from=dependencybuild --chown=$INVOICENINJA_USER:$INVOICENINJA_USER /var/www/app /var/www/app diff --git a/alpine/5/rootfs/etc/supervisord.conf b/alpine/5/rootfs/etc/supervisord.conf index 2ed26a7..3ca2d92 100644 --- a/alpine/5/rootfs/etc/supervisord.conf +++ b/alpine/5/rootfs/etc/supervisord.conf @@ -1,36 +1,37 @@ [supervisord] nodaemon=true -logfile=/dev/null +pidfile=/tmp/supervisord.pid +logfile=/dev/null ; nodaemon will cause logs to go to stdout logfile_maxbytes=0 - -[rpcinterface:supervisor] -supervisor.rpcinterface_factory=supervisor.rpcinterface:make_main_rpcinterface +loglevel=info [program:php-fpm] -command=php-fpm -stdout_logfile=/dev/fd/1 -stdout_logfile_maxbytes=0 redirect_stderr=true +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +stderr_logfile=/dev/stderr +stderr_logfile_maxbytes=0 +command=php-fpm [program:scheduler] -command=php artisan schedule:work autorestart=true -stdout_logfile=/dev/fd/1 -stdout_logfile_maxbytes=0 redirect_stderr=true +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +stderr_logfile=/dev/stderr +stderr_logfile_maxbytes=0 +command=php artisan schedule:work [program:queue-worker] process_name=%(program_name)s_%(process_num)02d -command=php artisan queue:work --sleep=3 --tries=1 --timeout=3600 -autostart=true autorestart=true -stopasgroup=true -killasgroup=true -numprocs=2 -stdout_logfile=/dev/fd/1 -stdout_logfile_maxbytes=0 redirect_stderr=true -stopwaitsecs=3600 +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +stderr_logfile=/dev/stderr +stderr_logfile_maxbytes=0 +numprocs=2 +command=php artisan queue:work --sleep=3 --tries=1 --memory=256 --timeout=3600 [eventlistener:shutdown] command=shutdown.sh diff --git a/alpine/5/rootfs/usr/local/bin/invoiceninja-init.sh b/alpine/5/rootfs/usr/local/bin/invoiceninja-init.sh index f4a21ba..b4b2ee5 100755 --- a/alpine/5/rootfs/usr/local/bin/invoiceninja-init.sh +++ b/alpine/5/rootfs/usr/local/bin/invoiceninja-init.sh @@ -30,7 +30,7 @@ php artisan optimize php artisan package:discover # Check if DB works, if not crash the app. -DB_READY=$(php -d opcache.preload='' artisan tinker --execute='echo app()->call("App\Utils\SystemHealth@dbCheck")["success"];') +DB_READY=$(php artisan tinker --execute='echo app()->call("App\Utils\SystemHealth@dbCheck")["success"];') if [ "$DB_READY" != "1" ]; then php artisan migrate:status # Print verbose error in_error "Error connecting to DB" @@ -39,7 +39,7 @@ fi php artisan migrate --force # If first IN run, it needs to be initialized -IN_INIT=$(php -d opcache.preload='' artisan tinker --execute='echo Schema::hasTable("accounts") && !App\Models\Account::all()->first();') +IN_INIT=$(php artisan tinker --execute='echo Schema::hasTable("accounts") && !App\Models\Account::all()->first();') if [ "$IN_INIT" == "1" ]; then docker_process_init_files /docker-entrypoint-init.d/* fi diff --git a/alpine/5/rootfs/usr/local/etc/php-fpm.d/invoiceninja.conf b/alpine/5/rootfs/usr/local/etc/php-fpm.d/invoiceninja.conf deleted file mode 100644 index 63bbada..0000000 --- a/alpine/5/rootfs/usr/local/etc/php-fpm.d/invoiceninja.conf +++ /dev/null @@ -1 +0,0 @@ -pm.max_children = 10 diff --git a/alpine/5/rootfs/usr/local/etc/php/conf.d/in-php.ini b/alpine/5/rootfs/usr/local/etc/php/conf.d/in-php.ini new file mode 100644 index 0000000..1ecaf93 --- /dev/null +++ b/alpine/5/rootfs/usr/local/etc/php/conf.d/in-php.ini @@ -0,0 +1,17 @@ +; How often (in seconds) to check file timestamps for changes to the shared +; memory storage allocation. ("1" means validate once per second, but only +; once per request. "0" means always validate) +;opcache.revalidate_freq=2 +opcache.revalidate_freq=60 + +# http://symfony.com/doc/current/performance.html +; Duration of time, in seconds for which to cache realpath information for a given +; file or directory. For systems with rarely changing files, consider increasing this +; value. +; http://php.net/realpath-cache-ttl +;realpath_cache_ttl = 120 +realpath_cache_ttl = 600 + +; Maximum allowed size for uploaded files. +; http://php.net/upload-max-filesize +upload_max_filesize = 8M diff --git a/alpine/5/rootfs/usr/local/etc/php/conf.d/invoiceninja.ini b/alpine/5/rootfs/usr/local/etc/php/conf.d/invoiceninja.ini deleted file mode 100644 index b9f3c58..0000000 --- a/alpine/5/rootfs/usr/local/etc/php/conf.d/invoiceninja.ini +++ /dev/null @@ -1,22 +0,0 @@ -[core] -; 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 -opcache.enable_cli=1 - -[jit] -; 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/app/preload.php -opcache.validate_timestamps=0 -realpath_cache_size=4096K -realpath_cache_ttl=600 diff --git a/config/nginx/in-vhost.conf b/config/nginx/in-vhost.conf new file mode 100644 index 0000000..cf262f7 --- /dev/null +++ b/config/nginx/in-vhost.conf @@ -0,0 +1,34 @@ +server { + listen 80 default_server; + server_name _; + + server_tokens off; + + client_max_body_size 100M; + + root /var/www/app/public/; + index index.php; + + location / { + try_files $uri $uri/ /index.php?$query_string; + } + + location = /favicon.ico { access_log off; log_not_found off; } + location = /robots.txt { access_log off; log_not_found off; } + + + location ~* /storage/.*\.php$ { + return 503; + } + + location ~ \.php$ { + fastcgi_split_path_info ^(.+\.php)(/.+)$; + fastcgi_pass app:9000; + fastcgi_index index.php; + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_intercept_errors off; + fastcgi_buffer_size 16k; + fastcgi_buffers 4 16k; + } +} diff --git a/config/nginx/invoiceninja.conf b/config/nginx/invoiceninja.conf deleted file mode 100644 index 78add9d..0000000 --- a/config/nginx/invoiceninja.conf +++ /dev/null @@ -1,14 +0,0 @@ -# https://nginx.org/en/docs/http/ngx_http_core_module.html -client_max_body_size 10M; -client_body_buffer_size 10M; -server_tokens off; - -# https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html -fastcgi_buffers 32 16K; - -# https://nginx.org/en/docs/http/ngx_http_gzip_module.html -gzip on; -gzip_comp_level 2; -gzip_min_length 1M; -gzip_proxied any; -gzip_types *; diff --git a/config/nginx/laravel.conf b/config/nginx/laravel.conf deleted file mode 100644 index 5edb43a..0000000 --- a/config/nginx/laravel.conf +++ /dev/null @@ -1,32 +0,0 @@ -# https://laravel.com/docs/master/deployment#nginx -server { - listen 80 default_server; - server_name _; - root /var/www/app/public; - - add_header X-Frame-Options "SAMEORIGIN"; - add_header X-Content-Type-Options "nosniff"; - - index index.php; - - charset utf-8; - - location / { - try_files $uri $uri/ /index.php?$query_string; - } - - location = /favicon.ico { access_log off; log_not_found off; } - location = /robots.txt { access_log off; log_not_found off; } - - error_page 404 /index.php; - - location ~ \.php$ { - fastcgi_pass app:9000; - fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; - include fastcgi_params; - } - - location ~ /\.(?!well-known).* { - deny all; - } -} diff --git a/config/php/php-cli.ini b/config/php/php-cli.ini new file mode 100644 index 0000000..c66bcfb --- /dev/null +++ b/config/php/php-cli.ini @@ -0,0 +1,18 @@ +session.auto_start = Off +short_open_tag = Off + +error_reporting = E_ALL & ~E_NOTICE & ~E_WARNING & ~E_STRICT & ~E_DEPRECATED + +; opcache.enable_cli=1 +; opcache.fast_shutdown=1 +; opcache.memory_consumption=256 +; opcache.interned_strings_buffer=8 +; opcache.max_accelerated_files=4000 +; opcache.revalidate_freq=60 +; # http://symfony.com/doc/current/performance.html +; realpath_cache_size = 4096K +; realpath_cache_ttl = 600 + +memory_limit = 2G +post_max_size = 60M +upload_max_filesize = 50M \ No newline at end of file diff --git a/config/php/php-fpm.conf b/config/php/php-fpm.conf deleted file mode 100644 index 63bbada..0000000 --- a/config/php/php-fpm.conf +++ /dev/null @@ -1 +0,0 @@ -pm.max_children = 10 diff --git a/config/php/php.ini b/config/php/php.ini index b9f3c58..f5298a6 100644 --- a/config/php/php.ini +++ b/config/php/php.ini @@ -1,22 +1,21 @@ -[core] -; https://www.php.net/manual/en/ini.core.php -post_max_size=10M -upload_max_filesize=10M +session.auto_start = Off +short_open_tag = Off -[opcache] -; https://www.php.net/manual/en/opcache.installation.php#opcache.installation.recommended -opcache.enable_cli=1 +error_reporting = E_ALL & ~E_NOTICE & ~E_WARNING & ~E_STRICT & ~E_DEPRECATED -[jit] -; https://wiki.php.net/rfc/jit_config_defaults -opcache.jit=tracing -opcache.jit_buffer_size=64M +; opcache.enable=1 +; opcache.preload=/var/www/app/preload.php +; opcache.preload_user=www-data -[extra] -; http://symfony.com/doc/current/performance.html -opcache.memory_consumption=256 -opcache.max_accelerated_files=20000 -opcache.preload=/var/www/app/preload.php -opcache.validate_timestamps=0 -realpath_cache_size=4096K -realpath_cache_ttl=600 +; ; The OPcache shared memory storage size. +; opcache.max_accelerated_files=300000 +; opcache.validate_timestamps=1 +; opcache.revalidate_freq=30 +; opcache.jit_buffer_size=256M +; opcache.jit=1205 +; opcache.memory_consumption=1024M + + +post_max_size = 60M +upload_max_filesize = 50M +memory_limit=512M diff --git a/docker-compose.yml b/docker-compose.yml index 338facf..187a742 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,12 +1,14 @@ +version: '3.7' + services: - nginx: + server: image: nginx restart: always env_file: env volumes: # Vhost configuration #- ./config/caddy/Caddyfile:/etc/caddy/Caddyfiledocker-com - - ./config/nginx:/etc/nginx/conf.d:ro + - ./config/nginx/in-vhost.conf:/etc/nginx/conf.d/in-vhost.conf:ro - ./docker/app/public:/var/www/app/public:ro depends_on: - app @@ -15,27 +17,28 @@ services: ports: - "80:80" #- "443:443" - # extra_hosts: - # - "in5.localhost:192.168.0.124 " #host and ip + networks: + - invoiceninja + extra_hosts: + - "in5.localhost:192.168.0.124 " #host and ip app: - build: - context: ./alpine/5 - image: invoiceninja/invoiceninja:${TAG:-5} + image: invoiceninja/invoiceninja:5 env_file: env restart: always volumes: - # - ./config/hosts:/etc/hosts:ro + - ./config/hosts:/etc/hosts:ro - ./docker/app/public:/var/www/app/public:rw,delegated - ./docker/app/storage:/var/www/app/storage:rw,delegated - # - ./config/php/php.ini:/usr/local/etc/php/conf.d/invoiceninja.ini - # - ./config/php/php-fpm.conf:/usr/local/etc/php-fpm.d/invoiceninja.conf + - ./config/php/php.ini:/usr/local/etc/php/php.ini + - ./config/php/php-cli.ini:/usr/local/etc/php/php-cli.ini depends_on: - db - - valkey - # extra_hosts: - # - "in5.localhost:192.168.0.124 " #host and ip + networks: + - invoiceninja + extra_hosts: + - "in5.localhost:192.168.0.124 " #host and ip db: image: mysql:8 @@ -54,8 +57,10 @@ services: #- ./config/mysql/backup-script:/etc/cron.daily/daily:ro #- ./config/mysql/backup-script:/etc/cron.weekly/weekly:ro #- ./config/mysql/backup-script:/etc/cron.monthly/monthly:ro - # extra_hosts: - # - "in5.localhost:192.168.0.124 " #host and ip + networks: + - invoiceninja + extra_hosts: + - "in5.localhost:192.168.0.124 " #host and ip # THIS IS ONLY A VALID CONFIGURATION FOR IN 4. DO NOT USE FOR IN 5. # cron: @@ -77,9 +82,6 @@ services: # networks: # - invoiceninja # - valkey: - image: valkey/valkey:8 - restart: unless-stopped - healthcheck: - test: [ "CMD", "valkey-cli", "ping" ] - start_period: 10s + +networks: + invoiceninja: diff --git a/env b/env index 9d99e59..eb49e7d 100644 --- a/env +++ b/env @@ -7,13 +7,8 @@ PHANTOMJS_PDF_GENERATION=false PDF_GENERATOR=snappdf TRUSTED_PROXIES='*' -CACHE_DRIVER=redis -QUEUE_CONNECTION=redis -SESSION_DRIVER=redis -REDIS_HOST=valkey -REDIS_PASSWORD=null -REDIS_PORT=6379 +QUEUE_CONNECTION=database # DB connection DB_HOST=db