Docker: Use single container for server

This commit is contained in:
Igor Scheller 2022-04-20 00:07:09 +02:00
parent 6ea938460a
commit 59e54fc1f5
13 changed files with 107 additions and 130 deletions

View File

@ -1,7 +1,7 @@
# Docker config # Docker config
docker/ docker/
!docker/nginx/entrypoint.sh !docker/entrypoint.sh
!docker/nginx/nginx.conf !docker/nginx.conf
# Configuration # Configuration
config/config.php config/config.php

View File

@ -2,9 +2,7 @@ image: php
variables: variables:
TEST_IMAGE: ${CI_REGISTRY_IMAGE}/engelsystem:${CI_COMMIT_REF_SLUG} TEST_IMAGE: ${CI_REGISTRY_IMAGE}/engelsystem:${CI_COMMIT_REF_SLUG}
TEST_IMAGE_NGINX: ${CI_REGISTRY_IMAGE}/nginx:${CI_COMMIT_REF_SLUG}
RELEASE_IMAGE: ${CI_REGISTRY_IMAGE}/engelsystem:latest RELEASE_IMAGE: ${CI_REGISTRY_IMAGE}/engelsystem:latest
RELEASE_IMAGE_NGINX: ${CI_REGISTRY_IMAGE}/nginx:latest
MYSQL_DATABASE: engelsystem MYSQL_DATABASE: engelsystem
MYSQL_USER: engel MYSQL_USER: engel
MYSQL_PASSWORD: engelsystem MYSQL_PASSWORD: engelsystem
@ -78,23 +76,12 @@ generate-version:
.container_template: &container_definition .container_template: &container_definition
image: image:
name: gcr.io/kaniko-project/executor:debug name: gcr.io/kaniko-project/executor:debug
entrypoint: [ "" ] entrypoint: [ '' ]
before_script: before_script:
- mkdir -p /kaniko/.docker - mkdir -p /kaniko/.docker
- echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" - echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}"
> /kaniko/.docker/config.json > /kaniko/.docker/config.json
build-image-nginx:
<<: *container_definition
stage: build
needs:
- check-editorconfig
- validate-yarn
script:
- /kaniko/executor --force --context ${CI_PROJECT_DIR}
--dockerfile ${CI_PROJECT_DIR}/docker/nginx/Dockerfile
--destination "${TEST_IMAGE_NGINX}"
build-image: build-image:
<<: *container_definition <<: *container_definition
stage: build stage: build
@ -103,10 +90,11 @@ build-image:
- check-style - check-style
- generate-version - generate-version
- validate-composer - validate-composer
- validate-yarn
dependencies: dependencies:
- generate-version - generate-version
script: script:
- /kaniko/executor --force --context ${CI_PROJECT_DIR} - /kaniko/executor --context ${CI_PROJECT_DIR}
--dockerfile ${CI_PROJECT_DIR}/docker/Dockerfile --dockerfile ${CI_PROJECT_DIR}/docker/Dockerfile
--destination "${TEST_IMAGE}" --destination "${TEST_IMAGE}"
@ -132,7 +120,9 @@ audit-yarn:
- yarn audit - yarn audit
test: test:
image: ${TEST_IMAGE} image:
name: ${TEST_IMAGE}
entrypoint: [ '' ]
stage: test stage: test
needs: [ build-image ] needs: [ build-image ]
services: services:
@ -164,7 +154,9 @@ test:
- '"${DOCROOT}/bin/migrate" down' - '"${DOCROOT}/bin/migrate" down'
dump-database: dump-database:
image: ${TEST_IMAGE} image:
name: ${TEST_IMAGE}
entrypoint: [ '' ]
stage: test stage: test
needs: [ build-image ] needs: [ build-image ]
services: services:
@ -185,10 +177,10 @@ dump-database:
generate-assets: generate-assets:
image: image:
name: $TEST_IMAGE_NGINX name: $TEST_IMAGE
entrypoint: [ "" ] entrypoint: [ '' ]
stage: test stage: test
needs: [ build-image-nginx ] needs: [ build-image ]
artifacts: artifacts:
name: "${CI_JOB_NAME}_${CI_JOB_ID}_assets" name: "${CI_JOB_NAME}_${CI_JOB_ID}_assets"
expire_in: 1 day expire_in: 1 day
@ -202,32 +194,21 @@ generate-assets:
# #
release-image: release-image:
<<: *container_definition
stage: release
needs: [ test ]
dependencies: [ ]
script:
- echo -e "FROM ${TEST_IMAGE}" | /kaniko/executor --force --dockerfile /dev/stdin --destination "${RELEASE_IMAGE}"
only:
- main
release-image-nginx:
<<: *container_definition <<: *container_definition
stage: release stage: release
needs: needs:
- test - test
- build-image-nginx
dependencies: [ ] dependencies: [ ]
script: script:
- >- - echo -e "FROM ${TEST_IMAGE}" | /kaniko/executor --dockerfile /dev/stdin --destination "${RELEASE_IMAGE}"
echo -e "FROM ${TEST_IMAGE_NGINX}" |
/kaniko/executor --force --dockerfile /dev/stdin --destination "${RELEASE_IMAGE_NGINX}"
only: only:
- main - main
.deploy_template: &deploy_definition .deploy_template: &deploy_definition
stage: release stage: release
image: ${TEST_IMAGE} image:
name: ${TEST_IMAGE}
entrypoint: [ '' ]
before_script: before_script:
- apk add -q bash rsync openssh-client - apk add -q bash rsync openssh-client
@ -236,7 +217,6 @@ build-release-file:
stage: release stage: release
needs: needs:
- build-image - build-image
- build-image-nginx
- audit-yarn - audit-yarn
- audit-composer - audit-composer
- test - test
@ -314,7 +294,6 @@ deploy:
needs: needs:
- test - test
- build-image - build-image
- build-image-nginx
before_script: before_script:
- &kubectl_deployment_script if [[ -z "${KUBE_INGRESS_BASE_DOMAIN}" ]]; then echo "Skipping deployment"; exit; fi - &kubectl_deployment_script if [[ -z "${KUBE_INGRESS_BASE_DOMAIN}" ]]; then echo "Skipping deployment"; exit; fi
@ -331,7 +310,6 @@ deploy:
# CI_ENVIRONMENT_URL is the URL configured in the GitLab environment # CI_ENVIRONMENT_URL is the URL configured in the GitLab environment
- export CI_ENVIRONMENT_URL="${CI_ENVIRONMENT_URL:-https://${CI_PROJECT_PATH_SLUG}.${KUBE_INGRESS_BASE_DOMAIN}/}" - export CI_ENVIRONMENT_URL="${CI_ENVIRONMENT_URL:-https://${CI_PROJECT_PATH_SLUG}.${KUBE_INGRESS_BASE_DOMAIN}/}"
- export CI_IMAGE=$RELEASE_IMAGE - export CI_IMAGE=$RELEASE_IMAGE
- export CI_IMAGE_NGINX=$RELEASE_IMAGE_NGINX
- export CI_INGRESS_DOMAIN=$(echo "$CI_ENVIRONMENT_URL" | grep -oP '(?:https?://)?\K([^/]+)' | head -n1) - export CI_INGRESS_DOMAIN=$(echo "$CI_ENVIRONMENT_URL" | grep -oP '(?:https?://)?\K([^/]+)' | head -n1)
- export CI_INGRESS_PATH=$(echo "$CI_ENVIRONMENT_URL" | grep -oP '(?:https?://)?(?:[^/])+\K(.*)') - export CI_INGRESS_PATH=$(echo "$CI_ENVIRONMENT_URL" | grep -oP '(?:https?://)?(?:[^/])+\K(.*)')
- export CI_KUBE_NAMESPACE=$KUBE_NAMESPACE - export CI_KUBE_NAMESPACE=$KUBE_NAMESPACE
@ -380,7 +358,6 @@ deploy-k8s-review:
before_script: before_script:
- *kubectl_deployment_script - *kubectl_deployment_script
- RELEASE_IMAGE=$TEST_IMAGE - RELEASE_IMAGE=$TEST_IMAGE
- RELEASE_IMAGE_NGINX=$TEST_IMAGE_NGINX
stop-k8s-review: stop-k8s-review:
<<: *deploy_k8s_stop <<: *deploy_k8s_stop
@ -426,7 +403,6 @@ deploy-k8s-production:
stage: deploy-production stage: deploy-production
needs: needs:
- release-image - release-image
- release-image-nginx
- audit-yarn - audit-yarn
- audit-composer - audit-composer
environment: environment:

View File

@ -74,7 +74,7 @@ To view the output of `dump` call the following commands:
```bash ```bash
vendor/bin/var-dump-server vendor/bin/var-dump-server
# or for running in docker # or for running in docker
docker-compose exec es_php_fpm vendor/bin/var-dump-server docker-compose exec es_server vendor/bin/var-dump-server
``` ```
For more information check out the Var Dump Server documentation: [Symfony VarDumper](https://symfony.com/components/VarDumper) For more information check out the Var Dump Server documentation: [Symfony VarDumper](https://symfony.com/components/VarDumper)

View File

@ -53,16 +53,15 @@ The Engelsystem can now be used.
### Docker ### Docker
#### Build #### Build
To build the `es_nginx` and the `es_php_fpm` containers: To build the `es_server` container:
```bash ```bash
cd docker cd docker
docker-compose build docker-compose build
``` ```
or to build the containers separately or to build the container by its own:
```bash ```bash
docker build -f docker/nginx/Dockerfile . -t es_nginx docker build -f docker/Dockerfile . -t es_server
docker build -f docker/Dockerfile . -t es_php_fpm
``` ```
#### Run #### Run
@ -76,7 +75,7 @@ docker-compose up -d
Import database changes to migrate it to the newest version Import database changes to migrate it to the newest version
```bash ```bash
cd docker cd docker
docker-compose exec es_php_fpm bin/migrate docker-compose exec es_server bin/migrate
``` ```
### Scripts ### Scripts

View File

@ -131,7 +131,7 @@ spec:
value: '<CI_SETUP_ADMIN_PASSWORD>' value: '<CI_SETUP_ADMIN_PASSWORD>'
containers: containers:
- image: <CI_IMAGE> - image: <CI_IMAGE>
name: engelsystem-fpm name: engelsystem-server
imagePullPolicy: Always imagePullPolicy: Always
env: env:
- name: MYSQL_HOST - name: MYSQL_HOST
@ -146,12 +146,6 @@ spec:
value: <CI_ENVIRONMENT_URL> value: <CI_ENVIRONMENT_URL>
- name: APP_NAME - name: APP_NAME
value: '<CI_APP_NAME>' value: '<CI_APP_NAME>'
- image: <CI_IMAGE_NGINX>
name: engelsystem-nginx
imagePullPolicy: Always
env:
- name: PHP_FPM_HOST
value: localhost
livenessProbe: livenessProbe:
httpGet: httpGet:
path: /health path: /health

View File

@ -1,15 +1,24 @@
# composer install # Composer install
FROM composer:latest AS composer FROM composer:latest AS composer
COPY ./ /app/ COPY ./ /app/
RUN composer --no-ansi install --no-dev --ignore-platform-reqs RUN composer --no-ansi install --no-dev --ignore-platform-reqs
RUN composer --no-ansi dump-autoload --optimize RUN composer --no-ansi dump-autoload --optimize
# Intermediate containers for less layers # Generate .mo files
FROM alpine as translation FROM alpine as translation
RUN apk add gettext RUN apk add gettext
COPY resources/lang/ /data COPY resources/lang/ /data
RUN find /data -type f -name '*.po' -exec sh -c 'file="{}"; msgfmt "${file%.*}.po" -o "${file%.*}.mo"' \; RUN find /data -type f -name '*.po' -exec sh -c 'file="{}"; msgfmt "${file%.*}.po" -o "${file%.*}.mo"' \;
# Build the themes
FROM node:14-alpine as themes
WORKDIR /app
COPY .babelrc .browserslistrc package.json webpack.config.js yarn.lock /app/
RUN yarn --frozen-lockfile
COPY resources/assets/ /app/resources/assets
RUN yarn build
# Generate application structure
FROM alpine as data FROM alpine as data
COPY .babelrc .browserslistrc composer.json LICENSE package.json README.md webpack.config.js yarn.lock /app/ COPY .babelrc .browserslistrc composer.json LICENSE package.json README.md webpack.config.js yarn.lock /app/
COPY bin/ /app/bin COPY bin/ /app/bin
@ -24,14 +33,20 @@ COPY storage/ /app/storage
COPY --from=translation /data/ /app/resources/lang COPY --from=translation /data/ /app/resources/lang
COPY --from=composer /app/vendor/ /app/vendor COPY --from=composer /app/vendor/ /app/vendor
COPY --from=composer /app/composer.lock /app/ COPY --from=composer /app/composer.lock /app/
COPY --from=themes /app/public/assets /app/public/assets/
RUN find /app/storage/ -type f -not -name VERSION -exec rm {} \; RUN find /app/storage/ -type f -not -name VERSION -exec rm {} \;
# Build the PHP container # Build the PHP/Nginx container
FROM php:8-fpm-alpine FROM php:8-fpm-alpine
WORKDIR /var/www WORKDIR /var/www
RUN apk add --no-cache icu-dev && \ RUN apk add --no-cache icu-dev nginx && \
docker-php-ext-install intl pdo_mysql docker-php-ext-install intl pdo_mysql && \
sed -i 's/9000/127.0.0.1:9000/' /usr/local/etc/php-fpm.d/zz-docker.conf
COPY docker/entrypoint.sh /
COPY docker/nginx.conf /etc/nginx/nginx.conf
ENTRYPOINT /entrypoint.sh
EXPOSE 80
COPY --from=data /app/ /var/www COPY --from=data /app/ /var/www
RUN chown -R www-data:www-data /var/www/storage/ && \ RUN chown -R www-data:www-data /var/www/storage/ && \
rm -r /var/www/html rm -r /var/www/html

View File

@ -1,5 +1,5 @@
# Engelsystem PHP FPM development image including Xdebug # Engelsystem PHP FPM/Nginx development image including Xdebug
FROM php:8-fpm-alpine AS es_php_fpm FROM php:8-fpm-alpine AS es_base
WORKDIR /var/www WORKDIR /var/www
RUN apk add --no-cache icu-dev $PHPIZE_DEPS && \ RUN apk add --no-cache icu-dev $PHPIZE_DEPS && \
pecl install pcov xdebug && \ pecl install pcov xdebug && \
@ -7,6 +7,14 @@ RUN apk add --no-cache icu-dev $PHPIZE_DEPS && \
docker-php-ext-enable pcov xdebug docker-php-ext-enable pcov xdebug
RUN echo -e "xdebug.mode=debug\nxdebug.discover_client_host=1\n" >> /usr/local/etc/php/conf.d/xdebug.ini RUN echo -e "xdebug.mode=debug\nxdebug.discover_client_host=1\n" >> /usr/local/etc/php/conf.d/xdebug.ini
FROM es_base AS es_webserver
RUN apk add --no-cache nginx && \
sed -i 's/9000/127.0.0.1:9000/' /usr/local/etc/php-fpm.d/zz-docker.conf
COPY docker/entrypoint.sh /
COPY docker/nginx.conf /etc/nginx/nginx.conf
ENTRYPOINT /entrypoint.sh
EXPOSE 80
ENV TRUSTED_PROXIES 10.0.0.0/8,::ffff:10.0.0.0/8,\ ENV TRUSTED_PROXIES 10.0.0.0/8,::ffff:10.0.0.0/8,\
127.0.0.0/8,::ffff:127.0.0.0/8,\ 127.0.0.0/8,::ffff:127.0.0.0/8,\
172.16.0.0/12,::ffff:172.16.0.0/12,\ 172.16.0.0/12,::ffff:172.16.0.0/12,\
@ -15,6 +23,7 @@ ENV TRUSTED_PROXIES 10.0.0.0/8,::ffff:10.0.0.0/8,\
# Engelsystem development workspace # Engelsystem development workspace
# Contains all tools required to build / manage the system # Contains all tools required to build / manage the system
FROM es_php_fpm AS es_workspace FROM es_base AS es_workspace
RUN apk add --no-cache gettext nodejs npm yarn RUN apk add --no-cache gettext nodejs npm yarn
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
ENTRYPOINT php -r 'sleep(PHP_INT_MAX);'

View File

@ -1,30 +1,15 @@
version: "3.6" version: "3.6"
services: services:
es_nginx: es_server:
image: es_dev_nginx image: es_dev_webserver
build:
context: ./../..
dockerfile: docker/nginx/Dockerfile
target: es_nginx
volumes:
- ./../..:/var/www
ports:
- 5000:80
networks:
- fpm
- internet
depends_on:
- es_php_fpm
es_php_fpm:
image: es_dev_php_fpm
build: build:
context: ./../.. context: ./../..
dockerfile: docker/dev/Dockerfile dockerfile: docker/dev/Dockerfile
target: es_php_fpm target: es_webserver
user: "${UID}:${GID}"
volumes: volumes:
- ./../..:/var/www - ./../..:/var/www
environment: environment:
RUN_USER: "${UID}:${GID}"
MYSQL_HOST: es_database MYSQL_HOST: es_database
MYSQL_USER: engelsystem MYSQL_USER: engelsystem
MYSQL_PASSWORD: engelsystem MYSQL_PASSWORD: engelsystem
@ -34,9 +19,10 @@ services:
MAIL_DRIVER: log MAIL_DRIVER: log
APP_NAME: Engelsystem DEV APP_NAME: Engelsystem DEV
env_file: deployment.env env_file: deployment.env
ports:
- "5000:80"
networks: networks:
- database - database
- fpm
- internet - internet
depends_on: depends_on:
- es_database - es_database
@ -60,7 +46,6 @@ services:
APP_NAME: Engelsystem DEV APP_NAME: Engelsystem DEV
networks: networks:
- database - database
- fpm
- internet - internet
depends_on: depends_on:
- es_database - es_database
@ -82,6 +67,4 @@ volumes:
networks: networks:
database: database:
internal: true internal: true
fpm:
internal: true
internet: internet:

View File

@ -1,20 +1,8 @@
--- ---
version: "3.6" version: "3.6"
services: services:
es_nginx: es_server:
image: es_nginx image: es_server
build:
context: ..
dockerfile: docker/nginx/Dockerfile
ports:
- 5000:80
networks:
- fpm
- internet
depends_on:
- es_php_fpm
es_php_fpm:
image: es_php_fpm
build: build:
context: .. context: ..
dockerfile: docker/Dockerfile dockerfile: docker/Dockerfile
@ -23,10 +11,11 @@ services:
MYSQL_USER: engelsystem MYSQL_USER: engelsystem
MYSQL_PASSWORD: engelsystem MYSQL_PASSWORD: engelsystem
MYSQL_DATABASE: engelsystem MYSQL_DATABASE: engelsystem
ports:
- "5000:80"
env_file: deployment.env env_file: deployment.env
networks: networks:
- database - database
- fpm
- internet - internet
depends_on: depends_on:
- es_database - es_database
@ -48,6 +37,4 @@ volumes:
networks: networks:
database: database:
internal: true internal: true
fpm:
internal: true
internet: internet:

40
docker/entrypoint.sh Executable file
View File

@ -0,0 +1,40 @@
#!/usr/bin/env sh
set -e
nginx -g 'daemon off;'&
# If first arg starts with a `-` or is empty
if [[ "${1#-}" != "${1}" ]] || [[ -z "${1}" ]]; then
set -- php-fpm "$@"
fi
function get_name() {
echo "$1" | cut -d: -f1
}
# Create users for user mapping from RUN_USER=[uid]:[gid]
if [[ -n "${RUN_USER}" ]]; then
echo "Setting user to $RUN_USER"
gid=${RUN_USER#*:}
grp=$(getent group $gid || true)
if [[ -z "$grp" ]]; then # Group not present
addgroup -g $gid php
grp=$(getent group $gid)
fi
group=$(get_name "$grp")
uid=${RUN_USER%:*}
usr=$(getent passwd $uid || true)
if [[ -z "$usr" ]]; then # User not present
adduser -D -h "$PWD" -u $uid -G "$group" php
usr=$(getent passwd $uid)
fi
user=$(get_name "$usr")
echo -e "user = $user\ngroup = $group" >> /usr/local/etc/php-fpm.d/zz-docker.conf
echo "Running as $user:$group"
fi
exec "$@"

View File

@ -36,7 +36,7 @@ http {
} }
location ~ \.php$ { location ~ \.php$ {
fastcgi_pass es_php_fpm:9000; fastcgi_pass localhost:9000;
fastcgi_index index.php; fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params; include fastcgi_params;

View File

@ -1,15 +0,0 @@
FROM nginx:alpine as es_nginx
COPY docker/nginx/entrypoint.sh /
ENTRYPOINT /entrypoint.sh
RUN mkdir -p /var/www/public/ && touch /var/www/public/index.php
COPY docker/nginx/nginx.conf /etc/nginx/nginx.conf
FROM node:14-alpine as themes
WORKDIR /app
COPY .babelrc .browserslistrc package.json webpack.config.js yarn.lock /app/
RUN yarn --frozen-lockfile
COPY resources/assets/ /app/resources/assets
RUN yarn build
FROM es_nginx
COPY --from=themes /app/public/assets /var/www/public/assets/

View File

@ -1,11 +0,0 @@
#!/usr/bin/env sh
set -e
sed -i "s/es_php_fpm:/${PHP_FPM_HOST:-es_php_fpm}:/g" /etc/nginx/nginx.conf
# If first arg starts with a `-` or is empty
if [[ "${1#-}" != "${1}" ]] || [[ -z "${1}" ]]; then
set -- nginx -g 'daemon off;' "$@"
fi
exec "$@"