Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Use dedicated images for php and nginx, aligned workdirs #4

Merged
merged 3 commits into from
Dec 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .env
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
# https://symfony.com/doc/current/best_practices.html#use-environment-variables-for-infrastructure-configuration

# Main user is 1000 on Linux
USER_UID=1000
UID=1000
PUBLIC_NGINX_PORT=8781
PUBLIC_VARNISH_PORT=8784
PUBLIC_PMA_PORT=8782
Expand Down
127 changes: 95 additions & 32 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
ARG PHP_VERSION=8.3.14
ARG MYSQL_VERSION=8.0.40
ARG NGINX_VERSION=1.27.2
ARG SOLR_VERSION=9
ARG VARNISH_VERSION=7.1
ARG USER_UID=1000
ARG UID=1000

#######
# PHP #
Expand All @@ -12,7 +13,7 @@ FROM php:${PHP_VERSION}-fpm-bookworm AS php

LABEL org.opencontainers.image.authors="ambroise@rezo-zero.com"

ARG USER_UID
ARG UID

ARG COMPOSER_VERSION=2.8.1
ARG PHP_EXTENSION_INSTALLER_VERSION=2.6.0
Expand All @@ -24,8 +25,6 @@ ENV APP_FFMPEG_PATH=/usr/bin/ffmpeg
ENV MYSQL_HOST=db
ENV MYSQL_PORT=3306

HEALTHCHECK --start-period=30s --interval=1m --timeout=6s CMD bin/console monitor:health -q

COPY --link docker/php/crontab.txt /crontab.txt
COPY --link docker/php/wait-for-it.sh /wait-for-it.sh
COPY --link docker/php/fpm.d/www.conf ${PHP_INI_DIR}-fpm.d/zz-www.conf
Expand All @@ -42,13 +41,17 @@ apt-get --quiet --yes --no-install-recommends --verbose-versions install \
ffmpeg
rm -rf /var/lib/apt/lists/*

usermod -u ${USER_UID} www-data
groupmod -g ${USER_UID} www-data
echo "www-data ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/www-data
# User
addgroup --gid ${UID} php
adduser --home /home/php --shell /bin/bash --uid ${UID} --gecos php --ingroup php --disabled-password php
echo "php ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/php

/usr/bin/crontab -u www-data /crontab.txt
# App
install --verbose --owner php --group php --mode 0755 --directory /app

/usr/bin/crontab -u php /crontab.txt
chmod +x /wait-for-it.sh
chown -R www-data:www-data /var/www/html
chown -R php:php /app

# Php extensions
curl -sSLf https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions \
Expand All @@ -75,7 +78,7 @@ install-php-extensions \
redis-${PHP_EXTENSION_REDIS_VERSION}
EOF

WORKDIR /var/www/html
WORKDIR /app

###################
# PHP Development #
Expand Down Expand Up @@ -105,12 +108,12 @@ apt-get --quiet --yes --purge --autoremove upgrade
apt-get --quiet --yes --no-install-recommends --verbose-versions install make
rm -rf /var/lib/apt/lists/*
# Prepare folder to install composer credentials
install --owner=www-data --group=www-data --mode=755 --directory /var/www/.composer
install --owner=php --group=php --mode=755 --directory /home/php/.composer
EOF

VOLUME /var/www/html
VOLUME /app

USER www-data
USER php

# If you depend on private Gitlab repositories, you must use a deploy token and username
#RUN composer config --global gitlab-token.gitlab.rezo-zero.com ${COMPOSER_DEPLOY_TOKEN_USER} ${COMPOSER_DEPLOY_TOKEN}
Expand Down Expand Up @@ -138,17 +141,17 @@ COPY --link docker/php/conf.d/php.prod.ini ${PHP_INI_DIR}/conf.d/zz-app.ini
COPY --link --chmod=755 docker/php/docker-php-entrypoint /usr/local/bin/docker-php-entrypoint
COPY --link --chmod=755 docker/php/docker-cron-entrypoint /usr/local/bin/docker-cron-entrypoint

USER www-data
USER php

# Composer
COPY --link --chown=www-data:www-data composer.* symfony.* ./
COPY --link --chown=php:php composer.* symfony.* ./
RUN <<EOF
# If you depend on private Gitlab repositories, you must use a deploy token and username
#composer config gitlab-token.gitlab.rezo-zero.com ${COMPOSER_DEPLOY_TOKEN_USER} ${COMPOSER_DEPLOY_TOKEN}
composer install --no-cache --prefer-dist --no-dev --no-autoloader --no-scripts --no-progress
EOF

COPY --link --chown=www-data:www-data . .
COPY --link --chown=php:php . .

RUN <<EOF
composer dump-autoload --classmap-authoritative --no-dev
Expand All @@ -157,23 +160,83 @@ bin/console assets:install
bin/console themes:assets:install Rozier
EOF

VOLUME /var/www/html/config/jwt \
/var/www/html/config/secrets \
/var/www/html/public/files \
/var/www/html/public/assets \
/var/www/html/var/files
HEALTHCHECK --start-period=30s --interval=1m --timeout=6s CMD bin/console monitor:health -q

VOLUME /app/config/jwt \
/app/config/secrets \
/app/public/files \
/app/public/assets \
/app/var/files



#########
# Nginx #
#########

FROM roadiz/nginx-alpine AS nginx-prod
FROM nginx:${NGINX_VERSION}-bookworm AS nginx

LABEL org.opencontainers.image.authors="ambroise@rezo-zero.com"

COPY --link --from=php-prod --chown=www-data:www-data /var/www/html/public /var/www/html/public
ARG UID

SHELL ["/bin/bash", "-e", "-o", "pipefail", "-c"]

RUN <<EOF
# Packages
apt-get --quiet update
apt-get --quiet --yes --purge --autoremove upgrade
apt-get --quiet --yes --no-install-recommends --verbose-versions install \
less \
sudo
rm -rf /var/lib/apt/lists/*

# User
groupmod --gid ${UID} nginx
usermod --uid ${UID} nginx
echo "nginx ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/nginx

# App
install --verbose --owner nginx --group nginx --mode 0755 --directory /app
EOF

ambroisemaupate marked this conversation as resolved.
Show resolved Hide resolved
ENV NGINX_ENTRYPOINT_QUIET_LOGS=1
# Config
COPY --link docker/nginx/nginx.conf /etc/nginx/nginx.conf
COPY --link docker/nginx/redirections.conf /etc/nginx/redirections.conf
COPY --link docker/nginx/mime.types /etc/nginx/mime.types
COPY --link docker/nginx/conf.d/_gzip.conf /etc/nginx/conf.d/_gzip.conf
COPY --link docker/nginx/conf.d/_security.conf /etc/nginx/conf.d/_security.conf
COPY --link docker/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf

WORKDIR /app



##############
# Nginx DEV #
##############

FROM nginx AS nginx-dev

# Silence entrypoint logs

# Declare a volume for development
VOLUME /app



##############
# Nginx PROD #
##############

FROM nginx AS nginx-prod
# Copy public files from API
COPY --link --from=php-prod --chown=${USER_UID}:${USER_UID} /app/public /app/public

# Only enable healthcheck in production when the app is ready to serve requests on root path
# This could prevent Traefik or an ingress controller to route traffic to the app
#HEALTHCHECK --start-period=1m30s --interval=1m --timeout=6s CMD curl --fail -I http://localhost

#########
# MySQL #
Expand All @@ -183,14 +246,14 @@ FROM mysql:${MYSQL_VERSION} AS mysql

LABEL org.opencontainers.image.authors="ambroise@rezo-zero.com"

ARG USER_UID
ARG UID

SHELL ["/bin/bash", "-e", "-o", "pipefail", "-c"]

RUN <<EOF
usermod -u ${USER_UID} mysql
groupmod -g ${USER_UID} mysql
echo "USER_UID: ${USER_UID}\n"
usermod -u ${UID} mysql
groupmod -g ${UID} mysql
echo "UID: ${UID}\n"
EOF

COPY --link docker/mysql/performances.cnf /etc/mysql/conf.d/performances.cnf
Expand All @@ -203,18 +266,18 @@ FROM solr:${SOLR_VERSION}-slim AS solr

LABEL org.opencontainers.image.authors="ambroise@rezo-zero.com"

ARG USER_UID
ARG UID

SHELL ["/bin/bash", "-e", "-o", "pipefail", "-c"]

USER root

RUN <<EOF
set -ex
echo "USER_UID: ${USER_UID}\n"
usermod -u ${USER_UID} "$SOLR_USER"
groupmod -g ${USER_UID} "$SOLR_GROUP"
chown -R ${USER_UID}:${USER_UID} /var/solr
echo "UID: ${UID}\n"
usermod -u ${UID} "$SOLR_USER"
groupmod -g ${UID} "$SOLR_GROUP"
chown -R ${UID}:${UID} /var/solr
EOF

COPY --link docker/solr/managed-schema.xml /opt/solr/server/solr/configsets/_default/conf/managed-schema
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ services:
#app:
# build:
# args:
# USER_UID: ${USER_UID}
# UID: ${UID}
# COMPOSER_DEPLOY_TOKEN: xxxxxxxxxxxxx
# COMPOSER_DEPLOY_TOKEN_USER: "gitlab+deploy-token-1"

Expand Down
2 changes: 1 addition & 1 deletion compose.override.yml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ services:
#app:
# build:
# args:
# USER_UID: ${USER_UID}
# UID: ${UID}
# COMPOSER_DEPLOY_TOKEN: xxxxxxxxxxxxx
# COMPOSER_DEPLOY_TOKEN_USER: "gitlab+deploy-token-1"

Expand Down
28 changes: 14 additions & 14 deletions compose.prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,9 @@ services:
networks:
- default
volumes:
- ./robots.txt:/var/www/html/public/robots.txt:ro
- app_file_data:/var/www/html/public/files:ro
- app_assets_data:/var/www/html/public/assets:ro
- ./robots.txt:/app/public/robots.txt:ro
- app_file_data:/app/public/files:ro
- app_assets_data:/app/public/assets:ro
labels:
- "com.centurylinklabs.watchtower.enable=true"
- "com.centurylinklabs.watchtower.depends-on=/skeleton-app-1"
Expand All @@ -118,24 +118,24 @@ services:
- redis
#- solr
volumes:
- app_file_data:/var/www/html/public/files
- app_assets_data:/var/www/html/public/assets
- app_private_file_data:/var/www/html/var/files
- app_secret_data:/var/www/html/config/secrets
- app_file_data:/app/public/files
- app_assets_data:/app/public/assets
- app_private_file_data:/app/var/files
- app_secret_data:/app/config/secrets
## Use docker-compose env file as .env.local in container
- ./.env:/var/www/html/.env.local:ro
- ./.env:/app/.env.local:ro
## Generate JWT certificates on your host and share them to docker container
## openssl genpkey -out jwt_private.pem -aes256 -algorithm rsa -pkeyopt rsa_keygen_bits:4096; chmod 0644 jwt_private.pem;
- ./jwt_private.pem:/var/www/html/config/jwt/private.pem:ro
- ./jwt_private.pem:/app/config/jwt/private.pem:ro
## openssl pkey -in jwt_private.pem -out jwt_public.pem -pubout; chmod 0644 jwt_public.pem;
- ./jwt_public.pem:/var/www/html/config/jwt/public.pem:ro
- ./jwt_public.pem:/app/config/jwt/public.pem:ro
##
## Do not add volume for src/GeneratedEntity, they are versioned since Roadiz v2
## Uncomment these if you DO want to persist and edit node-types on production env
##
#- app_node_types_api:/var/www/html/config/api_resources
#- app_node_types_resource:/var/www/html/src/Resources
#- app_node_types_entities:/var/www/html/src/GeneratedEntity
#- app_node_types_api:/app/config/api_resources
#- app_node_types_resource:/app/src/Resources
#- app_node_types_entities:/app/src/GeneratedEntity
networks:
- default
environment:
Expand All @@ -156,7 +156,7 @@ services:
# Do not use more than 1 replica if you're using Varnish and need to purge/ban cache
# from your workers. Varnish ACL hostnames won't be resolved correctly.
replicas: 1
entrypoint: [ "php", "/var/www/html/bin/console", "messenger:consume", "async", "--time-limit=1800" ]
entrypoint: [ "php", "/app/bin/console", "messenger:consume", "async", "--time-limit=1800" ]

cron:
<<: *app_template
Expand Down
22 changes: 11 additions & 11 deletions compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ services:
# Custom image for file permissions and performances
target: mysql
args:
USER_UID: ${USER_UID}
UID: ${UID}
cap_add:
- SYS_NICE # CAP_SYS_NICE
networks:
Expand Down Expand Up @@ -54,26 +54,29 @@ services:
build:
target: php-dev
args:
USER_UID: ${USER_UID}
UID: ${UID}
depends_on:
- db
- solr
- redis
volumes:
- ./:/var/www/html
- ./:/app
networks:
default:
environment:
TRUSTED_PROXIES: ${TRUSTED_PROXIES}
USER_UID: ${USER_UID}
UID: ${UID}
DEFAULT_GATEWAY: ${DEFAULT_GATEWAY}

nginx:
image: roadiz/nginx-alpine:latest
build:
target: nginx-dev
args:
UID: ${UID}
depends_on:
- app
volumes:
- ./:/var/www/html
- ./:/app
networks:
default:
# frontproxynet:
Expand Down Expand Up @@ -110,7 +113,7 @@ services:
replicas: 1
# official php-fpm image uses SIGQUIT
stop_signal: SIGTERM
entrypoint: [ "php", "/var/www/html/bin/console", "messenger:consume", "async", "--time-limit=600" ]
entrypoint: [ "php", "/app/bin/console", "messenger:consume", "async", "--time-limit=600" ]
restart: unless-stopped

cron:
Expand All @@ -127,12 +130,9 @@ services:
# Custom image for file permissions
target: solr
args:
USER_UID: ${USER_UID}
UID: ${UID}
volumes:
- "solr:/var/solr"
environment:
SOLR_UID: ${USER_UID}
SOLR_GID: ${USER_UID}
command:
- solr-precreate
- ${SOLR_CORE_NAME}
Expand Down
14 changes: 14 additions & 0 deletions docker/nginx/conf.d/_gzip.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
gzip on;
gzip_proxied any;
gzip_vary on;
gzip_comp_level 2;
gzip_min_length 256;
gzip_types application/atom+xml application/javascript application/json application/rss+xml
application/vnd.ms-fontobject application/x-font-opentype application/x-font-truetype
application/x-font-ttf application/x-javascript application/xhtml+xml application/xml
font/eot font/opentype font/otf font/truetype image/svg+xml image/vnd.microsoft.icon
image/x-icon image/x-win-bitmap text/css text/javascript text/plain text/xml;
gzip_disable "MSIE [1-6]\.(?!.*SV1)";
# make sure gzip does not lose large gzipped js or css files
# see http://blog.leetsoft.com/2007/7/25/nginx-gzip-ssl
gzip_buffers 16 8k;
Loading
Loading