この記事では、Symfonyアプリケーションの開発プロセス全体を、インフラストラクチャのセットアップから実稼働環境へのデプロイまでゼロから自動化した経験を共有します。 開発環境から実稼働環境まで、docker-composeを使用してアプリケーションを起動し、すべての継続的な統合/展開手順は、DockerコンテナのGitLab CI / CDパイプラインを通じて起動します。
dockerおよびdocker-composeに精通していることが理解されます。 そうでない場合、またはインストール方法がわからない場合は、 ローカル開発者環境を準備する手順を準備しました 。 実際、アプリケーションで作業するために必要なのは、Docker、VirtualBox、およびオプションでYarnのみです。
アプリケーションをローカルで実行する
アプリケーションのスケルトンを準備し、 GitHubに投稿しました 。 以下に書かれているすべては、このテンプレートに基づいて作成されたアプリケーションと、そのようなアプリケーションを実行するために必要なインフラストラクチャに適用されます。
アプリケーションをローカルで実行するには、次のコマンドを実行する必要があります。
git clone git@github.com:covex-nn/docker-workflow-symfony.git cd docker-workflow-symfony docker-compose up -d docker-compose exec php phing
このサイトはhttp://docker.local/で利用できます。アドレスにapp_dev.php/
を追加する必要はありません。 4つのコンテナが起動されます: nginx
、 php
、 mysql
およびphpmyadmin
(後者は開発環境でのみ起動されます)。
docker.local
hosts
登録する必要がありhosts
。 Linuxの場合、サイトのIPアドレスは127.0.0.1
になりますが、Windowsでは、 docker-machine env
結果として見つけることができます(すべて同じ手順を参照してください )。
php
コンテナーのcomposer
は、 vendor
フォルダーがホストではなくコンテナー内に配置されるように構成されており、ローカル開発者環境のパフォーマンスに影響を与えません。
インフラストラクチャの準備と構成
戦闘状態では、システムには3つのサーバーが必要になります: GitLab
-Gitおよびコンテナレジストリリポジトリを管理するためのサーバー、 GitLab
用のGitLab
本番サイト用のサーバー、およびDocker
用のGitLab
本番前およびテスト開発者用サイトのサーバー。
GitLabおよびContainer Registryを使用したサーバーのセットアップ
GitLabおよびContainer Registryのインストール手順は、gitlab.comで入手できます。
デフォルトでは、GitLab Container RegistryにはSSL証明書の構成が必要です。 Container RegistryとGitLab Webインターフェースの両方に同じ証明書を使用します。 LetsEncryptサービスを使用してSSL証明書を作成できます。
/etc/gitlab/gitlab.rb
ファイルでSSL証明書を有効にできます。 また、証明書を自動的に更新する機能を構成する必要があります。
nginx['ssl_certificate'] = "/etc/letsencrypt/live/gitlab.site.ru/fullchain.pem" nginx['ssl_certificate_key'] = "/etc/letsencrypt/live/gitlab.site.ru/privkey.pem" registry_nginx['ssl_certificate'] = "/etc/letsencrypt/live/gitlab.site.ru/fullchain.pem" registry_nginx['ssl_certificate_key'] = "/etc/letsencrypt/live/gitlab.site.ru/privkey.pem" nginx['custom_gitlab_server_config'] = "location ^~ /.well-known { \n allow all;\n alias /var/lib/letsencrypt/.well-known/;\n default_type \"text/plain\";\n try_files $uri =404;\n }\n"
gitlab.rb
ファイルを変更しgitlab.rb
、 gitlab-ctl restart
を使用してgitlab-ctl restart
、 crontab
を構成して証明書を更新する必要があります。
41 0 * * * /root/certbot-auto renew --no-self-upgrade --webroot -w /var/lib/letsencrypt --renew-hook "service nginx reload"
本番用のDockerを使用したサーバーの構成
Dockerのインストール手順はdocs.docker.comで入手できます。
さらに、ローカルネットワークを作成して、コンテナの内部IPアドレスを割り当てる必要があります。
docker network create graynetwork --gateway 192.168.10.1 --subnet 192.168.10.0/24
Dockerに加えて、 サーバー上のLetsEncryptからnginx
とcertbot-auto
をインストールする必要があります 。
Nginxは、リクエストをDockerコンテナ内のWebサーバーにプロキシします。 Nginxのインストール手順は、 nginx.orgにあります。
GitLabを備えたサーバーと同様に、将来のSSL証明書の更新はすぐに構成する必要があります。
41 0 * * * /root/certbot-auto renew --no-self-upgrade --webroot -w /var/lib/letsencrypt --renew-hook "service nginx reload"
開発用のDockerを使用したサーバーのセットアップ
Docker production
のDocker production
すべてのインストールポイントを完了する必要があり、サーバーに加えてGitLab CI Runner
をインストールする必要があります。
GitLab CI Runner
インストールGitLab CI Runner
は、 docs.gitlab.comで入手できます。
GitLab Runnerの実行:
gitlab-ci-multi-runner verify --delete printf "concurrent = 10\ncheck_interval = 0\n\n" > /etc/gitlab-runner/config.toml gitlab-ci-multi-runner register -n \ --url https://gitlab-server.ru/ \ --registration-token <token> \ --tag-list "executor-docker,docker-in-docker" \ --executor docker \ --description "docker-dev" \ --docker-image "docker:latest" \ --docker-volumes "/composer/home/cache" \ --docker-volumes "/root/.composer/cache" \ --docker-volumes "/var/run/docker.sock:/var/run/docker.sock"
<token>
は、 Admin Area --> Runners
セクションのGitLab Webインターフェイスからコピーする必要があります。
何人かの開発者がプロジェクトに取り組みます。何も壊したり互いに干渉したりしないように、アクセスを許可する必要があります。
マスターユーザーの作成
Docker production
のDocker production
サーバーDocker production
、master
ユーザーを作成し、グループにdocker
を追加します。
adduser master usermod -aG docker master
次に、新しいユーザーとしてログインし、パスフレーズなしで
id_rsa
キーを作成する必要があります。
ssh-keygen -t rsa -b 4096 -C "master@docker-server-prod.ru" cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
このキーは、サーバーへのSSHアクセスおよび開発者のgitリポジトリへのアクセスに使用されます。
- GitLabで、ユーザー
master
を作成し、それにSSHキーを追加します。 このユーザーは純粋に技術的なものです。 将来的には、その下に行って操作を実行する必要はありません。
開発者ユーザーの作成
Docker
サーバーでDocker
ために、ユーザーdev1
を作成する必要があります(名前は何でもdev1
ん):
adduser dev1 usermod -aG docker dev1
次に、新しいユーザーとしてログインし、パスフレーズなしでid_rsaキーを作成する必要があります。
ssh-keygen -t rsa -b 4096 -C "dev1@docker-server-dev.ru" cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys chmod 400 ~/.ssh/id_rsa ~/.ssh/id_rsa.pub ~/.ssh/authorized_keys
このキーはサーバーへのSSHアクセスに使用され、開発者には知られていません。
GitLabでユーザー
dev1
作成し、ユーザーが自分のリポジトリとグループを作成できないようにします。 SSHキーを設定する必要はありません-開発者が自分で設定します。
- GitLabで、
dev1-projects
グループを作成し、Master
ロールを持つMaster
をユーザーグループに追加します。 このグループには、この開発者のすべてのリポジトリが含まれます。
プロジェクトには、開発者ごとに1つのメインリポジトリと1つのリポジトリがあります。 メインリポジトリは、本番およびステージングサイトのソース、この特定の開発者のテストサイトの開発者リポジトリになります。 各サイトの展開プロセスは一致します。 違いは、Dockerでのアプリケーション構成とサーバーアクセス設定のみです。 構成と設定は、 GitLab
のSettings -- CI/CD Pipelines
セクションGitLab
Settings -- CI/CD Pipelines
:主にGitLab
サイトとステージングサイトのリポジトリ、およびこの開発者のテストサイトの開発者のリポジトリに保存されます。
メインプロジェクトリポジトリは、任意のグループに配置できます。
Settings --> Pipelines
セクションで、 Settings --> Pipelines
のGit strategy for pipelines
としてgit clone
を選択し、変数を追加します。
可変 | 価値 |
---|---|
COMPOSER_GITHUB_TOKEN | https://github.com/settings/tokensでトークンを作成します |
SSH_PRIVATE_KEY | ユーザーmaster
id_rsaファイルの内容を入力します |
NETWORK_NAME_MASTER | グレーネットワーク |
SERVER_NAME_MASTER | site-staging.ru |
NETWORK_IP_MASTER | グレーネットワークサブネット上の無料のIPを選択します |
NETWORK_NAME_PRODUCTION | グレーネットワーク |
SERVER_NAME_PRODUCTION | site-production.ru |
NETWORK_IP_PRODUCTION | グレーネットワークサブネット上の無料のIPを選択します |
DEPLOY_USER_MASTER | マスター |
DEPLOY_HOST_MASTER | docker-server-prod.ru |
DEPLOY_DIRECTORY_MASTER | /home/master/site-staging.ru |
DEPLOY_USER_PRODUCTION | マスター |
DEPLOY_HOST_PRODUCTION | docker-server-prod.ru |
DEPLOY_DIRECTORY_PRODUCTION | /home/master/site-production.ru |
PROJECT_FORKS | <空白のまま> |
アプリケーションスケルトンをステージングにデプロイするには、 git push origin master
を使用してmaster
ブランチをリポジトリにアップロードする必要があります。
開発者リポジトリは、開発者プロジェクトグループに属している必要があります ユーザーdev1
場合、これはdev1-projects
です。 開発者リポジトリは、メインリポジトリからFork 管理者を作成することで作成されます。 これは重要です。
- フォークの作成に加えて、メインの開発者リポジトリからマージリクエストを作成できます。
- また、システムの安定性を確保し、id_rsaにサーバーにアクセスするための秘密鍵を保持するには、管理者によるフォークの作成が必要です。
Settings --> Pipelines
セクションで、 Settings --> Pipelines
のGit strategy for pipelines
として[ git clone
を選択し、 Public pipelines
を非表示にして変数を追加します。
可変 | 価値 |
---|---|
COMPOSER_GITHUB_TOKEN | https://github.com/settings/tokensでトークンを作成します |
SSH_PRIVATE_KEY | ユーザーdev1
id_rsaファイルの内容を入力します |
NETWORK_NAME_MASTER | グレーネットワーク |
SERVER_NAME_MASTER | site-dev1.ru |
NETWORK_IP_MASTER | グレーネットワークサブネット上の無料のIPを選択します |
DEPLOY_USER_MASTER | 開発者 |
DEPLOY_HOST_MASTER | docker-server-dev.ru |
DEPLOY_DIRECTORY_MASTER | /home/dev1/site-dev1.ru |
PROJECT_FORKS | <空白のまま> |
テストサイトに展開する前に、 master
ブランチと同じコミットを指すstable
ブランチを作成する必要があります。 stable
ブランチはステージングサイトの状態に対応し、検証され受け入れられたコードのみがこのブランチに含まれます。
その過程で、開発者は一方で、コミットを結合し、 git push -f origin master
介して履歴を書き換えることができるはずです。 一方、システムの残りの部分を混乱させないように、 stable
ブランチをシフトしてタグを作成することはできません。
これを行うには、 Settings --> Repository
セクションで、 master
ブランチから保護を削除し、 stable
ブランチとすべてのタグを保護する必要があります。
開発者のテストサイトにアプリケーションをデプロイするには、 master
ブランチに対してPipelineを実行する必要があります。 その後、 Settings --> Members
dev1
で、 Developer
ロールをユーザーdev1
に付与する必要があります。
最後に、メインリポジトリを構成する必要があります。 開発者リポジトリのアドレスを含む行をPROJECT_FORKS
変数に追加して、新しいリポジトリのstable
ブランチを同期する必要があります。 そして、メインリポジトリのユーザーdev1
にReporter
ロールを与えます。
作業を開始する前の最後の手順は、Dockerを使用してサーバーでNginxを構成することです。 このNginxは手動で設定され、SymfonyアプリケーションへのすべてのHTTP / HTTPSリクエストは、以前に作成されたDockerサブネットで選択されたIPアドレスにプロキシされます( NETWORK_NAME_...
およびNETWORK_IP_...
変数を参照)。
構成ファイルの作成
site-dev1.ru
ドメインの構成例。 ここで、 192.168.10.10
は、 dev1
開発者リポジトリ設定のNETWORK_IP_MASTER
変数の内容です。
server { listen 80; # listen 443 ssl; server_name site-dev1.ru; # ssl_certificate /etc/letsencrypt/live/site-dev1.ru/fullchain.pem; # ssl_certificate_key /etc/letsencrypt/live/site-dev1.ru/privkey.pem; # if ($ssl_protocol = "") { # rewrite ^/(.*) https://$server_name/$1 permanent; # } location / { proxy_pass http://192.168.10.10; include proxy_params; } location ~ /.well-known { allow all; alias /var/lib/letsencrypt/.well-known; } }
SSL証明書を作成する
/root/certbot-auto certonly \ --no-self-upgrade \ --webroot \ -d site-dev1.ru \ -w /var/lib/letsencrypt
サイトをHTTPからHTTPSに切り替えるには、HTTPドメイン構成の行のコメントを解除して、Nginxを再起動します。
nginx -t service nginx reload
開発プロセス
この段階で、開発者は自分のリポジトリにアクセスできます。 彼のリポジトリでは、彼はDeveloper
の役割を持ち、ほとんど何でもできます。 開発者のリポジトリでは、 master
ブランチはテストサイトの状態に対応しています。 stable
ブランチはstaging
サイトとしてstable
れています。
新しいタスクはそれぞれ、 stable
ブランチと同じコミットを指すタスクブランチを作成することから始めます。
git fetch --all --prune git checkout origin/stable git checkout -b feature-qwerty git push origin feature-qwerty
その後、ある段階で、テストサイトに変更を投稿する必要がある場合、 master
ブランチのリポジトリに変更をアップロードできます。変更は2〜5分以内に投稿されます。
開発者リポジトリからメインリポジトリへの変更のマージは、GitLab Webインターフェイスで対応するマージリクエストを作成して、タスクブランチ(例ではfeature-qwerty
qwerty)からメインリポジトリのmaster
ブランチにマージする必要があります。
管理者は、マージリクエストを受け入れる前に、開発者のブランチでのコミットがメインリポジトリのmaster
ブランチの現在の位置に厳密に追随することを確認する必要があります。 これはGitLab CEで自動的に行うことはできません;この機能はGitLab EEでのみ利用可能です。
変更を作業サイトにロールアウトするには、GitLab Webインターフェースでrelease-...
タグを作成する必要があります。
開発者は、プロジェクトコードの変更とともに、新しい値をアプリケーションパラメータに追加できます。 これらのパラメーターの値は、環境によって異なる場合があります。
ローカル開発者環境
デフォルトの構成は、プロジェクトのルートにある.env
ファイルに保存されます。 このファイルはすべての開発者向けのファイルであり、リポジトリの一部です。
ENV_hwi_facebook_client_id=1234 ENV_hwi_facebook_client_secret=4567
docker-compose up -d
起動されると、ファイルがロードされ、値はphp
サービスの説明のenvironment
ブロックを介してコンテナーに入ります。
services: php: environment: ENV_hwi_facebook_client_id: "${ENV_hwi_facebook_client_id}" ENV_hwi_facebook_client_secret: "${ENV_hwi_facebook_client_secret}"
Symfony内では、これらの値はapp/config/parameters.yml
ファイルを介して取得されます(これもアプリケーションの一部です)。
parameters: hwi_facebook_client_id: "%env(ENV_hwi_facebook_client_id)%" env(ENV_hwi_facebook_client_id): ~ hwi_facebook_client_secret: "%env(ENV_hwi_facebook_client_secret)" env(ENV_hwi_facebook_client_secret): ~
新しいパラメーターを実装するには、 docker-compose
を再起動する必要があります。
docker-compose stop docker-compose up -d
開発者テストサイト
開発者のテストサイトに変更を展開する前に、管理者はSettings --> Pipelines
セクションでこのサイトの変数値を追加する必要があります。 接尾辞_MASTER
変数名に追加する必要があります
ENV_hwi_facebook_client_id_MASTER ENV_hwi_facebook_client_secret_MASTER
変数が作成されない場合、それらの値は.env
ファイルから.env
ます。
ステージング
マージリクエストを受け入れる前に、メインリポジトリは、開発者のテストサイトで行われたように、接尾辞_MASTER
変数を追加します。
マージリクエストを受け入れ、 staging
の変更を実装した後、他のすべての開発者リポジトリに変数を追加する必要があります。
生産
ステージングで行われたように、接尾辞が_PRODUCTION
変数をメインリポジトリに追加する必要があります。
開発者は開発環境でxdebug
拡張機能も利用でき、CSSファイルとJavascriptファイルはWebpack Encoreを使用して管理されます。
内部CI / CD
継続的インテグレーション/実装のプロセスは、リポジトリのルートにある.gitlab-ci.ymlファイルに記述されており、依存関係のロード、phpunitテスト、アセンブリ、デプロイメントの4つのステージで構成されています。
依存関係の読み込み
この段階で、 composer
使用してすべてのアプリケーションの依存関係をインストールしようとします。
deps:php-composer: stage: deps image: covex/php7.1-fpm:1.0 script: - echo '{"github-oauth":{"github.com":"'"$COMPOSER_GITHUB_TOKEN"'"}}' > ./auth.json - composer install --prefer-dist --no-scripts --no-autoloader --no-interaction tags: - executor-docker
この段階の結果は、フォルダー/composer/home/cache
いっぱいにします。 このフォルダーはgitlab-ci-multi-runner
volume
に保存され、コンポーザーキャッシュはすべての後続のタスク(現在のパイプラインと後続のパイプラインの両方)で使用できます。
PHPUnitテスト
phpunit
起動する前に、Symfonyアプリケーションが機能するための環境変数が作成されます。 テスト環境の変数の値の一部が他のすべての環境の値と異なる場合は、GitLabリポジトリの設定にそのような変数を接尾辞_TEST
作成する必要があります(たとえば、 ENV_hwi_facebook_client_id_TEST
)。 次に、その値は.env
ファイルのデフォルトを.env
ます。
.template-suffix-vars: &suffix-vars before_script: - cat .env | grep ENV_ > .build-env - sed -i 's/^/export /' .build-env - for name in `env | awk -F= '{if($1 ~ /'"$ENV_SUFFIX"'$/) print $1}'`; do echo 'export '`echo $name|awk -F''"$ENV_SUFFIX"'$' '{print $1}'`'='`printenv $name`'' >> .build-env; done test:phpunit: stage: test image: covex/php7.1-fpm:1.0 <<: *suffix-vars variables: ENV_SUFFIX: "_TEST" script: - eval $(cat .build-env) - echo '{"github-oauth":{"github.com":"'"$COMPOSER_GITHUB_TOKEN"'"}}' > ./auth.json - composer require phpunit/phpunit:* --dev - phpunit dependencies: [] tags: - executor-docker
組立
ここで、 phpプロジェクトのアセンブリは、 nginxおよびphpコンテナーのdockerイメージを作成し、準備されたイメージをGitLab Container Registryにレイアウトします。
.template-docker-nginx-image: &docker-nginx-image stage: build image: docker:latest <<: *suffix-vars script: - eval $(cat .build-env) - docker build --tag $CI_NGINX_IMAGE_WITH_TAG --build-arg server_name=$SERVER_NAME --build-arg server_upstream=prod --build-arg app_php=app ./docker/nginx - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY - docker push $CI_NGINX_IMAGE_WITH_TAG - docker logout $CI_REGISTRY tags: - executor-docker - docker-in-docker .template-docker-app-image: &docker-app-image stage: build image: docker:latest <<: *suffix-vars script: - eval $(cat .build-env) - echo '{"github-oauth":{"github.com":"'"$COMPOSER_GITHUB_TOKEN"'"}}' > ./auth.json - docker build --tag $CI_APP_IMAGE_WITH_TAG . - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY - docker push $CI_APP_IMAGE_WITH_TAG - docker logout $CI_REGISTRY dependencies: - deps:php-composer tags: - executor-docker - docker-in-docker .template-docker-compose: &docker-compose stage: build image: covex/docker-compose:1.0 <<: *suffix-vars script: - eval $(cat .build-env) - mkdir build - docker-compose -f docker-compose-deploy.yml config > build/docker-compose.yml - sed -i 's/\/builds\/'"$CI_PROJECT_NAMESPACE"'\/'"$CI_PROJECT_NAME"'/\./g' build/docker-compose.yml artifacts: untracked: true name: "$CI_COMMIT_REF_NAME" paths: - build/ tags: - executor-docker dependencies: [] build:docker-nginx-image-master: <<: *docker-nginx-image variables: ENV_SUFFIX: "_MASTER" only: - master except: - tags build:docker-nginx-image-production: <<: *docker-nginx-image variables: ENV_SUFFIX: "_PRODUCTION" only: - /^release-.*$/ except: - branches build:docker-app-image-master: <<: *docker-app-image variables: ENV_SUFFIX: "_MASTER" only: - master except: - tags build:docker-app-image-production: <<: *docker-app-image variables: ENV_SUFFIX: "_PRODUCTION" only: - /^release-.*$/ except: - branches build:docker-compose-master: <<: *docker-compose variables: ENV_SUFFIX: "_MASTER" only: - master except: - tags build:docker-compose-production: <<: *docker-compose variables: ENV_SUFFIX: "_PRODUCTION" only: - /^release-.*$/ except: - branches
ここで、 build:docker-app-image-master
タスクbuild:docker-app-image-master
は、ステージングサイト(および開発者のテストサイト)のPHPアプリケーションのイメージを作成します。 そしてbuild:docker-app-image-production
タスクbuild:docker-app-image-production
は本番サイト用です。 タスクごとに、接尾辞が_MASTER
または_PRODUCTION
であるパイプライン設定の変数の値は、 .env
ファイルのデフォルト値と重複します。 nginx
イメージをアセンブルするためのタスクは、同様の方法で説明されています(タスクbuild:docker-nginx-image-master
およびbuild:docker-nginx-image-production
参照)。
また、この段階でdocker-compose.yml
ファイルが作成され、次の段階でリモートサーバーにコピーされます( build:docker-compose-master
およびbuild:docker-compose-production
のタスクbuild:docker-compose-master
参照)。 生成されたdocker-compose.yml
は、アプリケーションの起動に必要なすべての環境変数が含まれています。 services
セクションでは、すべてのコンテナは既製のdockerイメージからのみ作成されます。
networks: nw_external: external: name: graynetwork nw_internal: {} services: mysql: environment: MYSQL_DATABASE: project MYSQL_PASSWORD: project MYSQL_ROOT_PASSWORD: root MYSQL_USER: project expose: - '3306' image: covex/mysql:5.7 networks: nw_internal: null restart: always volumes: - database:/var/lib/mysql:rw nginx: depends_on: mysql: condition: service_healthy image: gitlab.site.ru:5005/dev1-projects/symfony-workflow2/nginx:master networks: nw_external: ipv4_address: 192.168.10.13 nw_internal: null ports: - 80/tcp restart: always volumes: - assets:/srv/a:ro - assets:/srv/b:ro - assets:/srv/storage:ro php: environment: ENV_database_host: mysql ENV_database_mysql_version: '5.7' ENV_database_name: project ENV_database_password: project ENV_database_port: '3306' ENV_database_user: project ENV_mailer_from: andrey@mindubaev.ru ENV_mailer_host: 127.0.0.1 ENV_mailer_password: 'null' ENV_mailer_transport: smtp ENV_mailer_user: 'null' ENV_secret: ThisTokenIsNotSoSecretChangeIt image: gitlab.site.ru:5005/dev1-projects/symfony-workflow2:master networks: nw_internal: null restart: always volumes: - assets:/srv/a:rw - assets:/srv/b:rw - assets:/srv/storage:rw spare: environment: ENV_database_host: mysql ENV_database_mysql_version: '5.7' ENV_database_name: project ENV_database_password: project ENV_database_port: '3306' ENV_database_user: project ENV_mailer_from: andrey@mindubaev.ru ENV_mailer_host: 127.0.0.1 ENV_mailer_password: 'null' ENV_mailer_transport: smtp ENV_mailer_user: 'null' ENV_secret: ThisTokenIsNotSoSecretChangeIt image: gitlab.site.ru:5005/dev1-projects/symfony-workflow2:master networks: nw_internal: null restart: always volumes: - assets:/srv/a:rw - assets:/srv/b:rw - assets:/srv/storage:rw version: '2.1' volumes: assets: {} database: {}
展開
この時点で、アプリケーションのdockerイメージの準備が整い、Container Registryにアップロードされます。 アプリケーションの更新は残ります。
リモートサーバーにはphpmyadmin
サービスがありません。 php
サービスに加えて、まったく同じspare
サービスが追加されました。 また、 nginx
構成では、1つのサーバーの代わりに、 upstream
2つが登録されます。 2つの同一のサービスを使用すると、 展開のダウンタイムをほぼゼロにできます 。
.template-secure-copy: &secure-copy stage: deploy image: covex/alpine-git:1.0 before_script: - eval $(ssh-agent -s) - ssh-add <(echo "$SSH_PRIVATE_KEY") script: - eval $(cat .build-env) - ssh -p 22 $DEPLOY_USER@$DEPLOY_HOST 'set -e ; rm -rf '"$DEPLOY_DIRECTORY"'_tmp ; mkdir -p '"$DEPLOY_DIRECTORY"'_tmp' - scp -P 22 -r build/* ''"$DEPLOY_USER"'@'"$DEPLOY_HOST"':'"$DEPLOY_DIRECTORY"'_tmp' - ssh -p 22 $DEPLOY_USER@$DEPLOY_HOST 'set -e ; if [ -d '"$DEPLOY_DIRECTORY"' ]; then rm -rf '"$DEPLOY_DIRECTORY"'; fi ; mv '"$DEPLOY_DIRECTORY"'_tmp '"$DEPLOY_DIRECTORY"' ; cd '"$DEPLOY_DIRECTORY"' ; docker login -u gitlab-ci-token -p '"$CI_JOB_TOKEN"' '"$CI_REGISTRY"' ; docker-compose pull ; docker-compose up -d --no-recreate ; docker-compose up -d --force-recreate --no-deps spare ; docker-compose exec -T spare sh -c "cd /srv && rm -rf b/* && cp -a web/. b/ && rm -rf a/* && cp -a web/. a/" ; docker-compose exec -T spare phing storage-prepare database-deploy ; docker-compose up -d --force-recreate --no-deps php' - ssh -p 22 $DEPLOY_USER@$DEPLOY_HOST 'set -e ; cd '"$DEPLOY_DIRECTORY"' ; echo "[$(date -R)] web-server is down" ; docker-compose stop nginx ; docker-compose up -d nginx ; echo "[$(date -R)] web-server is up"' tags: - executor-docker deploy:secure-copy-master: <<: *secure-copy only: - master except: - tags environment: name: staging dependencies: - build:docker-compose-master deploy:secure-copy-production: <<: *secure-copy only: - /^release-.*$/ except: - branches environment: name: production dependencies: - build:docker-compose-production
展開アルゴリズムは次のとおりです。
-
build
段階で生成されたdocker-compose.yml
ファイルをコピーします - コンテナレジストリから新しいイメージをダウンロードする
-
spare
コンテナの更新 -
nginx
静的ファイルを更新し、データベースを移行します -
php
コンテナの更新 -
nginx
およびmysql
コンテナーの更新(戦闘状態-これは必要ありません)
spare
コンテナまたはphp
コンテナのアップグレード中に、 nginx
かが数秒間使用できなくなった後、 upstream
使用可能な次のコンテナに切り替わります。 すなわち アプリケーションは100%の HTTP要求に対して正しく動作しますが、遅延が発生する場合があります。
データベースの移行中、HTTPリクエストの前半は、古いデータベース構造で機能するphp
コンテナにphp
れ、後半は、新しい構造でのみ機能するspare
コンテナにspare
れます。 すなわち 両方のコンテナで、データベースの移行中に誤動作が発生する可能性があります 。 , , .
nginx
mysql
, . , "". 5 , 80-90% deployment downtime.
おわりに
GitLab Continuous Integration & Deployment
docker-compose
— . - vagrant
. , , , , composer.json
. Development- — , production, Linux + Apache + PHP + MySQL. , , .
— docker swarm
, kubernetes
, . , .