From 58752d83d8310039eb3b3f15f9d36d063a5b903d Mon Sep 17 00:00:00 2001 From: Leonard Jonathan Oh Date: Sun, 29 Oct 2023 16:15:01 +0000 Subject: [PATCH] Enhancement (ci): Combine `nginx` and `php` into a single `web` container --- .github/workflows/ci-master-pr.yml | 19 +++++-- Dockerfile.web-php => Dockerfile.web | 20 +++++-- Dockerfile.web-nginx | 18 ------ README.md | 24 ++++---- config/web/{ => etc}/nginx/nginx.conf | 9 ++- config/web/php-fpm.d/www.conf | 10 ---- config/web/supervisor.conf | 31 ++++++++++ .../web/usr/local/etc/php-fpm.d/php-fpm.conf | 27 +++++++++ .../{ => usr/local/etc}/php/conf.d/php.ini | 0 docker-compose.test.yml | 38 ++++++------- docker-compose.tmp.yml | 12 ---- docker-compose.yml | 57 +++++++------------ 12 files changed, 146 insertions(+), 119 deletions(-) rename Dockerfile.web-php => Dockerfile.web (71%) delete mode 100644 Dockerfile.web-nginx rename config/web/{ => etc}/nginx/nginx.conf (93%) delete mode 100644 config/web/php-fpm.d/www.conf create mode 100644 config/web/supervisor.conf create mode 100644 config/web/usr/local/etc/php-fpm.d/php-fpm.conf rename config/web/{ => usr/local/etc}/php/conf.d/php.ini (100%) delete mode 100644 docker-compose.tmp.yml diff --git a/.github/workflows/ci-master-pr.yml b/.github/workflows/ci-master-pr.yml index aa635a72..e76e4708 100644 --- a/.github/workflows/ci-master-pr.yml +++ b/.github/workflows/ci-master-pr.yml @@ -21,13 +21,21 @@ jobs: id: buildx uses: docker/setup-buildx-action@v2 - - name: Cache Docker layers + - name: Cache Docker layers (daemon) uses: actions/cache@v3 with: - path: /tmp/.buildx-cache - key: ${{ runner.os }}-buildx-test-${{ github.sha }} + path: /tmp/.buildx-cache-daemon + key: ${{ runner.os }}-buildx-daemon-${{ github.sha }} + restore-keys: | + ${{ runner.os }}-buildx-daemon- + + - name: Cache Docker layers (web) + uses: actions/cache@v3 + with: + path: /tmp/.buildx-cache-web + key: ${{ runner.os }}-buildx-web-${{ github.sha }} restore-keys: | - ${{ runner.os }}-buildx-test- + ${{ runner.os }}-buildx-web- - name: Print buildx and compose run: | @@ -45,9 +53,8 @@ jobs: strategy: matrix: variant: - - web-nginx - - web-php - daemon + - web runs-on: ubuntu-latest steps: - name: Checkout diff --git a/Dockerfile.web-php b/Dockerfile.web similarity index 71% rename from Dockerfile.web-php rename to Dockerfile.web index 6ecf98ca..77c56e2e 100644 --- a/Dockerfile.web-php +++ b/Dockerfile.web @@ -3,6 +3,9 @@ ARG TARGETPLATFORM ARG BUILDPLATFORM RUN echo "I am running on $BUILDPLATFORM, building for $TARGETPLATFORM" +# Install nginx and supervisor for multi-process container +RUN apk add --no-cache ca-certificates nginx supervisor + # opcache RUN docker-php-ext-install opcache @@ -56,6 +59,19 @@ RUN set -eux; \ php -i; \ php -m +# Add default configs +COPY ./config/web/supervisor.conf /supervisor.conf +COPY ./config/web/etc/nginx/nginx.conf /etc/nginx/nginx.conf +COPY ./config/web/usr/local/etc/php/conf.d/php.ini /usr/local/etc/php/conf.d/php.ini +COPY ./config/web/usr/local/etc/php-fpm.d/php-fpm.conf /usr/local/etc/php-fpm.d/php-fpm.conf +# Disable the built-in php-fpm configs, since we're using our own config +RUN set -eux; \ + mv -v /usr/local/etc/php-fpm.d/docker.conf /usr/local/etc/php-fpm.d/docker.conf.disabled; \ + mv -v /usr/local/etc/php-fpm.d/www.conf /usr/local/etc/php-fpm.d/www.conf.disabled; \ + mv -v /usr/local/etc/php-fpm.d/zz-docker.conf /usr/local/etc/php-fpm.d/zz-docker.conf.disabled; + +CMD ["/usr/bin/supervisord", "-c", "/supervisor.conf", "--pidfile", "/run/supervisord.pid"] + FROM base AS prod # Set permissions for 'www-data' user @@ -71,7 +87,3 @@ RUN set -eux; \ chown -R www-data:www-data /heatmaps; \ find /heatmaps -type d -exec chmod 750 {} \; ; \ find /heatmaps -type f -exec chmod 640 {} \; ; - -# Add default configs -COPY ./config/web/php/conf.d/php.ini /usr/local/etc/php/conf.d/php.ini -COPY ./config/web/php-fpm.d/www.conf /usr/local/etc/php-fpm.d/www.conf diff --git a/Dockerfile.web-nginx b/Dockerfile.web-nginx deleted file mode 100644 index 8b38fd71..00000000 --- a/Dockerfile.web-nginx +++ /dev/null @@ -1,18 +0,0 @@ -FROM nginx:1.21-alpine AS base - -WORKDIR /web - -FROM base AS dev - -FROM base AS prod - -# Set permissions for 'nginx' user -# COPY --chown=nginx:nginx --chmod=640 /web /web -COPY ./web /web -RUN set -eux; \ - chown -R nginx:nginx /web; \ - find /web -type d -exec chmod 750 {} \; ; \ - find /web -type f -exec chmod 640 {} \; ; - -# Add default configs -COPY config/web/nginx/nginx.conf /etc/nginx/nginx.conf diff --git a/README.md b/README.md index b060af3c..73427461 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ [![github-actions](https://github.com/startersclan/hlstatsx-community-edition/workflows/ci-master-pr/badge.svg)](https://github.com/startersclan/hlstatsx-community-edition/actions) [![github-release](https://img.shields.io/github/v/release/startersclan/hlstatsx-community-edition?style=flat-square)](https://github.com/startersclan/hlstatsx-community-edition/releases/) -[![docker-image-size](https://img.shields.io/docker/image-size/startersclan/hlstatsx-community-edition/web)](https://hub.docker.com/r/startersclan/hlstatsx-community-edition) -[![docker-image-size](https://img.shields.io/docker/image-size/startersclan/hlstatsx-community-edition/daemon)](https://hub.docker.com/r/startersclan/hlstatsx-community-edition) +[![docker-image-size](https://img.shields.io/docker/image-size/startersclan/hlstatsx-community-edition/master-web?label=web)](https://hub.docker.com/r/startersclan/hlstatsx-community-edition) +[![docker-image-size](https://img.shields.io/docker/image-size/startersclan/hlstatsx-community-edition/master-daemon?label=daemon)](https://hub.docker.com/r/startersclan/hlstatsx-community-edition) HLstatsX Community Edition is an open-source project licensed under GNU General Public License v2 and is a real-time stats @@ -32,11 +32,18 @@ a PHP frontend. --- +## Usage + +```sh +docker run --rm -it -p 80:80 startersclan/hlstatsx-community-edition:v1.7.0-web +docker run --rm -it -p 27500:27500/udp startersclan/hlstatsx-community-edition:v1.7.0-daemon --help +``` + ## Development ```sh # 1. Start Counter-strike 1.6 server, source-udp-forwarder, HLStatsX:CE stack -docker compose up +docker compose up --build # HLStatsX:CE web frontend available at http://localhost:8081/. Admin Panel username: admin, password 123456 # phpmyadmin available at http://localhost:8083. Root username: root, root password: root. Username: hlstatsxce, password: hlstatsxce @@ -76,10 +83,8 @@ docker attach $( docker compose ps -q cstrike ) # CS 1.6 server - Exec into container docker exec -it $( docker compose ps -q cstrike) bash -# web-nginx - Exec into container -docker exec -it $( docker compose ps -q web-nginx ) sh -# web-php - Exec into container -docker exec -it $( docker compose ps -q web-php ) sh +# web - Exec into container +docker exec -it $( docker compose ps -q web ) sh # Run awards docker exec -it $( docker compose ps -q awards) sh -c /awards.sh # Generate heatmaps @@ -88,12 +93,11 @@ docker exec -it $( docker compose ps -q heatmaps) php /heatmaps/generate.php #-- docker exec -it $( docker compose ps -q db ) sh # Test routes -docker compose -f docker compose.test.yml up +docker compose -f docker-compose.test.yml up # Test production builds locally docker build -t startersclan/hlstatsx-community-edition:daemon -f Dockerfile.daemon . -docker build -t startersclan/hlstatsx-community-edition:web-nginx -f Dockerfile.web-nginx . -docker build -t startersclan/hlstatsx-community-edition:web-php -f Dockerfile.web-php . +docker build -t startersclan/hlstatsx-community-edition:web -f Dockerfile.web . # Dump the DB docker exec $( docker compose ps -q db ) mysqldump -uroot -proot hlstatsxce | gzip > hlstatsxce.sql.gz diff --git a/config/web/nginx/nginx.conf b/config/web/etc/nginx/nginx.conf similarity index 93% rename from config/web/nginx/nginx.conf rename to config/web/etc/nginx/nginx.conf index 2000f627..66a59f65 100644 --- a/config/web/nginx/nginx.conf +++ b/config/web/etc/nginx/nginx.conf @@ -70,8 +70,11 @@ http { location ~ /\.[^/]+$ { return 401; } - # Deny access to the certain folders - location ~ ^/(includes|pages|updater|system) { + # Deny access to the certain files / folders + location ~ ^/config.php { + return 401; + } + location ~ ^/(includes|pages|updater|system)/ { return 401; } @@ -88,7 +91,7 @@ http { include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_index index.php; - fastcgi_pass web-php:9000; + fastcgi_pass 127.0.0.1:9000; } location / { diff --git a/config/web/php-fpm.d/www.conf b/config/web/php-fpm.d/www.conf deleted file mode 100644 index eefbe39b..00000000 --- a/config/web/php-fpm.d/www.conf +++ /dev/null @@ -1,10 +0,0 @@ -[www] -user = www-data -group = www-data -security.limit_extensions = .php .aspx -pm = dynamic -pm.max_children = 5 -pm.start_servers = 2 -pm.min_spare_servers = 1 -pm.max_spare_servers = 3 -pm.status_path = /status.php diff --git a/config/web/supervisor.conf b/config/web/supervisor.conf new file mode 100644 index 00000000..26409e23 --- /dev/null +++ b/config/web/supervisor.conf @@ -0,0 +1,31 @@ +[supervisord] +nodaemon=true +user=root +logfile=/dev/null +logfile_maxbytes=0 + +[program:nginx] +command=nginx -c /etc/nginx/nginx.conf -g 'daemon off;' +process_name=%(program_name)s_%(process_num)02d +user=root +numprocs=1 +autostart=true +autorestart=false +startsecs=0 +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +stderr_logfile=/dev/stderr +stderr_logfile_maxbytes=0 + +[program:php-fpm] +command=php-fpm -F +process_name=%(program_name)s_%(process_num)02d +user=root +numprocs=1 +autostart=true +autorestart=false +startsecs=0 +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +stderr_logfile=/dev/stderr +stderr_logfile_maxbytes=0 diff --git a/config/web/usr/local/etc/php-fpm.d/php-fpm.conf b/config/web/usr/local/etc/php-fpm.d/php-fpm.conf new file mode 100644 index 00000000..982418db --- /dev/null +++ b/config/web/usr/local/etc/php-fpm.d/php-fpm.conf @@ -0,0 +1,27 @@ +[global] +daemonize = no +error_log = /proc/self/fd/2 +; https://github.com/docker-library/php/pull/725#issuecomment-443540114 +log_limit = 8192 +log_buffering = no + +[default] +listen = 9000 +user = www-data +listen.owner = www-data +listen.group = www-data +pm = dynamic +pm.max_children = 30 +pm.start_servers = 2 +pm.min_spare_servers = 1 +pm.max_spare_servers = 3 +pm.process_idle_timeout = 10s +pm.max_requests = 500 +catch_workers_output = yes +decorate_workers_output = no +chdir = / +pm.status_path = /status +php_admin_value[log_errors] = On +php_admin_value[expose_php] = Off +php_admin_value[display_errors] = Off +php_admin_value[date.timezone] = UTC diff --git a/config/web/php/conf.d/php.ini b/config/web/usr/local/etc/php/conf.d/php.ini similarity index 100% rename from config/web/php/conf.d/php.ini rename to config/web/usr/local/etc/php/conf.d/php.ini diff --git a/docker-compose.test.yml b/docker-compose.test.yml index a0620a49..d85fbbe9 100644 --- a/docker-compose.test.yml +++ b/docker-compose.test.yml @@ -4,23 +4,23 @@ services: image: alpine:latest environment: URLS: | - http://web-nginx/ 302 - http://web-nginx/css/spinner.gif 200 - http://web-nginx/hlstatsimg/ajax.gif 200 - http://web-nginx/includes/ 401 - http://web-nginx/pages/ 401 - http://web-nginx/pages/.htaccess 401 - http://web-nginx/styles/classic.css 200 - http://web-nginx/updater/ 401 - http://web-nginx/autocomplete.php 200 - http://web-nginx/config.php 200 - http://web-nginx/hlstats.php 200 - http://web-nginx/index.php 302 - http://web-nginx/ingame.php 200 - http://web-nginx/show_graph.php 200 - http://web-nginx/sig.php 200 - http://web-nginx/status.php 200 - http://web-nginx/trend_graph.php 200 + http://web/ 302 + http://web/css/spinner.gif 200 + http://web/hlstatsimg/ajax.gif 200 + http://web/includes/ 401 + http://web/pages/ 401 + http://web/pages/.htaccess 401 + http://web/styles/classic.css 200 + http://web/updater/ 401 + http://web/autocomplete.php 200 + http://web/config.php 401 + http://web/hlstats.php 200 + http://web/index.php 302 + http://web/ingame.php 200 + http://web/show_graph.php 200 + http://web/sig.php 200 + http://web/status.php 200 + http://web/trend_graph.php 200 networks: - default entrypoint: @@ -33,8 +33,8 @@ services: echo "Waiting for stack to be ready" s=0 while true; do - nc -vz -w 1 web-nginx 80 \ - && nc -vz -w 1 web-php 9000 \ + nc -vz -w 1 web 80 \ + && nc -vz -w 1 web 9000 \ && nc -vz -w 1 db 3306 \ && break || true s=$$(( $$s + 1 )) diff --git a/docker-compose.tmp.yml b/docker-compose.tmp.yml deleted file mode 100644 index e3c26e97..00000000 --- a/docker-compose.tmp.yml +++ /dev/null @@ -1,12 +0,0 @@ -version: '2.2' -services: - test: - build: - dockerfile_inline: | - FROM alpine:3.17 - RUN echo hello - cache_from: - - type=local,src=/tmp/.buildx-cache - cache_to: - - type=local,dest=/tmp/.buildx-cache,mode=max - diff --git a/docker-compose.yml b/docker-compose.yml index ddd33028..905893fa 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -63,9 +63,9 @@ services: context: . target: dev cache_from: - - type=local,src=/tmp/.buildx-cache + - type=local,src=/tmp/.buildx-cache-daemon cache_to: - - type=local,dest=/tmp/.buildx-cache,mode=max + - type=local,dest=/tmp/.buildx-cache-daemon,mode=max ports: - 27500:27500/udp # For external servers to send logs to the daemon networks: @@ -92,9 +92,9 @@ services: context: . target: dev cache_from: - - type=local,src=/tmp/.buildx-cache + - type=local,src=/tmp/.buildx-cache-daemon cache_to: - - type=local,dest=/tmp/.buildx-cache,mode=max + - type=local,dest=/tmp/.buildx-cache-daemon,mode=max stop_signal: SIGKILL entrypoint: - /bin/sh @@ -137,45 +137,28 @@ services: networks: - default - # 5a. HLStatsX:CE web - nginx - # Available at http://localhost:8083 + # 5. HLStatsX:CE web + # Available at http://localhost:8081 # Admin Panel username: admin, password: 123456 - web-nginx: + web: build: - dockerfile: Dockerfile.web-nginx + dockerfile: Dockerfile.web context: . target: dev cache_from: - - type=local,src=/tmp/.buildx-cache + - type=local,src=/tmp/.buildx-cache-web cache_to: - - type=local,dest=/tmp/.buildx-cache,mode=max + - type=local,dest=/tmp/.buildx-cache-web,mode=max volumes: - ./web:/web - - ./config/web/nginx/nginx.conf:/etc/nginx/nginx.conf:ro + - ./config/web/config.php:/web/config.php:ro # Main config file + # - ./config/web/supervisor.conf:/supervisor.conf:ro + # - ./config/web/etc/nginx/nginx.conf:/etc/nginx/nginx.conf:ro + # - ./config/web/usr/local/etc/php/conf.d/php.ini:/usr/local/etc/php/conf.d/php.ini:ro + # - ./config/web/usr/local/etc/php-fpm.d/php-fpm.conf:/usr/local/etc/php-fpm.d/php-fpm.conf:ro ports: - 8081:80 - networks: - - default - depends_on: - - init-container - - web-php - working_dir: /web - - # 5b. HLStatsX:CE web - php - web-php: - build: - dockerfile: Dockerfile.web-php - context: . - target: dev - cache_from: - - type=local,src=/tmp/.buildx-cache - cache_to: - - type=local,dest=/tmp/.buildx-cache,mode=max - volumes: - - ./web:/web - - ./config/web/config.php:/web/config.php:ro # Main config file. - - ./config/web/php/conf.d/php.ini:/usr/local/etc/php/conf.d/php.ini:ro - - ./config/web/php-fpm.d/www.conf:/usr/local/etc/php-fpm.d/www.conf:ro + - 9000 networks: - default extra_hosts: @@ -188,17 +171,17 @@ services: # Cron - Heatmaps heatmaps: build: - dockerfile: Dockerfile.web-php + dockerfile: Dockerfile.web context: . target: base cache_from: - - type=local,src=/tmp/.buildx-cache + - type=local,src=/tmp/.buildx-cache-web cache_to: - - type=local,dest=/tmp/.buildx-cache,mode=max + - type=local,dest=/tmp/.buildx-cache-web,mode=max volumes: - ./web:/web - ./heatmaps:/heatmaps - - ./config/heatmaps/config.inc.php:/heatmaps/config.inc.php:ro # Heatmaps config file. + - ./config/heatmaps/config.inc.php:/heatmaps/config.inc.php:ro # Heatmaps config file working_dir: /heatmaps stop_signal: SIGKILL entrypoint: