harden(docker): non-root, dedicated healthcheck, opcache split, graceful shutdown
Coolify-doc-driven production hardening of the deploy stack: - run the whole stack as non-root www-data; nginx on 8080 (non-privileged), pid in /tmp, user directive dropped (Coolify routes to any port) - docker/healthcheck.sh: hit real /health route via PHP (not just port probe) - split OPcache config into docker/php/opcache.ini - graceful shutdown: supervisord stopsignal/stopwaitsecs + worker stop_grace_period - APCu intentionally not added (Symfony cache uses redis) - DEPLOY.md: 8080 port, non-root, resource-limit guidance Verified on linux/amd64: non-root uid=82, /health 200, migrations run, worker process healthcheck OK. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+20
-3
@@ -85,19 +85,36 @@ RUN [ -f .env ] || printf 'APP_ENV=prod\nAPP_DEBUG=0\n' > .env
|
||||
|
||||
# Container configuration.
|
||||
COPY docker/php/php.ini /usr/local/etc/php/conf.d/zz-app.ini
|
||||
COPY docker/php/opcache.ini /usr/local/etc/php/conf.d/zz-opcache.ini
|
||||
COPY docker/php/zz-pool.conf /usr/local/etc/php-fpm.d/zz-pool.conf
|
||||
COPY docker/nginx/default.conf /etc/nginx/http.d/default.conf
|
||||
COPY docker/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
|
||||
COPY docker/entrypoint.sh /usr/local/bin/entrypoint.sh
|
||||
|
||||
RUN chmod +x /usr/local/bin/entrypoint.sh \
|
||||
COPY docker/healthcheck.sh /usr/local/bin/healthcheck.sh
|
||||
|
||||
# Make nginx run as the non-root www-data user:
|
||||
# - drop the `user nginx;` directive (ignored + warns when master isn't root)
|
||||
# - put the pid file in a www-data-writable path (default /run/nginx is root-only)
|
||||
RUN sed -i '/^user /d' /etc/nginx/nginx.conf \
|
||||
&& sed -i '1i pid /tmp/nginx.pid;' /etc/nginx/nginx.conf
|
||||
|
||||
RUN chmod +x /usr/local/bin/entrypoint.sh /usr/local/bin/healthcheck.sh \
|
||||
&& mkdir -p var/cache var/log var/uploads public/uploads config/jwt \
|
||||
# Source may be copied with restrictive (0600) host perms; ensure the runtime
|
||||
# user (www-data) can read all app files — opcache preload runs as www-data
|
||||
# and otherwise fails with "Permission denied" on /app/config/preload.php.
|
||||
&& chmod -R a+rX /app \
|
||||
&& chown -R www-data:www-data var public/uploads config/jwt
|
||||
&& chown -R www-data:www-data var public/uploads config/jwt \
|
||||
# nginx (run as www-data) needs to write its temp/cache/log dirs.
|
||||
&& chown -R www-data:www-data /var/lib/nginx /var/log/nginx 2>/dev/null || true
|
||||
|
||||
EXPOSE 80
|
||||
# Drop privileges: the entrypoint, supervisord, php-fpm and nginx all run as
|
||||
# www-data. nginx binds 8080 (non-privileged) so root is never required.
|
||||
USER www-data
|
||||
|
||||
EXPOSE 8080
|
||||
HEALTHCHECK --interval=15s --timeout=5s --retries=5 --start-period=60s \
|
||||
CMD ["/usr/local/bin/healthcheck.sh"]
|
||||
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
|
||||
CMD ["supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]
|
||||
|
||||
Reference in New Issue
Block a user