frankenphp, mariadb and valkey

This commit is contained in:
Benjamin Brummer
2024-12-28 08:33:39 +01:00
parent 99f280319c
commit 6c6950d298
2 changed files with 112 additions and 99 deletions

80
debian/Dockerfile vendored
View File

@@ -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"]

View File

@@ -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