From 01e11c3b0053d0a9136fcb17aeaaa3b454b59d72 Mon Sep 17 00:00:00 2001 From: Soner Sayakci Date: Mon, 14 Oct 2024 11:20:52 +0200 Subject: [PATCH 1/6] feat: add nginx variant --- caddy/rootfs/etc/supervisord.conf | 3 +- nginx/Dockerfile | 20 ++++++ nginx/rootfs/etc/nginx/nginx.conf | 116 ++++++++++++++++++++++++++++++ nginx/rootfs/etc/supervisord.conf | 17 +++++ 4 files changed, 155 insertions(+), 1 deletion(-) create mode 100644 nginx/Dockerfile create mode 100644 nginx/rootfs/etc/nginx/nginx.conf create mode 100644 nginx/rootfs/etc/supervisord.conf diff --git a/caddy/rootfs/etc/supervisord.conf b/caddy/rootfs/etc/supervisord.conf index cef5ede..3be7525 100644 --- a/caddy/rootfs/etc/supervisord.conf +++ b/caddy/rootfs/etc/supervisord.conf @@ -2,6 +2,7 @@ nodaemon=true logfile=/dev/stderr logfile_maxbytes=0 +pidfile=/tmp/supervisord.pid [program:php-fpm] command=/usr/local/sbin/php-fpm @@ -13,4 +14,4 @@ stdout_logfile_maxbytes=0 command=/usr/sbin/caddy run --config /etc/caddy/Caddyfile --adapter caddyfile redirect_stderr=true stdout_logfile=/dev/stderr -stdout_logfile_maxbytes=0 \ No newline at end of file +stdout_logfile_maxbytes=0 diff --git a/nginx/Dockerfile b/nginx/Dockerfile new file mode 100644 index 0000000..81e8e0b --- /dev/null +++ b/nginx/Dockerfile @@ -0,0 +1,20 @@ +#syntax=docker/dockerfile:1.4 + +ARG FPM_IMAGE=ghcr.io/shopware/docker-base:8.3.1-fpm + +FROM ${FPM_IMAGE} + +USER root + +RUN apk add --no-cache nginx supervisor + +USER www-data + +COPY --link rootfs / + +EXPOSE 8000 +WORKDIR /var/www/html + +ENV FPM_LISTEN=/tmp/php-fpm.sock + +ENTRYPOINT [ "/usr/bin/supervisord", "-c", "/etc/supervisord.conf" ] diff --git a/nginx/rootfs/etc/nginx/nginx.conf b/nginx/rootfs/etc/nginx/nginx.conf new file mode 100644 index 0000000..2480dba --- /dev/null +++ b/nginx/rootfs/etc/nginx/nginx.conf @@ -0,0 +1,116 @@ +worker_processes auto; +pid /tmp/nginx.pid; +daemon off; +error_log stderr warn; +pcre_jit on; + +events { + worker_connections 1024; +} + +http { + client_body_temp_path /tmp/client_body_temp; + proxy_temp_path /tmp/proxy_temp; + fastcgi_temp_path /tmp/fastcgi_temp; + uwsgi_temp_path /tmp/uwsgi_temp; + scgi_temp_path /tmp/scgi_temp; + error_log /dev/fd/2 warn; + client_max_body_size 8M; + server_tokens off; + sendfile on; + tcp_nopush on; + + log_format json_combined escape=json + '{' + '"time_local":"$time_local",' + '"remote_addr":"$remote_addr",' + '"remote_user":"$remote_user",' + '"request":"$request",' + '"status": "$status",' + '"body_bytes_sent":"$body_bytes_sent",' + '"request_time":"$request_time",' + '"http_referrer":"$http_referer",' + '"http_user_agent":"$http_user_agent"' + '}'; + + access_log /dev/fd/1 json_combined; + + server { + listen 8000; + server_name localhost; + + root /var/www/html/public; + index index.php; + include /etc/nginx/mime.types; + + # Deny access to . (dot) files + location ~ /\. { + deny all; + } + + # Deny access to .php files in public directories + location ~ ^/(media|thumbnail|theme|bundles|sitemap).*\.php$ { + deny all; + } + + location ~ ^/(theme|media|thumbnail|bundles|css|fonts|js|recovery|sitemap)/ { + expires 1y; + add_header Cache-Control "public, must-revalidate, proxy-revalidate"; + log_not_found off; + tcp_nodelay off; + open_file_cache max=3000 inactive=120s; + open_file_cache_valid 45s; + open_file_cache_min_uses 2; + open_file_cache_errors off; + + location ~* ^.+\.svg { + add_header Content-Security-Policy "script-src 'none'"; + add_header Cache-Control "public, must-revalidate, proxy-revalidate"; + log_not_found off; + } + } + + location ~* ^.+\.(?:css|cur|js|jpe?g|gif|ico|png|svg|webp|html|woff|woff2|xml)$ { + expires 1y; + add_header Cache-Control "public, must-revalidate, proxy-revalidate"; + + access_log off; + + # The directive enables or disables messages in error_log about files not found on disk. + log_not_found off; + + tcp_nodelay off; + + ## Set the OS file cache. + open_file_cache max=3000 inactive=120s; + open_file_cache_valid 45s; + open_file_cache_min_uses 2; + open_file_cache_errors off; + + try_files $uri /index.php$is_args$args; + } + + location ~* ^.+\.svg$ { + add_header Content-Security-Policy "script-src 'none'"; + } + + location / { + try_files $uri /index.php$is_args$args; + } + + location ~ \.php$ { + fastcgi_split_path_info ^(.+\.php)(/.+)$; + include fastcgi.conf; + fastcgi_buffers 8 16k; + fastcgi_buffer_size 32k; + fastcgi_read_timeout 300s; + client_body_buffer_size 128k; + fastcgi_pass unix:/tmp/php-fpm.sock; + } + + gzip on; + gzip_min_length 1000; + gzip_proxied expired no-cache no-store private auth; + gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript; + } +} diff --git a/nginx/rootfs/etc/supervisord.conf b/nginx/rootfs/etc/supervisord.conf new file mode 100644 index 0000000..846696e --- /dev/null +++ b/nginx/rootfs/etc/supervisord.conf @@ -0,0 +1,17 @@ +[supervisord] +nodaemon=true +logfile=/dev/stderr +logfile_maxbytes=0 +pidfile=/tmp/supervisord.pid + +[program:php-fpm] +command=/usr/local/sbin/php-fpm +redirect_stderr=true +stdout_logfile=/dev/stderr +stdout_logfile_maxbytes=0 + +[program:nginx] +command=/usr/sbin/nginx +redirect_stderr=true +stdout_logfile=/dev/stderr +stdout_logfile_maxbytes=0 From 97fb35870067a3188cebf0f432833d981bb06715 Mon Sep 17 00:00:00 2001 From: Soner Sayakci Date: Mon, 14 Oct 2024 11:26:24 +0200 Subject: [PATCH 2/6] feat: add nginx and nginx-otel build jobs to CI workflow --- .github/workflows/build.yml | 75 ++++++++++++++++++++++++++++++++++++- matrix.php | 22 +++++++++++ 2 files changed, 95 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ad0fabe..02c137e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -167,10 +167,81 @@ jobs: push: true provenance: false + nginx: + name: Build Nginx with ${{ matrix.php }} + runs-on: ubuntu-latest + needs: [generate-matrix, fpm] + strategy: ${{ fromJson(needs.generate-matrix.outputs.matrix) }} + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Login into Docker Hub + if: github.ref == 'refs/heads/main' + run: echo "${{ secrets.DOCKER_HUB_PASSWORD }}" | docker login -u ${{ secrets.DOCKER_HUB_USERNAME }} --password-stdin + + - name: Login into Github Docker Registery + run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build and Push + uses: docker/build-push-action@v6 + with: + tags: | + ${{ matrix.nginx-tags }} + context: nginx + cache-from: type=registry,ref=ghcr.io/shopware/docker-cache:${{ matrix.php }}-nginx + cache-to: type=registry,ref=ghcr.io/shopware/docker-cache:${{ matrix.php }}-nginx,mode=max + platforms: linux/amd64,linux/arm64 + build-args: | + FPM_IMAGE=${{ matrix.fpm-image }} + push: true + provenance: false + + nginx-otel: + name: Build Nginx with ${{ matrix.php }} with OpenTelemetry + runs-on: ubuntu-latest + needs: [generate-matrix, fpm] + strategy: ${{ fromJson(needs.generate-matrix.outputs.matrix) }} + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Login into Docker Hub + if: github.ref == 'refs/heads/main' + run: echo "${{ secrets.DOCKER_HUB_PASSWORD }}" | docker login -u ${{ secrets.DOCKER_HUB_USERNAME }} --password-stdin + + - name: Login into Github Docker Registery + run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build and Push + uses: docker/build-push-action@v6 + with: + tags: | + ${{ matrix.nginx-tags-otel }} + context: nginx + cache-from: type=registry,ref=ghcr.io/shopware/docker-cache:${{ matrix.php }}-nginx-otel + cache-to: type=registry,ref=ghcr.io/shopware/docker-cache:${{ matrix.php }}-nginx-otel,mode=max + platforms: linux/amd64,linux/arm64 + build-args: | + FPM_IMAGE=${{ matrix.fpm-image }}-otel + push: true + provenance: false + check: - name: Test Image + name: Test Image with Webserver ${{ matrix.webserver }} runs-on: ubuntu-latest needs: [caddy] + strategy: + matrix: + webserver: + - caddy + - nginx steps: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 @@ -188,7 +259,7 @@ jobs: - name: Build PR if: github.ref != 'refs/heads/main' - run: docker compose build --build-arg BASE_IMAGE=ghcr.io/shopware/docker-base-ci-test:${{ github.run_id }}-8.3-caddy + run: docker compose build --build-arg BASE_IMAGE=ghcr.io/shopware/docker-base-ci-test:${{ github.run_id }}-8.3-${{ matrix.webserver}} env: DOCKER_BUILDKIT: 0 diff --git a/matrix.php b/matrix.php index dba8cd6..858ea7a 100644 --- a/matrix.php +++ b/matrix.php @@ -90,6 +90,16 @@ function get_digest_of_image(string $imageName, string $tag): string { 'ghcr.io/shopware/docker-base' . $imageSuffix . ':' . $imageTagPrefix . $patchVersion['version'] . '-caddy-otel', ]; + $nginxImages = [ + 'ghcr.io/shopware/docker-base' . $imageSuffix . ':' . $imageTagPrefix . $supportedVersion . '-nginx', + 'ghcr.io/shopware/docker-base' . $imageSuffix . ':' . $imageTagPrefix . $patchVersion['version'] . '-nginx', + ]; + + $nginxImagesOtel = [ + 'ghcr.io/shopware/docker-base' . $imageSuffix . ':' . $imageTagPrefix . $supportedVersion . '-nginx-otel', + 'ghcr.io/shopware/docker-base' . $imageSuffix . ':' . $imageTagPrefix . $patchVersion['version'] . '-nginx-otel', + ]; + $fpmImages = [ 'ghcr.io/shopware/docker-base' . $imageSuffix . ':' . $imageTagPrefix . $supportedVersion . '-fpm', 'ghcr.io/shopware/docker-base' . $imageSuffix . ':' . $imageTagPrefix . $patchVersion['version'] . '-fpm' @@ -113,6 +123,16 @@ function get_digest_of_image(string $imageName, string $tag): string { 'shopware/docker-base:' . $imageTagPrefix . $patchVersion['version'] . '-caddy-otel', ]); + $nginxImages = array_merge($nginxImages, [ + 'shopware/docker-base:' . $imageTagPrefix . $supportedVersion . '-nginx', + 'shopware/docker-base:' . $imageTagPrefix . $patchVersion['version'] . '-nginx', + ]); + + $nginxImagesOtel = array_merge($nginxImagesOtel, [ + 'shopware/docker-base:' . $imageTagPrefix . $supportedVersion . '-nginx-otel', + 'shopware/docker-base:' . $imageTagPrefix . $patchVersion['version'] . '-nginx-otel', + ]); + $fpmImages = array_merge($fpmImages, [ 'shopware/docker-base:' . $imageTagPrefix . $supportedVersion . '-fpm', 'shopware/docker-base:' . $imageTagPrefix . $patchVersion['version'] . '-fpm' @@ -133,6 +153,8 @@ function get_digest_of_image(string $imageName, string $tag): string { 'fpm-tags-otel' => implode("\n", $fpmImagesOtel), 'caddy-tags' => implode("\n", $caddyImages), 'caddy-tags-otel' => implode("\n", $caddyImagesOtel), + 'nginx-tags' => implode("\n", $nginxImages), + 'nginx-tags-otel' => implode("\n", $nginxImagesOtel), 'scan-tag' => $caddyImages[0], 'scan-to' => 'ghcr.io/shopware/docker-base:'.$supportedVersion, ]; From 366c66214de891d9a82098af9c7f4de7761b2e30 Mon Sep 17 00:00:00 2001 From: Soner Sayakci Date: Mon, 14 Oct 2024 11:31:29 +0200 Subject: [PATCH 3/6] fix: reorder job dependencies and improve health check steps in CI workflow --- .github/workflows/build.yml | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 02c137e..0f117d6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -140,7 +140,7 @@ jobs: caddy-otel: name: Build Caddy ${{ matrix.php }} with OpenTelemetry runs-on: ubuntu-latest - needs: [fpm-otel, generate-matrix] + needs: [generate-matrix, fpm-otel] strategy: ${{ fromJson(needs.generate-matrix.outputs.matrix) }} steps: - name: Checkout @@ -203,7 +203,7 @@ jobs: nginx-otel: name: Build Nginx with ${{ matrix.php }} with OpenTelemetry runs-on: ubuntu-latest - needs: [generate-matrix, fpm] + needs: [generate-matrix, fpm-otel] strategy: ${{ fromJson(needs.generate-matrix.outputs.matrix) }} steps: - name: Checkout @@ -236,7 +236,7 @@ jobs: check: name: Test Image with Webserver ${{ matrix.webserver }} runs-on: ubuntu-latest - needs: [caddy] + needs: [caddy, nginx] strategy: matrix: webserver: @@ -284,10 +284,13 @@ jobs: sleep 5 done - - name: Check if shopware is running + - name: Check if shopware admin is running run: curl --fail localhost:8000/admin + - name: Check if shopware is running + run: curl --fail localhost:8000 + # output logs if failed - name: Output logs run: docker compose logs - if: ${{ failure() }} + if: ${{ always() }} From 1cc2b4c34ee9db305a0cc244ea55029020c57cc8 Mon Sep 17 00:00:00 2001 From: Shyim Date: Mon, 14 Oct 2024 11:47:03 +0200 Subject: [PATCH 4/6] Update nginx/rootfs/etc/nginx/nginx.conf Co-authored-by: tinect --- nginx/rootfs/etc/nginx/nginx.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nginx/rootfs/etc/nginx/nginx.conf b/nginx/rootfs/etc/nginx/nginx.conf index 2480dba..8e251de 100644 --- a/nginx/rootfs/etc/nginx/nginx.conf +++ b/nginx/rootfs/etc/nginx/nginx.conf @@ -111,6 +111,6 @@ http { gzip on; gzip_min_length 1000; gzip_proxied expired no-cache no-store private auth; - gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript; + gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript application/atom+xml application/json application/vnd.api+json application/rss+xml application/vnd.ms-fontobject application/x-font-opentype application/x-font-truetype application/x-font-ttf application/xhtml+xml font/eot font/opentype font/otf font/truetype image/svg+xml image/vnd.microsoft.icon; } } From 02241d41eb5f220c3adc6f8039b3349bb18faaf6 Mon Sep 17 00:00:00 2001 From: Soner Sayakci Date: Mon, 14 Oct 2024 12:09:33 +0200 Subject: [PATCH 5/6] fix: update gzip_types in nginx configuration for consistency --- nginx/rootfs/etc/nginx/nginx.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nginx/rootfs/etc/nginx/nginx.conf b/nginx/rootfs/etc/nginx/nginx.conf index 8e251de..454623c 100644 --- a/nginx/rootfs/etc/nginx/nginx.conf +++ b/nginx/rootfs/etc/nginx/nginx.conf @@ -111,6 +111,6 @@ http { gzip on; gzip_min_length 1000; gzip_proxied expired no-cache no-store private auth; - gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript application/atom+xml application/json application/vnd.api+json application/rss+xml application/vnd.ms-fontobject application/x-font-opentype application/x-font-truetype application/x-font-ttf application/xhtml+xml font/eot font/opentype font/otf font/truetype image/svg+xml image/vnd.microsoft.icon; + gzip_types text/plain text/css application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript application/atom+xml application/json application/vnd.api+json application/rss+xml application/vnd.ms-fontobject application/x-font-opentype application/x-font-truetype application/x-font-ttf application/xhtml+xml font/eot font/opentype font/otf font/truetype image/svg+xml image/vnd.microsoft.icon; } } From a66a18cf78dd8fc1740db0dfc16bdc9e0b5e70d1 Mon Sep 17 00:00:00 2001 From: Soner Sayakci Date: Mon, 14 Oct 2024 12:14:17 +0200 Subject: [PATCH 6/6] fix: update nginx command in supervisord configuration to specify error log path --- nginx/rootfs/etc/supervisord.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nginx/rootfs/etc/supervisord.conf b/nginx/rootfs/etc/supervisord.conf index 846696e..d7941c0 100644 --- a/nginx/rootfs/etc/supervisord.conf +++ b/nginx/rootfs/etc/supervisord.conf @@ -11,7 +11,7 @@ stdout_logfile=/dev/stderr stdout_logfile_maxbytes=0 [program:nginx] -command=/usr/sbin/nginx +command=/usr/sbin/nginx -e /tmp/error.log redirect_stderr=true stdout_logfile=/dev/stderr stdout_logfile_maxbytes=0