From 6c6950d298d04f524356ee81423264d3b96f8783 Mon Sep 17 00:00:00 2001 From: Benjamin Brummer Date: Sat, 28 Dec 2024 08:33:39 +0100 Subject: [PATCH] frankenphp, mariadb and valkey --- debian/Dockerfile | 80 ++++++++++++----------- debian/docker-compose.yml | 131 ++++++++++++++++++++------------------ 2 files changed, 112 insertions(+), 99 deletions(-) diff --git a/debian/Dockerfile b/debian/Dockerfile index 2be80b5..20f534b 100644 --- a/debian/Dockerfile +++ b/debian/Dockerfile @@ -1,14 +1,24 @@ -FROM php:8.3-fpm AS base +FROM dunglas/frankenphp:1-php8.3-bookworm +ARG USER=ninja + +# 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" +ENV APP_DIR=/app + +# Create a system user +RUN useradd -r ${USER} + +# Allow to bind to privileged ports +RUN setcap CAP_NET_BIND_SERVICE=+eip /usr/local/bin/frankenphp + # Install system dependencies RUN apt-get update && apt-get install -y --no-install-recommends \ mariadb-client \ gpg \ - supervisor \ # Unicode support for PDF fonts-noto-cjk-extra \ fonts-wqy-microhei \ @@ -21,14 +31,15 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ 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; \ + && apt-get install -y --no-install-recommends google-chrome-stable \ + && mkdir /config/google-chrome \ + && chown ${USER}: /config/google-chrome; \ elif [ "$(dpkg --print-architecture)" = "arm64" ]; then \ apt-get install -y --no-install-recommends \ - chromium; \ + chromium \ + && mkdir /config/chromium \ + && chown ${USER}: /config/chromium; \ fi \ - # Create config directory for chromium/google-chrome-stable - && mkdir /var/www/.config \ - && chown www-data:www-data /var/www/.config \ # Cleanup && apt-get purge -y gpg \ && apt-get autoremove -y \ @@ -36,7 +47,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ && rm -rf /var/lib/apt/lists/* # 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 \ +RUN install-php-extensions \ ${php_require} \ ${php_suggest} \ ${php_extra} \ @@ -45,43 +56,38 @@ RUN ( curl -sSLf https://github.com/mlocati/docker-php-extension-installer/relea # Configure PHP RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" -# Copy scripts -COPY rootfs / +# Add initialization script +COPY --chmod=0755 scripts/init.sh /usr/local/bin/init.sh -USER www-data +# Prepare app directory +RUN rm -rf ${APP_DIR}/* \ + && chown ${USER}: ${APP_DIR} -WORKDIR /var/www/html +# Create directory for artisan tinker (init.sh) +RUN mkdir /config/psysh \ + && chown ${USER}: /config/psysh + +# Change owner for caddy directories +RUN chown -R ${USER}: \ + /data/caddy \ + /config/caddy + +USER ${USER} # 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 \ - && 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 {} \; \ + tar -oxz -C ${APP_DIR} \ + && ln -s ${APP_DIR}/resources/views/react/index.blade.php ${APP_DIR}/public/index.html \ + # Set permissions: directories 755, files 644 + && chmod -R a=r,u+w,a+X ${APP_DIR} \ # Install dependencies - && composer install --no-dev --no-scripts --no-autoloader \ - && composer dump-autoload --optimize \ - && 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 - -# Add initialization script -COPY --chmod=0755 scripts/init.sh /usr/local/bin/init.sh - -# Health check -HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 \ - CMD php -v || exit 1 + && composer install --working-dir=${APP_DIR} --no-dev --no-scripts --no-autoloader \ + && composer dump-autoload --working-dir=${APP_DIR} --optimize \ + && frankenphp php-cli ${APP_DIR}/artisan storage:link ENTRYPOINT ["/usr/local/bin/init.sh"] -CMD ["supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"] + +CMD ["frankenphp", "run", "--config", "/etc/caddy/Caddyfile", "--adapter", "caddyfile"] diff --git a/debian/docker-compose.yml b/debian/docker-compose.yml index e643610..937ed27 100644 --- a/debian/docker-compose.yml +++ b/debian/docker-compose.yml @@ -4,93 +4,100 @@ x-logging: &default-logging max-file: "3" driver: json-file +x-app-volumes: &volumes + volumes: + - ./.env:/app/.env + - ./php/php.ini:/usr/local/etc/php/conf.d/zzz-php.ini:ro + - app_cache:/var/www/html/bootstrap/cache + - app_storage:/app/storage + services: app: build: context: . image: invoiceninja/invoiceninja-debian:${TAG:-latest} restart: unless-stopped - env_file: - - ./.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 - - app_cache:/var/www/html/bootstrap/cache - - app_public:/var/www/html/public - - app_storage:/var/www/html/storage - networks: - - app-network - depends_on: - mysql: - condition: service_healthy - redis: - condition: service_healthy - logging: *default-logging - - nginx: - image: nginx:alpine - restart: unless-stopped ports: - "80:80" - volumes: - - ./nginx:/etc/nginx/conf.d:ro - - app_public:/var/www/html/public:ro - - app_storage:/var/www/html/storage:ro - networks: - - app-network + env_file: + - ./.env + environment: + LARAVEL_ROLE: app + # https://frankenphp.dev/docs/production/#preparing-your-app + SERVER_NAME: :80 + <<: *volumes + # HEALTHCHECK from frankenphp image + healthcheck: + start_period: 180s depends_on: - - app + mariadb: + condition: service_healthy + valkey: + condition: service_healthy + logging: *default-logging + + app-worker: + image: invoiceninja/invoiceninja-debian:${TAG:-latest} + restart: unless-stopped + deploy: + mode: replicated + replicas: 2 + env_file: + - ./.env + environment: + LARAVEL_ROLE: worker + <<: *volumes + depends_on: + app: + condition: service_healthy logging: *default-logging - mysql: - image: mysql:8 + app-scheduler: + image: invoiceninja/invoiceninja-debian:${TAG:-latest} restart: unless-stopped env_file: - ./.env environment: - MYSQL_DATABASE: ${DB_DATABASE} - MYSQL_USER: ${DB_USERNAME} - MYSQL_PASSWORD: ${DB_PASSWORD} - MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD} - volumes: - - mysql_data:/var/lib/mysql - networks: - - app-network - healthcheck: - test: [ "CMD", "mysqladmin", "ping", "-h", "localhost", "-u${MYSQL_USER}", "-p${MYSQL_PASSWORD}" ] - interval: 10s - timeout: 5s - retries: 5 + LARAVEL_ROLE: scheduler + <<: *volumes + depends_on: + app: + condition: service_healthy logging: *default-logging - redis: - image: redis:alpine + mariadb: + image: mariadb:11.4 + restart: unless-stopped + env_file: + - ./.env + environment: + MARIADB_DATABASE: ${DB_DATABASE} + MARIADB_USER: ${DB_USERNAME} + MARIADB_PASSWORD: ${DB_PASSWORD} + MARIADB_ROOT_PASSWORD: ${DB_ROOT_PASSWORD} + volumes: + - mariadb:/var/lib/mysql + healthcheck: + test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"] + start_period: 60s + logging: *default-logging + + valkey: + image: valkey/valkey:8 restart: unless-stopped volumes: - - redis_data:/data - networks: - - app-network + - valkey:/data healthcheck: - test: [ "CMD", "redis-cli", "ping" ] - interval: 10s - timeout: 5s - retries: 5 + test: [ "CMD", "valkey-cli", "ping" ] + start_period: 10s logging: *default-logging -networks: - app-network: - driver: bridge - volumes: app_cache: driver: local - app_public: - driver: local app_storage: - driver: local - mysql_data: driver: local - redis_data: + mariadb: + driver: local + valkey: driver: local