From fe5f1179c7da9da42c7acd1e8c8869d2cdf7411c Mon Sep 17 00:00:00 2001 From: Kovah Date: Wed, 10 Mar 2021 22:35:21 +0100 Subject: [PATCH] Overhaul of the Docker build process and deployment configuration with support for ARM (#175) --- .github/workflows/build-docker-simple.yml | 2 +- .github/workflows/build-docker.yml | 2 +- docker-compose.production-simple.yml | 7 +- docker-compose.production.yml | 5 +- docker-compose.yml | 2 +- nginx-simple.conf => nginx-ssl.conf | 24 ++--- .../release-multiplatform-simple.Dockerfile | 97 +++++++++++++++++++ ...rfile => release-multiplatform.Dockerfile} | 18 ++-- .../docker/nginx/{site.conf => dev.conf} | 0 .../docker/nginx/nginx.conf | 16 ++- resources/docker/supervisor.ini | 27 ++++++ 11 files changed, 163 insertions(+), 37 deletions(-) rename nginx-simple.conf => nginx-ssl.conf (68%) create mode 100644 resources/docker/dockerfiles/release-multiplatform-simple.Dockerfile rename resources/docker/dockerfiles/{release-arm-test.Dockerfile => release-multiplatform.Dockerfile} (81%) rename resources/docker/nginx/{site.conf => dev.conf} (100%) rename nginx.conf => resources/docker/nginx/nginx.conf (80%) create mode 100644 resources/docker/supervisor.ini diff --git a/.github/workflows/build-docker-simple.yml b/.github/workflows/build-docker-simple.yml index 59d7e113..2e20ac3c 100644 --- a/.github/workflows/build-docker-simple.yml +++ b/.github/workflows/build-docker-simple.yml @@ -60,6 +60,6 @@ jobs: with: context: . file: ./resources/docker/dockerfiles/release-simple.Dockerfile - platforms: linux/amd64,linux/arm64,linux/arm/v6,linux/arm/v7 + platforms: linux/amd64,linux/arm64,linux/arm/v7 push: true tags: ${{ steps.prep.outputs.tags }} diff --git a/.github/workflows/build-docker.yml b/.github/workflows/build-docker.yml index 11b28a74..90165627 100644 --- a/.github/workflows/build-docker.yml +++ b/.github/workflows/build-docker.yml @@ -58,6 +58,6 @@ jobs: with: context: . file: ./resources/docker/dockerfiles/release.Dockerfile - platforms: linux/amd64,linux/arm64,linux/arm/v6,linux/arm/v7 + platforms: linux/amd64,linux/arm64,linux/arm/v7 push: true tags: ${{ steps.prep.outputs.tags }} diff --git a/docker-compose.production-simple.yml b/docker-compose.production-simple.yml index 81e99931..6dc9a289 100644 --- a/docker-compose.production-simple.yml +++ b/docker-compose.production-simple.yml @@ -26,12 +26,13 @@ services: #- "0.0.0.0:443:8443" volumes: - ./.env:/app/.env - - ./nginx-simple.conf:/opt/docker/etc/nginx/conf.d/linkace.conf:ro - linkace_logs:/app/storage/logs + # Remove the hash of the following line if you want to use HTTPS for this container + #- ./nginx-ssl.conf:/etc/nginx/conf.d/default.conf:ro + #- /path/to/your/ssl/certificates:/certs:ro # Remove the hash of the following line if you want to use local backups #- ./backups:/app/storage/app/backups - # Remove the hash of the following line if you are using HTTPS - #- /path/to/your/ssl/certificates:/opt/docker/etc/nginx/ssl + volumes: linkace_logs: diff --git a/docker-compose.production.yml b/docker-compose.production.yml index 9f11bc4c..089bc247 100644 --- a/docker-compose.production.yml +++ b/docker-compose.production.yml @@ -39,8 +39,9 @@ services: - app volumes: - linkace_app:/app - - ./nginx.conf:/opt/bitnami/nginx/conf/server_blocks/linkace.conf:ro - #- /path/to/your/ssl/certificates:/certs + # Remove the hash of the following line if you want to use HTTPS for this container + #- ./nginx-ssl.conf:/etc/nginx/conf.d/default.conf:ro + #- /path/to/your/ssl/certificates:/certs:ro # --- Redis redis: diff --git a/docker-compose.yml b/docker-compose.yml index 035c9a12..ada06c9e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -40,7 +40,7 @@ services: - php volumes: - .:/app:delegated - - ./resources/docker/nginx/site.conf:/opt/bitnami/nginx/conf/server_blocks/linkace.conf:ro + - ./resources/docker/nginx/dev.conf:/opt/bitnami/nginx/conf/server_blocks/linkace.conf:ro # --- Redis redis: diff --git a/nginx-simple.conf b/nginx-ssl.conf similarity index 68% rename from nginx-simple.conf rename to nginx-ssl.conf index eeea7c4b..97bd38d5 100644 --- a/nginx-simple.conf +++ b/nginx-ssl.conf @@ -8,12 +8,11 @@ server { port_in_redirect off; # Choose the connection method - listen 0.0.0.0:8080; - #listen 0.0.0.0:8443 ssl; + listen 0.0.0.0:8443 ssl; # Provide SSL certificates - #ssl_certificate /certs/[FULLCHAIN FILE NAME]; - #ssl_certificate_key /certs/[CERTIFICATE KEY FILE NAME]; + ssl_certificate /certs/[FULLCHAIN FILE NAME]; + ssl_certificate_key /certs/[CERTIFICATE KEY FILE NAME]; # Content security headers for Laravel add_header X-Frame-Options "SAMEORIGIN"; @@ -33,21 +32,24 @@ server { try_files $uri $uri/ /index.php?$query_string; } - # CSS and Javascript - location ~* \.(?:css|js|map|scss)$ { - expires 7d; - access_log off; - add_header Cache-Control "public"; - try_files $uri =404; + # Assets and media files + location ~* \.(?:css|js|map|scss|jpg|jpeg|png|gif|mp4|woff|woff2|ico|svg|webmanifest)$ { + expires max; + access_log off; + add_header Cache-Control "public"; + try_files $uri =404; } + location = /favicon.ico { access_log off; log_not_found off; } + location = /robots.txt { access_log off; log_not_found off; } + # Error pages error_page 404 /index.php; error_page 403 /index.php; # PHP handling location ~ \.php$ { - fastcgi_pass 127.0.0.1:9000; + fastcgi_pass app:9000; try_files $uri /index.php; include fastcgi.conf; diff --git a/resources/docker/dockerfiles/release-multiplatform-simple.Dockerfile b/resources/docker/dockerfiles/release-multiplatform-simple.Dockerfile new file mode 100644 index 00000000..830b1cb1 --- /dev/null +++ b/resources/docker/dockerfiles/release-multiplatform-simple.Dockerfile @@ -0,0 +1,97 @@ +# DOCKERFILE RELEASE + +# ================================ +# PHP Dependency Setup +FROM composer AS builder +WORKDIR /app + +# Make needed parts of the app available in the container +COPY ./app /app/app +COPY ./bootstrap /app/bootstrap +COPY ./config /app/config +COPY ./database /app/database +COPY ./resources /app +COPY ./routes /app/routes +COPY ./tests /app/tests + +COPY ./artisan /app +COPY ./composer.json /app +COPY ./composer.lock /app +COPY ./README.md /app +COPY ./.env.example /app/.env + +# Install dependencies using Composer +RUN composer install -n --prefer-dist --no-dev + +# ================================ +# Compile all assets +FROM node:14 AS npm_builder +WORKDIR /srv + +# Copy package.json and Gruntfile +COPY ./package.json ./ +COPY ./package-lock.json ./ +COPY ./webpack.mix.js ./ +COPY ./resources/assets ./resources/assets + +RUN npm install +RUN npm run production + +# ================================ +# Prepare the final image +FROM php:8.0-fpm-alpine +WORKDIR /app + +# Copy the app into the container +COPY ./app /app/app +COPY ./bootstrap /app/bootstrap +COPY ./config /app/config +COPY ./database /app/database +COPY ./public /app/public +COPY ./resources /app/resources +COPY ./routes /app/routes +COPY ./storage /app/storage +COPY ./tests /app/tests + +COPY ./artisan /app +COPY ./composer.json /app +COPY ./composer.lock /app +COPY ./README.md /app +COPY ./package.json /app +COPY ./server.php /app +COPY ./.env.example /app/.env + +# Copy the PHP and nginx config files +COPY ./resources/docker/php/php.ini /usr/local/etc/php/php.ini +COPY ./resources/docker/nginx/nginx.conf /etc/nginx/conf.d/default.conf + +# Install nginx, MySQL Dump for automated backups and other dependencies +RUN apk add --no-cache mariadb-client nginx supervisor postgresql postgresql-dev zip libzip-dev ; \ + docker-php-ext-configure zip ; \ + docker-php-ext-install bcmath pdo_mysql pdo_pgsql zip + +# Configure Supervisor for nginx +RUN mkdir /etc/supervisor.d/; \ + mkdir -p /run/nginx; \ + mkdir /ssl-certs ; \ + ln -sf /dev/stdout /var/log/nginx/access.log ; \ + ln -sf /dev/stderr /var/log/nginx/error.log +COPY ./resources/docker/supervisord.ini /etc/supervisor.d/supervisord.ini + +# Copy files from the composer build +COPY --from=builder /app/vendor /app/vendor +COPY --from=builder /app/bootstrap/cache /app/bootstrap/cache + +# Publish package resources +RUN php artisan vendor:publish --provider="Spatie\Backup\BackupServiceProvider" + +# Copy files from the theme build +COPY --from=npm_builder /srv/public/assets/dist/js /app/public/assets/dist/js +COPY --from=npm_builder /srv/public/assets/dist/css /app/public/assets/dist/css +COPY --from=npm_builder /srv/public/mix-manifest.json /app/public/mix-manifest.json + +# Set correct permissions for the storage directory +RUN chmod -R 0777 /app/storage + +EXPOSE 80 443 +CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor.d/supervisord.ini"] diff --git a/resources/docker/dockerfiles/release-arm-test.Dockerfile b/resources/docker/dockerfiles/release-multiplatform.Dockerfile similarity index 81% rename from resources/docker/dockerfiles/release-arm-test.Dockerfile rename to resources/docker/dockerfiles/release-multiplatform.Dockerfile index 3dbfa6c7..68fe1c7c 100644 --- a/resources/docker/dockerfiles/release-arm-test.Dockerfile +++ b/resources/docker/dockerfiles/release-multiplatform.Dockerfile @@ -2,13 +2,9 @@ # ================================ # PHP Dependency Setup -FROM php:8.0-fpm-alpine AS builder +FROM composer AS builder WORKDIR /app -# Install Composer -RUN apk add --no-cache git -RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer - # Make needed parts of the app available in the container COPY ./app /app/app COPY ./bootstrap /app/bootstrap @@ -65,11 +61,15 @@ COPY ./package.json /app COPY ./server.php /app COPY ./.env.example /app/.env -# Copy the PHP config files -COPY ./resources/docker/php/php.ini /opt/bitnami/php/etc/conf.d/php.ini +# Copy the PHP and nginx config files +COPY ./resources/docker/php/php.ini /usr/local/etc/php/php.ini +COPY ./resources/docker/nginx/nginx.conf /etc/nginx/conf.d/default.conf -# Install MySQL Dump for automated backups and other dependencies -RUN apk add --no-cache mariadb-client && docker-php-ext-install bcmath pdo_mysql pdo_pgsql +# Install nginx, MySQL Dump for automated backups and other dependencies +RUN apk add --no-cache mariadb-client postgresql postgresql-dev zip libzip-dev ; \ + docker-php-ext-configure zip ; \ + docker-php-ext-install bcmath pdo_mysql pdo_pgsql zip ; \ + mkdir /ssl-certs # Copy files from the composer build COPY --from=builder /app/vendor /app/vendor diff --git a/resources/docker/nginx/site.conf b/resources/docker/nginx/dev.conf similarity index 100% rename from resources/docker/nginx/site.conf rename to resources/docker/nginx/dev.conf diff --git a/nginx.conf b/resources/docker/nginx/nginx.conf similarity index 80% rename from nginx.conf rename to resources/docker/nginx/nginx.conf index bbd84cb4..a9aa7ba2 100644 --- a/nginx.conf +++ b/resources/docker/nginx/nginx.conf @@ -8,12 +8,7 @@ server { port_in_redirect off; # Choose the connection method - listen 0.0.0.0:8080; - #listen 0.0.0.0:8443 ssl; - - # Provide SSL certificates - #ssl_certificate /certs/[FULLCHAIN FILE NAME]; - #ssl_certificate_key /certs/[CERTIFICATE KEY FILE NAME]; + listen 0.0.0.0:80; # Content security headers for Laravel add_header X-Frame-Options "SAMEORIGIN"; @@ -33,14 +28,17 @@ server { try_files $uri $uri/ /index.php?$query_string; } - # CSS and Javascript - location ~* \.(?:css|js|map|scss)$ { - expires 7d; + # Assets and media files + location ~* \.(?:css|js|map|scss|jpg|jpeg|png|gif|mp4|woff|woff2|ico|svg|webmanifest)$ { + expires max; access_log off; add_header Cache-Control "public"; try_files $uri =404; } + location = /favicon.ico { access_log off; log_not_found off; } + location = /robots.txt { access_log off; log_not_found off; } + # Error pages error_page 404 /index.php; error_page 403 /index.php; diff --git a/resources/docker/supervisor.ini b/resources/docker/supervisor.ini new file mode 100644 index 00000000..7321e765 --- /dev/null +++ b/resources/docker/supervisor.ini @@ -0,0 +1,27 @@ +[supervisord] +nodaemon=true +user=root +directory=/tmp +pidfile=/tmp/supervisord.pid +logfile=/tmp/supervisord.log +logfile_maxbytes=50MB +logfile_backups=0 +loglevel=info + +[program:php-fpm] +command=/usr/local/sbin/php-fpm -F +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +stderr_logfile=/dev/stderr +stderr_logfile_maxbytes=0 +priority=10 +autorestart=unexpected + +[program:nginx] +command=/usr/sbin/nginx -g 'daemon off;' +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +stderr_logfile=/dev/stderr +stderr_logfile_maxbytes=0 +priority=20 +autorestart=unexpected