docker-composeおよびGitLab CIを使用したSymfonyアプリケーションの継続的な統合/展開

この記事では、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

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を使用したサーバーの構成



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を使用したサーバーのセットアップ



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_...



変数を参照)。







外部Nginxを構成する

構成ファイルの作成



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-...



タグを作成する必要があります。







開発者は、プロジェクトコードの変更とともに、新しい値をアプリケーションパラメータに追加できます。 これらのパラメーターの値は、環境によって異なる場合があります。







Symfony設定を構成する

ローカル開発者環境



デフォルトの構成は、プロジェクトのルートにある.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



使用してすべてのアプリケーションの依存関係をインストールしようとします。







.gitlab-ci.ymlのDEPSステージ
 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



ます。







.gitlab-ci.ymlのテストステップ
 .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にレイアウトします。







.gitlab-ci.ymlのビルドフェーズ
 .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イメージからのみ作成されます。







生成されたdocker-compose.ymlファイルの例
 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つの同一のサービスを使用すると、 展開のダウンタイムをほぼゼロにできます







.gitlab-ci.ymlのデプロイステージ
 .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
      
      





展開アルゴリズムは次のとおりです。









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



, . , .








All Articles