From f33439d829eff92101b1f199d2e00b5bb335a31d Mon Sep 17 00:00:00 2001 From: ErickSkrauch Date: Sat, 6 Apr 2019 15:52:23 +0200 Subject: [PATCH] Completely untie the backend from the frontend. Build nginx and mariadb together with the app image. Upgrade docker-compose configuration to 3 version. Add cleanup step to the gitlab-ci. --- .dockerignore | 3 - .gitattributes | 3 + .gitlab-ci.yml | 63 ++++++++++++++---- Dockerfile | 56 ++++++++++++++-- api/{web => }/index.php | 18 ++--- api/web/robots.txt | 2 - {api/web/assets => data}/.gitignore | 0 data/mysql/.gitignore | 2 - data/redis/.gitignore | 2 - docker-compose.dev.yml | 51 +++++++++----- docker-compose.prod.yml | 42 ++++++++---- docker/mariadb/Dockerfile | 6 -- docker/mariadb/{custom.cnf => config.cnf} | 1 + docker/nginx/account.ely.by.conf.template | 66 +++++++++++++++++++ docker/nginx/docker-entrypoint.sh | 7 ++ docker/nginx/generate-upstream.sh | 15 +++++ docker/nginx/nginx.conf | 33 ++++++++++ docker/php/docker-entrypoint.sh | 4 +- docker/phpmyadmin/Dockerfile | 9 +-- .../{config.local.php => config.inc.php} | 0 docker/supervisor/.gitkeep | 0 21 files changed, 302 insertions(+), 81 deletions(-) create mode 100644 .gitattributes rename api/{web => }/index.php (61%) delete mode 100644 api/web/robots.txt rename {api/web/assets => data}/.gitignore (100%) delete mode 100644 data/mysql/.gitignore delete mode 100644 data/redis/.gitignore delete mode 100644 docker/mariadb/Dockerfile rename docker/mariadb/{custom.cnf => config.cnf} (87%) create mode 100644 docker/nginx/account.ely.by.conf.template create mode 100755 docker/nginx/docker-entrypoint.sh create mode 100755 docker/nginx/generate-upstream.sh create mode 100644 docker/nginx/nginx.conf rename docker/phpmyadmin/{config.local.php => config.inc.php} (100%) delete mode 100644 docker/supervisor/.gitkeep diff --git a/.dockerignore b/.dockerignore index 1aff8d6..79bc7b2 100644 --- a/.dockerignore +++ b/.dockerignore @@ -6,6 +6,3 @@ vendor # Все временные файлы */runtime - -# Их по идее их не должно образовываться, но мало ли -*/web/assets diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..1a22cab --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +# Fix EOL for all files, that should be executed inside Docker container +*.sh text eol=lf +yii text eol=lf diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c6a7ac0..dc16f4a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -2,9 +2,13 @@ stages: - test - build - release + - cleanup variables: - CONTAINER_IMAGE: "registry.ely.by/elyby/accounts" + VERSION: "${CI_COMMIT_TAG:-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHA:0:7}}" + APP_IMAGE_NAME: "registry.ely.by/elyby/accounts" + WEB_IMAGE_NAME: "registry.ely.by/elyby/accounts-nginx" + DB_IMAGE_NAME: "registry.ely.by/elyby/accounts-mariadb" php-cs-fixer: image: edbizarro/gitlab-ci-pipeline-php:7.3-alpine @@ -55,15 +59,28 @@ build:production: image: docker:18.02 stage: build before_script: - - docker login -u gitlab-ci -p $CI_BUILD_TOKEN registry.ely.by - - export VERSION="${CI_COMMIT_TAG:-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHA:0:7}}" - - echo "$SSH_PRIVATE_KEY" > id_rsa - - sed -i"" -e "s/{{PLACE_VERSION_HERE}}/$VERSION/g" common/config/config.php + - sed -i -e "s/{{PLACE_VERSION_HERE}}/$VERSION/g" common/config/config.php script: - - export IMAGE_NAME="$CONTAINER_IMAGE:latest" - - docker build --pull --build-arg build_env=prod -t $IMAGE_NAME . + - > + docker build + --pull + --target app + --build-arg "build_env=prod" + -t "$APP_IMAGE_NAME:$CI_PIPELINE_ID" . + - > + docker build + --pull + --target web + --build-arg "build_env=prod" + -t "$WEB_IMAGE_NAME:$CI_PIPELINE_ID" . + - > + docker build + --pull + --target db + --build-arg "build_env=prod" + -t "$DB_IMAGE_NAME:$CI_PIPELINE_ID" . only: - - develop + - master - tags release:latest: @@ -74,9 +91,16 @@ release:latest: before_script: - docker login -u gitlab-ci -p $CI_BUILD_TOKEN registry.ely.by script: - - docker push $CONTAINER_IMAGE:latest + - docker tag "$APP_IMAGE_NAME:$CI_PIPELINE_ID" "$APP_IMAGE_NAME:latest" + - docker push "$APP_IMAGE_NAME:latest" + + - docker tag "$WEB_IMAGE_NAME:$CI_PIPELINE_ID" "$WEB_IMAGE_NAME:latest" + - docker push "$WEB_IMAGE_NAME:latest" + + - docker tag "$DB_IMAGE_NAME:$CI_PIPELINE_ID" "$DB_IMAGE_NAME:latest" + - docker push "$DB_IMAGE_NAME:latest" only: - - develop + - master - tags release:tag: @@ -87,8 +111,21 @@ release:tag: before_script: - docker login -u gitlab-ci -p $CI_BUILD_TOKEN registry.ely.by script: - - export IMAGE_NAME="$CONTAINER_IMAGE:$CI_BUILD_TAG" - - docker tag $CONTAINER_IMAGE:latest $IMAGE_NAME - - docker push $IMAGE_NAME + - docker tag "$APP_IMAGE_NAME:$CI_PIPELINE_ID" "$APP_IMAGE_NAME:$VERSION" + - docker push "$APP_IMAGE_NAME:$VERSION" + + - docker tag "$WEB_IMAGE_NAME:$CI_PIPELINE_ID" "$WEB_IMAGE_NAME:$VERSION" + - docker push "$WEB_IMAGE_NAME:$VERSION" + + - docker tag "$DB_IMAGE_NAME:$CI_PIPELINE_ID" "$DB_IMAGE_NAME:$VERSION" + - docker push "$DB_IMAGE_NAME:$VERSION" only: - tags + +cleanup: + stage: cleanup + script: + - docker rmi "$APP_IMAGE_NAME:$CI_PIPELINE_ID" "$APP_IMAGE_NAME:$VERSION" "$APP_IMAGE_NAME:latest" || true + - docker rmi "$WEB_IMAGE_NAME:$CI_PIPELINE_ID" "$WEB_IMAGE_NAME:$VERSION" "$WEB_IMAGE_NAME:latest" || true + - docker rmi "$DB_IMAGE_NAME:$CI_PIPELINE_ID" "$DB_IMAGE_NAME:$VERSION" "$DB_IMAGE_NAME:latest" || true + when: always diff --git a/Dockerfile b/Dockerfile index fc12794..9946b37 100644 --- a/Dockerfile +++ b/Dockerfile @@ -63,9 +63,57 @@ COPY ./common /var/www/html/common/ COPY ./console /var/www/html/console/ COPY ./yii /var/www/html/yii -# Expose everything under /var/www/html to share it with nginx -VOLUME ["/var/www/html"] - -WORKDIR /var/www/html ENTRYPOINT ["docker-entrypoint.sh"] CMD ["php-fpm"] + +# ================================================================================ + +FROM nginx:1.15.10-alpine AS web + +ENV PHP_SERVERS php:9000 + +RUN rm /etc/nginx/conf.d/default.conf \ + && mkdir -p /data/nginx/cache \ + && mkdir -p /var/www/html + +WORKDIR /var/www/html + +COPY ./docker/nginx/docker-entrypoint.sh / +COPY ./docker/nginx/generate-upstream.sh /usr/bin/generate-upstream +COPY ./docker/nginx/nginx.conf /etc/nginx/nginx.conf +COPY ./docker/nginx/account.ely.by.conf.template /etc/nginx/conf.d/ + +COPY --from=app /var/www/html/vendor/ely/email-renderer/dist/assets /var/www/html/vendor/ely/email-renderer/dist/assets + +ENTRYPOINT ["/docker-entrypoint.sh"] +CMD ["nginx", "-g", "daemon off;"] + +# ================================================================================ + +FROM mariadb:10.3.14-bionic AS db + +COPY ./docker/mariadb/config.cnf /etc/mysql/conf.d/ + +RUN set -ex \ + && fetchDeps='ca-certificates wget' \ + && apt-get update \ + && apt-get install -y --no-install-recommends $fetchDeps \ + && rm -rf /var/lib/apt/lists/* \ + && wget -O /mysql-sys.tar.gz 'https://github.com/mysql/mysql-sys/archive/1.5.1.tar.gz' \ + && mkdir /mysql-sys \ + && tar -zxf /mysql-sys.tar.gz -C /mysql-sys \ + && rm /mysql-sys.tar.gz \ + && cd /mysql-sys/*/ \ + && ./generate_sql_file.sh -v 56 -m \ + # Fix mysql-sys for MariaDB according to the https://www.fromdual.com/mysql-sys-schema-in-mariadb-10-2 notes + # and https://mariadb.com/kb/en/library/system-variable-differences-between-mariadb-100-and-mysql-56/ reference + && sed -i -e "s/@@global.server_uuid/@@global.server_id/g" gen/*.sql \ + && sed -i -e "s/@@master_info_repository/NULL/g" gen/*.sql \ + && sed -i -e "s/@@relay_log_info_repository/NULL/g" gen/*.sql \ + && mv gen/*.sql /docker-entrypoint-initdb.d/ \ + && cd / \ + && rm -rf /mysql-sys \ + && apt-get purge -y --auto-remove $fetchDeps + +ENTRYPOINT ["docker-entrypoint.sh"] +CMD ["mysqld"] diff --git a/api/web/index.php b/api/index.php similarity index 61% rename from api/web/index.php rename to api/index.php index e6e45e4..6a6fe1a 100644 --- a/api/web/index.php +++ b/api/index.php @@ -6,25 +6,25 @@ use yii\web\Application; $time = microtime(true); -require __DIR__ . '/../../vendor/autoload.php'; +require __DIR__ . '/../vendor/autoload.php'; -defined('YII_DEBUG') || define('YII_DEBUG', in_array(getenv('YII_DEBUG'), ['true', '1'])); +defined('YII_DEBUG') || define('YII_DEBUG', in_array(getenv('YII_DEBUG'), ['true', '1'], false)); defined('YII_ENV') || define('YII_ENV', getenv('YII_ENV')); // Initialize an application aspect container AspectKernel::getInstance()->init([ 'debug' => YII_DEBUG, - 'appDir' => __DIR__ . '/../../', - 'cacheDir' => __DIR__ . '/../runtime/aspect', + 'appDir' => dirname(__DIR__), + 'cacheDir' => __DIR__ . '/runtime/aspect', 'excludePaths' => [ - __DIR__ . '/../runtime/aspect', - __DIR__ . '/../../vendor', + __DIR__ . '/runtime/aspect', + __DIR__ . '/../vendor', ], ]); -require __DIR__ . '/../../vendor/yiisoft/yii2/Yii.php'; -require __DIR__ . '/../../common/config/bootstrap.php'; -require __DIR__ . '/../config/bootstrap.php'; +require __DIR__ . '/../vendor/yiisoft/yii2/Yii.php'; +require __DIR__ . '/../common/config/bootstrap.php'; +require __DIR__ . '/config/bootstrap.php'; $config = ConfigLoader::load('api'); diff --git a/api/web/robots.txt b/api/web/robots.txt deleted file mode 100644 index 6f27bb6..0000000 --- a/api/web/robots.txt +++ /dev/null @@ -1,2 +0,0 @@ -User-agent: * -Disallow: \ No newline at end of file diff --git a/api/web/assets/.gitignore b/data/.gitignore similarity index 100% rename from api/web/assets/.gitignore rename to data/.gitignore diff --git a/data/mysql/.gitignore b/data/mysql/.gitignore deleted file mode 100644 index d6b7ef3..0000000 --- a/data/mysql/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/data/redis/.gitignore b/data/redis/.gitignore deleted file mode 100644 index d6b7ef3..0000000 --- a/data/redis/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index b58867a..a705544 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -1,5 +1,21 @@ -version: '2' +version: '3.4' services: + web: + image: registry.ely.by/elyby/accounts-nginx:latest + build: + context: . + target: web + args: + build_env: dev + depends_on: + - app + env_file: .env + volumes: + - ./:/var/www/html + networks: + - default + - nginx-proxy + app: image: registry.ely.by/elyby/accounts:dev build: @@ -10,8 +26,12 @@ services: - db - redis volumes: - - ./:/var/www/html/ + - ./:/var/www/html env_file: .env + networks: + default: + aliases: + - php worker: image: registry.ely.by/elyby/accounts:dev @@ -24,7 +44,7 @@ services: - db - redis volumes: - - ./:/var/www/html/ + - ./:/var/www/html env_file: .env cron: @@ -39,22 +59,15 @@ services: - db - redis volumes: - - ./:/var/www/html/ + - ./:/var/www/html env_file: .env - web: - image: registry.ely.by/elyby/accounts-nginx:latest - volumes_from: - - app - links: - - app:php - env_file: .env - networks: - - default - - nginx-proxy - db: - build: ./docker/mariadb + build: + context: . + target: db + args: + build_env: dev env_file: .env volumes: - ./data/mysql:/var/lib/mysql @@ -99,7 +112,11 @@ services: # 3) Uncomment the next 2 services (testdb and testredis): # # testdb: - # build: ./docker/mariadb + # build: + # context: . + # target: db + # args: + # build_env: dev # volumes: # - ./data/mysql-test:/var/lib/mysql # environment: diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 6b0f928..019f5be 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -1,5 +1,24 @@ -version: '2' +version: '3.4' + +x-logging: + &default-logging + options: + max-size: 50m + services: + web: + image: registry.ely.by/elyby/accounts-nginx:latest + restart: always + depends_on: + - app + env_file: .env + volumes: + - ./frontend:/var/www/html/frontend + networks: + - default + - nginx-proxy + logging: *default-logging + app: image: registry.ely.by/elyby/accounts:latest restart: always @@ -7,6 +26,11 @@ services: - db - redis env_file: .env + networks: + default: + aliases: + - php + logging: *default-logging worker: image: registry.ely.by/elyby/accounts:latest @@ -16,6 +40,7 @@ services: - db - redis env_file: .env + logging: *default-logging cron: image: registry.ely.by/elyby/accounts:latest @@ -26,21 +51,10 @@ services: - db - redis env_file: .env - - web: - image: registry.ely.by/elyby/accounts-nginx:1.0.3 - restart: always - volumes_from: - - app - links: - - app:php - env_file: .env - networks: - - default - - nginx-proxy + logging: *default-logging db: - build: ./docker/mariadb + image: registry.ely.by/elyby/accounts-mariadb:latest restart: always env_file: .env volumes: diff --git a/docker/mariadb/Dockerfile b/docker/mariadb/Dockerfile deleted file mode 100644 index 2dabddb..0000000 --- a/docker/mariadb/Dockerfile +++ /dev/null @@ -1,6 +0,0 @@ -FROM mariadb:10.2.11 - -COPY custom.cnf /etc/mysql/conf.d/ - -ENTRYPOINT ["docker-entrypoint.sh"] -CMD ["mysqld"] diff --git a/docker/mariadb/custom.cnf b/docker/mariadb/config.cnf similarity index 87% rename from docker/mariadb/custom.cnf rename to docker/mariadb/config.cnf index 66a1832..72aa275 100644 --- a/docker/mariadb/custom.cnf +++ b/docker/mariadb/config.cnf @@ -4,6 +4,7 @@ default-character-set = utf8mb4 [mysqld] character-set-server = utf8mb4 collation-server = utf8mb4_unicode_ci +performance_schema = ON [client] default-character-set = utf8mb4 diff --git a/docker/nginx/account.ely.by.conf.template b/docker/nginx/account.ely.by.conf.template new file mode 100644 index 0000000..91a72e4 --- /dev/null +++ b/docker/nginx/account.ely.by.conf.template @@ -0,0 +1,66 @@ +server { + listen 80; + + set $root_path '/var/www/html'; + set $frontend_path '${root_path}/frontend'; + + root $root_path; + charset utf-8; + + add_header X-Frame-Options "sameorigin" always; + add_header X-XSS-Protection "1; mode=block" always; + add_header X-Content-Type-Options "nosniff" always; + + # You can uncomment the next lines to enable debug mode + # rewrite_log on; + # error_log /var/log/nginx/error.log debug; + + set $request_url $request_uri; + set $host_with_uri '${host}${request_uri}'; + + if ($host_with_uri ~ '^${AUTHSERVER_HOST}/auth') { + set $request_url '/api/authserver${request_uri}'; + rewrite ^/auth /api/authserver$uri last; + } + + if ($host_with_uri ~ '^${AUTHSERVER_HOST}/session') { + set $request_url '/api/minecraft${request_uri}'; + rewrite ^/session /api/minecraft$uri last; + } + + if ($host_with_uri ~ '^${AUTHSERVER_HOST}/api/(user|profiles)') { + set $request_url '/api/mojang${request_uri}'; + rewrite ^/api/(user|profiles) /api/mojang$uri last; + } + + location / { + root $frontend_path; + access_log off; + etag on; + expires $cache_duration; + try_files $uri /index.html =404; + } + + location /api { + try_files $uri /api/index.php$is_args$args; + } + + location /images/emails/assets { + alias '${root_path}/vendor/ely/email-renderer/dist/assets'; + access_log off; + } + + location ~* \.php$ { + fastcgi_pass php; # Use generated upstream. See generate-upstream.sh + fastcgi_index /index.php; + fastcgi_cache cache; + + include fastcgi_params; + + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_param REQUEST_URI $request_url; + fastcgi_param REMOTE_ADDR $http_x_real_ip; + # Override HTTPS param to handle ssl from nginx-proxy container + fastcgi_param HTTPS $http_x_forwarded_ssl if_not_empty; + } +} diff --git a/docker/nginx/docker-entrypoint.sh b/docker/nginx/docker-entrypoint.sh new file mode 100755 index 0000000..1a2e74a --- /dev/null +++ b/docker/nginx/docker-entrypoint.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env sh + +generate-upstream + +envsubst '$AUTHSERVER_HOST' < /etc/nginx/conf.d/account.ely.by.conf.template > /etc/nginx/conf.d/default.conf + +exec "$@" diff --git a/docker/nginx/generate-upstream.sh b/docker/nginx/generate-upstream.sh new file mode 100755 index 0000000..40376c3 --- /dev/null +++ b/docker/nginx/generate-upstream.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env sh + +result="upstream php {" + +for x in $(echo $PHP_SERVERS | tr "," "\n"); do + parts=$(echo $x | tr "x" "\n") + host=$(echo $parts | awk '{print $1}') + weight=$(echo $parts | awk '{print $2}') + + result="$result\n server $host weight=${weight:-1};" +done + +result="$result\n}" + +echo -e $result > /etc/nginx/conf.d/upstream.conf diff --git a/docker/nginx/nginx.conf b/docker/nginx/nginx.conf new file mode 100644 index 0000000..eac3609 --- /dev/null +++ b/docker/nginx/nginx.conf @@ -0,0 +1,33 @@ +user nginx; +worker_processes auto; + +error_log /var/log/nginx/error.log warn; +pid /var/run/nginx.pid; + +events { + worker_connections 1024; +} + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + access_log /var/log/nginx/access.log main; + + sendfile on; + keepalive_timeout 10; + + fastcgi_cache_path /data/nginx/cache levels=1:2 keys_zone=cache:128m inactive=600m use_temp_path=off; + fastcgi_cache_key "$scheme$request_method$host$request_uri"; + + map $uri $cache_duration { + "~*^.+\.(jpe?g|gif|png|svg|js|json|css|zip|rar|eot|ttf|woff|woff2|ico|xml)$" "max"; + default "off"; + } + + include /etc/nginx/conf.d/*.conf; +} diff --git a/docker/php/docker-entrypoint.sh b/docker/php/docker-entrypoint.sh index c34f9fa..7898d21 100755 --- a/docker/php/docker-entrypoint.sh +++ b/docker/php/docker-entrypoint.sh @@ -18,8 +18,8 @@ fi cd /var/www/html # Create all necessary folders -mkdir -p api/runtime api/web/assets console/runtime -chown -R www-data:www-data api/runtime api/web/assets console/runtime +mkdir -p api/runtime console/runtime +chown -R www-data:www-data api/runtime console/runtime if [ "$YII_ENV" = "test" ] then diff --git a/docker/phpmyadmin/Dockerfile b/docker/phpmyadmin/Dockerfile index 6b03cfe..3848199 100644 --- a/docker/phpmyadmin/Dockerfile +++ b/docker/phpmyadmin/Dockerfile @@ -1,8 +1,3 @@ -FROM phpmyadmin/phpmyadmin:4.7.9-1 +FROM phpmyadmin/phpmyadmin:4.8.5 -RUN printf "\n\nrequire('./config.local.php');\n" >> /www/config.inc.php - -COPY config.local.php /www/ - -ENTRYPOINT [ "/run.sh" ] -CMD ["phpmyadmin"] +COPY config.inc.php /usr/src/phpmyadmin/ diff --git a/docker/phpmyadmin/config.local.php b/docker/phpmyadmin/config.inc.php similarity index 100% rename from docker/phpmyadmin/config.local.php rename to docker/phpmyadmin/config.inc.php diff --git a/docker/supervisor/.gitkeep b/docker/supervisor/.gitkeep deleted file mode 100644 index e69de29..0000000