- 投稿日:2020-08-06T20:03:32+09:00
【ECS】nginxとphp-fpmが連携したコンテナをECSで動かす
概要
ECS及びECRでコンテナを動かす
ころころUIが変わるので文字ベースで必要な作業をメモゴール
下記で作ったコンテナイメージをECSで動かしphpinfoが見られる
LBは通さずインスタンス直通
https://qiita.com/chanP_yamazaki/items/1397f4899f7768c1ed60プッシュ元のEC2インスタンスにECRへのアクセス権限を付与
・「AmazonEC2ContainerRegistryFullAccess」ポリシーがアタッチされたIAMRoleを設定する
ECRのリポジトリを作る
・Amazon Container Service -> Amazon ECR -> Repositories へ
・リポジトリを作成
名前は任意ECRへコンテナイメージをプッシュする
・先ほど作成したリポジトリをクリック
・プッシュコマンドの表示をクリック
・手順1の「認証トークンを取得し、レジストリに対して Docker クライアントを認証します。」のコマンドをコピーして実行手順1$ aws ecr get-login-password --region リージョン | docker login --username AWS --password-stdin アカウントID.dkr.ecr.リージョン.amazonaws.com ※ get-login-passwordはaws-cliのv1.17.10以降でないと実行できません その場合は下記 $ aws ecr get-login --region リージョン --no-include-email ↑で出力された物をコピーして実行 $ docker login -u AWS -p XXXXXXX https://アカウントID.dkr.ecr.リージョン.amazonaws.com・手順2は既にイメージをビルド済みであればスキップ
・手順3でビルド済みのコンテナイメージ名を確認してタグを付ける
これをnginxとphp-fpmそれぞれで実施手順3$ docker images $ docker tag コンテナイメージ名:latest アカウントID.dkr.ecr.リージョン.amazonaws.com/リポジトリ名:プッシュする際のイメージ名 例: docker tag project_nginx:latest アカウントID.dkr.ecr.リージョン.amazonaws.com/test:nginx $ docker images プッシュしたいコンテナイメージにecr用のタグがついていればOK・手順4でタグ付したコンテナイメージをECRへプッシュ
手順4$ docker push アカウントID.dkr.ecr.リージョン.amazonaws.com/test 一つずつも指定可能 $ docker push アカウントID.dkr.ecr.リージョン.amazonaws.com/test:php-fpm $ docker push アカウントID.dkr.ecr.リージョン.amazonaws.com/test:nginx・プッシュ後の確認とお掃除
ECRを確認してプッシュしたイメージが一覧に出てくるかを確認
下記コマンドでECRからログアウト
※なにもしなければ12時間でログアウトするけど不要ならログアウトした方が安全$ docker logout アカウントID.dkr.ecr.リージョン.amazonaws.comECSで行う作業の全体像を把握
・タスク定義
docker-compose.ymlに相当する設定
これをGUIで設定していくイメージ・ECSクラスター作成
ECS経由で立ち上げるEC2インスタンスに関する設定・ECSクラスター -> サービス作成
クラスターで立ち上げたEC2インスタンスに対して、どのタスクをどのように配置するかを設定するECSのタスクを定義する
※記載がないパラメータは変更しないものとする
・タスク名をつける
後から変えられないので注意
・コンテナの追加
これがまさにdocker-compose.ymlに相当している
▼ nginx
名称 設定値 コンテナ名 nginx イメージ ECRにプッシュしたnginxコンテナの「イメージのURI」をコピーして貼り付け メモリ制限 必要な分だけ設定。全コンテナの合計値がインスタンスのメモリサイズを超えないように注意 ポートマッピング 今回はLBを通さない & httpアクセスなので80:80を設定 スタートアップ依存順序 depends_on設定。コンテナ名「php-fpm」、状態「START」を設定 ネットワーク設定 リンクに「php-fpm:php-fpm」を設定 ストレージとログ ログ設定の「Auto-configure CloudWatch Logs」をONに (立ち上げに失敗した際にログを追えるようになる 他は最小構成では設定不要
▼ php-fpm
名称 設定値 コンテナ名 php-fpm イメージ ECRにプッシュしたphp-fpmコンテナの「イメージのURI」をコピーして貼り付け メモリ制限 必要な分だけ設定。全コンテナの合計値がインスタンスのメモリサイズを超えないように注意 ポートマッピング php-fpmは外に開ける必要無いので設定不要 ストレージとログ ログ設定の「Auto-configure CloudWatch Logs」をONに (立ち上げに失敗した際にログを追えるようになる 他は最小構成では設定不要
・他は設定せず作成
ECSクラスターを作成する
・Amazon Container Service -> Amazon ECS -> クラスター へ
・クラスターの作成
ステップ 名称 設定値 クラスターテンプレートの選択 クラスターテンプレートの選択 EC2 Linux + ネットワーキング クラスターの設定 クラスター名 test-cluster インスタンスの設定各種 インスタンスタイプや数は必要に応じて AmiId 特に理由がなければ今は 「AmazonLinux2」 キーペア コンテナの思想上、インスタンスに入って何かを操作する必要はないので 「なし」 ネットワーキング vpc、サブネットは必要に応じた設定を ネットワーキング - セキュリティグループ ポートは80を開ける。IPは必要なものを Auto assign public IP Use Subnet setting ・作成実行
実行したクラスターの「ECSインスタンス」タブで、指定した個数のインスタンスが立ち上がり、ステータスがACTIVEになったことを確認コンテナを立ち上げる
・サービスタブを開いて「作成」
ステップ 名称 設定値 サービスの設定 起動タイプ EC2 タスク定義 ファミリー 先ほど「タスク定義」で作ったタスクを指定 タスク定義 リビジョン latest(最新バージョン)を指定 クラスター test-cluster サービス名 適当に サービスタイプ REPLICA (DAEMONだとどう変わるか後で調査 タスク数 1 ネットワーク構成 LBを通す場合はここで設定。今回は何も設定せず次へ Auto Scalingオプション EC2インスタンスの数をAutoScalingさせたいならここで設定。今回は何も設定せず次へ ・サービスの作成
・作成したサービスのタスクタブにRUNNINGのタスクが出来あがれば成功
・EC2のpublicIPかDNS名にアクセスしてphpinfoが確認できればOK!
- 投稿日:2020-08-06T19:24:57+09:00
Ubuntu 16.04をインストールしたAlibaba Cloud ECS上でDockerを使ってMastodonを設定する
このチュートリアルでは、Ubuntu 16.04をインストールしたAlibaba Cloud Elastic Compute Service (ECS)上でMastodonを設定します。
本ブログは英語版からの翻訳です。オリジナルはこちらからご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。
前提条件
- Alibaba Cloud Elastic Compute Service (ECS)を有効にし、有効な支払い方法を確認する必要があります。新規ユーザーの場合は、新規アカウントに300ドル~1200ドル相当のAlibaba Cloudクレジットを獲得できます。ECSインスタンスのセットアップ方法がわからない場合は、こちらのチュートリアルまたはクイックスタートガイドを参照してください。ECSインスタンスは、少なくとも2GBのRAMと2コアプロセッサを搭載している必要があります。
- Alibaba Cloudから登録されたドメイン名。すでにAlibaba Cloudまたは他のホストからドメインを登録している場合は、そのドメインネームサーバーレコードを更新することができます。
- ドメイン名は、あなたのAlibaba Cloud ECSのIPアドレスを指している必要があります。
- Alibaba CloudのVNCコンソールまたはPCにインストールされているSSHクライアントにアクセスします。
- サーバーのホスト名を設定し、root権限を持つユーザーを作成します。
サーバーの設定
パッケージのインストールを進める前に、以下のコマンドを使用してUbuntuシステムをアップデートしてください。このコマンドを実行するには、root 以外のユーザから sudo 権限でログインすることを忘れないでください。
# sudo apt update && sudo apt upgradeDocker CEをインストールするためには、サポートされているファイルを取得するためにsoftware-properties-commonパッケージが必要です。software-properties-commonをインストールするには、以下のコマンドを実行します。
# sudo apt-get install software-properties-common -yDocker CEのインストールには、Apt-transport-https、ca-certificates、curlが必要です。これらをインストールするには、以下のコマンドを実行します。
# sudo apt-get install apt-transport-https -y # sudo apt-get install ca-certificates -y # sudo apt-get install curl -yDocker CEとDocker Composeのインストール
以下のコマンドを実行して、Docker用のGPGキーを追加します。
# curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -以下のコマンドを実行して、GPG キーのフィンガープリントを確認します。
# sudo apt-key fingerprint 0EBFCD88以下のコマンドを実行してDockerリポジトリを追加します。
# sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable”以下のコマンドを実行してシステムをアップデートし、追加されたリポジトリをロードします。
# sudo apt update以下のコマンドを実行してDockerをインストールします。
# sudo apt install docker-ce以下のコマンドを実行して、ユーザ名をdockerグループに追加します。
# sudo adduser aareez docker現在のシェルセッションを閉じて、新しいセッションを開始してください。そうしないとDockerを実行できず、パーミッションエラーが表示される可能性があります。
以下のコマンドを実行して、dockerが正しく実行されているかどうかを確認します。
# docker run hello-worldDocker Composeをダウンロードしてインストールするには、以下のコマンドを実行します。
# sudo curl -L https://github.com/docker/compose/releases/download/1.21.2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-composeDocker Composeファイルのパーミッションを設定するには、以下のコマンドを実行します。
# sudo chmod +x /usr/local/bin/docker-composeMastodonをインストール
以下のコマンドを実行して、GitリポジトリからMastodonをクローンします。
# git clone https://github.com/tootsuite/mastodon以下のコマンドを実行して、ダウンロードしたディレクトリに移動してください。
# cd mastodon以下のコマンドを実行して、.env.production.sampleを.env.productionにコピーします。
# cp .env.production.sample .env.production秘密鍵を生成するには、Dockerイメージをビルドして実行する必要があります。ビルドするには、以下のコマンドを実行します。
# docker-compose buildDockerイメージの構築に成功しました。設定に必要な3つの秘密鍵を生成する必要があります。SECRET_KEY_BASEを生成するには、以下のコマンドを実行します。
# SECRET_KEY_BASE=$(docker-compose run --rm web bundle exec rake secret)以下のコマンドを実行して、.env.productionファイルにSECRET_KEY_BASEの値を挿入します。
# sed -i -e "s/SECRET_KEY_BASE=/&${SECRET_KEY_BASE}/" .env.productionOTP_SECRETを生成するには、以下のコマンドを実行します。
# OTP_SECRET=$(docker-compose run --rm web bundle exec rake secret)以下のコマンドを実行して、.env.productionファイルにSECRET_KEY_BASEの値を挿入します。
# sed -i -e "s/OTP_SECRET=/&${OTP_SECRET}/" .env.productionPAPERCLIP_SECRETを生成するには、以下のコマンドを実行します。
# PAPERCLIP_SECRET=$(docker-compose run --rm web bundle exec rake secret)以下のコマンドを実行して、.env.productionファイルにPAPERCLIP_SECRETの値を挿入します。
# sed -i -e "s/PAPERCLIP_SECRET=/&${PAPERCLIP_SECRET}/" .env.productionLOCAL_DOMAINの値を更新する必要があります。そのためには、テキストエディタで.env.productionファイルを開く必要があります。以下のコマンドを実行して、.env.productionファイルを開きます。
# sudo nano ~/mastodon/.env.productionLOCAL_DOMAIN変数を見つけ、その値をexample.comからECSのドメイン名またはIPアドレスに変更し、更新したファイルを保存します。
mastodonに移動します。
# cd mastodon上記で変更したので、再度Dockerイメージをビルドする必要があります。ビルドするには、以下のコマンドを実行します。
# docker-compose buildを実行してマイグレーションを実行します。
# docker-compose run --rm web rails db:migrate物事をよりスムーズにするためには、アセットを事前にコンパイルする必要があります。そのためには、以下のコマンドを実行します。
# docker-compose run --rm web rails assets:precompile以下のコマンドを実行してコンテナを実行します。
# docker-compose up -dNginxサーバーのインストールと設定
Nginxの設定を作成してMastodonを動作させ、SSL証明書をインストールするには、Nginxサーバーをインストールする必要があります。
以下のコマンドを実行してnginxサーバーをインストールします。
# sudo apt-get install nginx以下のコマンドを実行して、デフォルトサイトのNginx設定を削除する必要があります。
# sudo rm /etc/nginx/sites-available/default以下のコマンドを実行して、デフォルトサイトのシンボリックリンクを削除します。
# sudo rm /etc/nginx/sites-enabled/default以下のコマンドを実行して、Mastodon用のNginx設定ファイルを作成します。
# sudo touch /etc/nginx/sites-available/mastodon以下のコマンドを実行して、Mastodonのシンボリックリンクを作成します。
# sudo ln -s /etc/nginx/sites-available/mastodon /etc/nginx/sites-enabled/mastodon以下のコマンドを実行して、Mastodon Nginxの設定ファイルをnanoのテキストエディタで開きます。
# sudo nano /etc/nginx/sites-available/mastodon開いているファイルに以下のテキストをコピーペーストし、変更内容を保存します。
map $http_upgrade $connection_upgrade { default upgrade; '' close; } server { listen 80; listen [::]:80; server_name softpedia.xyz; root /home/mastodon/live/public; # Useful for Encrypt location /.well-known/acme-challenge/ { allow all; } location / { return 301 https://$host$request_uri; } } server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name softpedia.xyz; ssl_protocols TLSv1.2; ssl_ciphers HIGH:!MEDIUM:!LOW:!aNULL:!NULL:!SHA; ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m; ssl_certificate /etc/letsencrypt/live/softpedia.xyz/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/softpedia.xyz/privkey.pem; keepalive_timeout 70; sendfile on; client_max_body_size 80m; root /home/mastodon/live/public; gzip on; gzip_disable "msie6"; gzip_vary on; gzip_proxied any; gzip_comp_level 6; gzip_buffers 16 8k; gzip_http_version 1.1; gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; add_header Strict-Transport-Security "max-age=31536000"; location / { try_files $uri @proxy; } location ~ ^/(emoji|packs|system/accounts/avatars|system/media_attachments/files) { add_header Cache-Control "public, max-age=31536000, immutable"; try_files $uri @proxy; } location /sw.js { add_header Cache-Control "public, max-age=0"; try_files $uri @proxy; } location @proxy { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto https; proxy_set_header Proxy ""; proxy_pass_header Server; proxy_pass http://127.0.0.1:3000; proxy_buffering off; proxy_redirect off; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; tcp_nodelay on; } location /api/v1/streaming { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto https; proxy_set_header Proxy ""; proxy_pass http://127.0.0.1:4000; proxy_buffering off; proxy_redirect off; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; tcp_nodelay on; } error_page 500 501 502 503 504 /500.html; }SSL証明書をインストール
Let's Encrypt with Certbotを使ってSSL証明書をインストールします。そのためには、以下の手順を実行します。
パッケージを更新します。
# sudo apt-get updatesoftware-properties-commonをインストールします。
# sudo apt-get install software-properties-common.以下のコマンドを使用して、サートボットのリポジトリを追加します。
# sudo add-apt-repository ppa:certbot/certbot追加された certbot リポジトリを読み込むようにパッケージを更新します。
# sudo apt-get updateSSL証明書発行前にapacheを停止します。
# sudo systemctl stop apache2以下のコマンドでpython-certbot-apacheをインストールします。
# sudo apt-get install python-certbot-apache以下のコマンドを実行して、Let's Encrypt SSLを発行してもらいます。
# sudo certbot --apache -d softpedia.xyzオプション2を選択してリンクをhttpsにリダイレクトし、SSLのバーチャルホスト設定を更新します。apacheサーバを再起動します。
# sudo systemctl start apache2あなたのウェブサイトにアクセスするには、https://your_domain_name.tld
これで完了です。Alibaba Cloud ECSサーバーにMastodonをインストールすることに成功しました。データベースのデフォルトパスワードを変更し、管理者アカウントを設定することで安全にインストールできます。
アリババクラウドは日本に2つのデータセンターを有し、世界で60を超えるアベラビリティーゾーンを有するアジア太平洋地域No.1(2019ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
アリババクラウドジャパン公式ページ
- 投稿日:2020-08-06T19:24:39+09:00
Docker 公式ドキュメントの Rails Quickstart 完全解説
Docker の公式ドキュメントに Rails の Quickstart があります:
Quickstart: Compose and Rails | Docker Documentationこちらのドキュメントを参考に Rails を始める方が増えており、
Tetatail で結構な件数の質問に回答しました。この Quickstartは説明が不十分だったり間違いがあったりで
Rails に慣れてないと行間を読んで正しい手順を踏むことは難しいでしょう。この記事で指摘している Quickstart の間違いなどは、すでに GitHub 上で PR を投稿しています。
Yukihiko shinoda/update quickstart rails by yukihiko-shinoda · Pull Request #11215 · docker/docker.github.ioここで Rails の Quickstart についてまとめて解説しておきます。
この Quickstart を実施するために必要なツール
この解説を理解するために必要な基礎知識
この Quickstart を理解するためには、次の基礎知識が必要です:
- エディターでテキストファイルを編集可能
- Docker のコマンドを使ってサービスを実行する程度の基礎知識
- Docker Compose の基礎知識
理解するために必要ないツール・知識
- Rails チュートリアル
- Rails チュートリアルで解説されていることと、この Quickstart で得られる知識は、大部分が別の内容です
- この Quickstart を理解する上で必要な Rails に関する知識はこの記事内で解説します
この Quickstart は何をするためのものなの?
この Quickstart ガイドでは、Docker Compose を使用して Rails / PostgreSQL アプリを設定および実行する方法を理解します。
この Quickstart はどんなことをしているの?
この Quickstart は次の手順を実施します:
- Define the project
- Docker イメージのビルドに必要なファイルを作成します
- Build the project
- 手順 1. で準備したファイルをもとに Rails の実行環境を起動して Rails を動かし新規 Rails アプリケーションを作成します
- このとき自動的に Docker イメージがビルドされます
- 新規作成した Rails アプリケーションを使い Docker イメージをビルドし直します
- Connect the database
- Rails の実行環境とデータベースのサービスを一度に起動します
- View the Rails welcome page!
- ブラウザで Rails の welcome page が表示されることを確認します
この Quickstart が理解しづらい原因
この Quickstart は手順 1. Define the project で準備するファイルやその内容が
相当な量であるにも関わらず、それらの目的についての解説が不十分であるためです。
- 上記の手順 1. Define the project で準備するファイルの内容を最初からすべて理解することは難しいです
- 準備するファイルの内容が次の目的を兼ねる内容になっており、どちらの目的のための内容なのか分かりづらいため
- 手順 2. Build the project で行う新規 Rails アプリケーション作成のための内容
- 最終的な Rails アプリケーション実行のための内容
- 手順 2. Build the project で Rails の実行環境のためのイメージを再度ビルドし直しています
- 手順 2. のコマンドが誤っています
Dockerfile
に不要な内容が含まれていますdocker-compose.yml
- 誤っています
- 不要な内容が含まれています
以降に、各手順で注意すべきポイントを解説します。
各手順の解説
Define the project
この手順では、Docker イメージのビルドに必要なファイルを作成します。
この手順を終えると、プロジェクトのディレクトリー内には次のようなファイルがあるはずです:
project/ +---docker-compose.yml +---Dockerfile +---entrypoint.sh +---Gemfile +---Gemfile.lockここで、初めてこの Quickstart を実施する人は
次の理由により混乱してしまうことでしょう:
- ファイルの内容が誤っていたり、不要な内容が含まれているため
- ここで準備するファイルやその内容が相当な量であるにも関わらず、それらの目的についての解説が不十分であるため
そこで、この記事では
Dockerfile
とdocker-compose.yml
の内容を次のように修正します:DockerfileFROM ruby:2.5 RUN apt-get update -qq && apt-get install -y nodejs RUN mkdir /myapp WORKDIR /myapp COPY Gemfile /myapp/Gemfile COPY Gemfile.lock /myapp/Gemfile.lock RUN bundle install COPY . /myapp # Add a script to be executed every time the container starts. COPY entrypoint.sh /usr/bin/ RUN chmod +x /usr/bin/entrypoint.sh ENTRYPOINT ["entrypoint.sh"] # Start the main process. CMD ["rails", "server", "-b", "0.0.0.0"]docker-compose.ymlversion: '3.8' services: db: image: postgres environment: POSTGRES_PASSWORD: password web: build: . volumes: - .:/myapp ports: - "3000:3000" depends_on: - db各ファイルの目的の整理
ここで準備するファイルは次の 2 つの目的のためです:
- 手順 2. Build the project で行う新規 Rails アプリケーション作成のため
- 手順 3. Connect the database で行う最終的な Rails アプリケーション実行のため
どのファイルがどの目的のためのファイルなのかは、次の通りです:
ファイル 目的 docker-compose.yml 手順 2, 3. Dockerfile 手順 2, 3. entrypoint.sh 手順 3. Gemfile 手順 2. Gemfile.lock 手順 2. まず、手順 2. のために必要なファイルだけを準備できないの?
手順 2. のために必要なファイルだけを準備すると、次のようになります:
Dockerfile
手順 2. で必要な処理以外をコメントアウトします:
DockerfileFROM ruby:2.5 # RUN apt-get update -qq && apt-get install -y nodejs RUN mkdir /myapp WORKDIR /myapp COPY Gemfile /myapp/Gemfile # COPY Gemfile.lock /myapp/Gemfile.lock RUN bundle install # COPY . /myapp # Add a script to be executed every time the container starts. # COPY entrypoint.sh /usr/bin/ # RUN chmod +x /usr/bin/entrypoint.sh # ENTRYPOINT ["entrypoint.sh"] # # Start the main process. # CMD ["rails", "server", "-b", "0.0.0.0"]
Gemfile
をCOPY
してbundle install
を実行する理由この後の手順 2. では
rails new
というコマンドを使い、
新規 Rails アプリケーションを作成します。
rails new
コマンドを使うためには、Rails をインストールする必要があります。
Rails は「Gem パッケージ」という形式で配布されています。
「Gem パッケージ」とは、Ruby のプログラムを配布するための形式です。参考: パッケージ - 意味・説明・解説 : ASCII.jpデジタル用語辞典
Gem パッケージをインストールするためには、
bundler
という、Gem パッケージを一度にインストールするためのツールの
bundle install
コマンドを使います。
bundle install
コマンドはGemfile
というファイルを参照してパッケージをインストールします。ここで出てきた命令一覧:
- RUN | Dockerfile reference | Docker Documentation
- COPY | Dockerfile reference | Docker Documentation
/myapp
を新規作成してWORKDIR
に指定する理由ここで、
/myapp
ディレクトリーを作成して作業ディレクトリーとして指定しています。
これは、ベースイメージとして指定されているruby:2.5
は、規定の作業ディレクトリーである/
には
大切なディレクトリーがたくさんあり、
Rails アプリケーションのコードを展開したり、後述する「bind
マウント」を行うと
様々な不具合が起きるためです。ベースイメージの作業ディレクトリーを調べる方法は次の通りです:
FROM ruby:2.5 RUN pwd$ docker-compose build db uses an image, skipping Building web Step 1/2 : FROM ruby:2.5 ---> a5c07a6f3bb6 Step 2/2 : RUN pwd ---> Running in 43f0381dd652 /参考: Answer: Is it possible to show the `WORKDIR` when building a docker image?
ここで出てきた命令一覧:
- WORKDIR | Dockerfile reference | Docker Documentation
- FROM | Dockerfile reference | Docker Documentation
Gemfile
Gemfile
は Quickstart で提示されている内容をそのまま準備します:Gemfilesource 'https://rubygems.org' gem 'rails', '~>5'
Gemfile
には、次のような情報を記述します:
- Gem パッケージをどこからダウンロードしてインストールするか
- インストールする Gem パッケージの一覧
この場合は標準の Gem パッケージ配信サーバーである https://rubygems.org から
Rails のバージョン 5 をインストールします。参考: Bundler: The best way to manage a Ruby application's gems
docker-compose.yml
続いて、
docker-compose.yml
です。手順 2. で必要な処理以外をコメントアウトします:
docker-compose.ymlversion: '3' services: # db: # image: postgres # environment: # POSTGRES_PASSWORD: password web: build: . volumes: - .:/myapp # ports: # - "3000:3000" # depends_on: # - dbbuild 命令の解説
db
サービスはここでは必要ありませんので、コメントアウトしました。
また、web
サービス内で手順 2. で必要な設定はbuild
とvolume
のみです。
build
は、先ほど作成したDockerfile
とGemfile
を使ってイメージをビルドするために必要です。
build: .
という指定は、
このweb
サービスのコンテナーのもととなるイメージとして、
docker-compose.yml
があるディレクトリーに存在するファイルを
コンテキストとしてビルドしたイメージを使うことになります。参考: build | Compose file version 3 reference | Docker Documentation
volumes 命令の解説
volumes
は、この設定がないと、
手順 2. でrails new
コマンドで作成する新規 Rails アプリケーションが、ホスト側のディレクトリーに残りません。
- .:/myapp
というvolumes
の設定は
ホスト側のdocker-compose.yml
があるディレクトリーをコンテナー内のディレクトリツリーの/myapp
に関連付けます。
こうすることで、手順 2. で実行するrails new
コマンドで作成された新規 Rails アプリケーションが
ホスト側のディレクトリーに出力されるようになります。このような volume の設定を
bind
といいます。参考:
Use bind mounts | Docker Documentation
volumes | Compose file version 3 reference | Docker Documentationまとめ
手順 2. のために必要なファイルだけを準備すると、次のようになります:
project/ +---docker-compose.yml +---Dockerfile +---Gemfile
Dockerfile
の中で、手順 2. に不要なコードをコメントアウトしたので
Gemfile.lock
は必要なくなりました。Build the project
新規 Rails アプリケーションの作成
冒頭で実行する次のコマンドについて解説します:
docker-compose run web rails new . --force --no-deps --database=postgresql
このコマンドは間違っており、正しくは次のコマンドです:
docker-compose run --no-deps web rails new . --force --database=postgresql
上記のコマンドは
docker-compose --no-deps run web
とrails new . --force --database=postgresql
に分けて考えます。
docker-compose --no-deps run web
上記のコマンドは
docker-compose.yml
で定義したweb
サービスのコンテナーを起動して実行します。
docker run
コマンドの書式は次の通りです:docker-compose run [options] [-v VOLUME...] [-p PORT...] [-e KEY=VAL...] [-l KEY=VALUE...] SERVICE [COMMAND] [ARGS...]
--no-deps
: Compose ファイル内のdepends_on
などで関係づけられたサービスを開始しませんつまり、
--no-deps
はdocker-compose.yml
内のdb
サービスのコンテナーを起動しないための設定です。
(この時点ではデータベースは必要ないため)
docker-compose run
コマンドは、
コンテナーを起動するためのイメージがまだビルドされていなければ、自動的にビルドを行います。
Dockerfile
内で、コンテナーを実行したときのCMD
が定義されていますが、
このトレーニングのようにdocker-compose run
コマンドでサービス名の後にコマンドを記述した場合は
CMD
の内容は無視され、代わりにコマンドラインから入力した内容が実行されます。
rails new . --force --database=postgresql
このコマンドは新規 Rails アプリケーションを作成します。
rails new
コマンドの書式は次の通りです:rails new APP_PATH [options]
-f
, [--force
]: すでに存在するファイルを上書きします
-d
, [--database=DATABASE
] 選択したデータベース向けに初期設定します
選択肢:mysql
/postgresql
/sqlite3
/oracle
/frontbase
/ibm_db
/sqlserver
/jdbcmysql
/jdbcsqlite3
/jdbcpostgresql
/jdbc
省略時:sqlite3
このコマンドによって
Gemfile
を新規 Rails アプリケーション用の内容に上書きするので
--force
オプションがない場合、Gemfile
を上書きするかどうかの確認が表示されます。イメージの再ビルド
手順 1. で、この解説記事に従って
entrypoint.sh
をまだ作成していない場合は、この時点で作成します:#!/bin/bash set -e # Remove a potentially pre-existing server.pid for Rails. rm -f /myapp/tmp/pids/server.pid # Then exec the container's main process (what's set as CMD in the Dockerfile). exec "$@"また、
Dockerfile
の一部コメントアウトしていた部分を、次のようにコメントインします:DockerfileFROM ruby:2.5 RUN apt-get update -qq && apt-get install -y nodejs RUN mkdir /myapp WORKDIR /myapp COPY Gemfile /myapp/Gemfile COPY Gemfile.lock /myapp/Gemfile.lock RUN bundle install # COPY . /myapp # Add a script to be executed every time the container starts. COPY entrypoint.sh /usr/bin/ RUN chmod +x /usr/bin/entrypoint.sh ENTRYPOINT ["entrypoint.sh"] # Start the main process. CMD ["rails", "server", "-b", "0.0.0.0"]まだコメントアウトしたままの命令がありますが、
これらは手順 4. を終えた後、Rails アプリケーションのイメージを作成するときに必要となる命令です。
手順 4. を終えた後で解説します。次のコマンドを実行すると、イメージが再ビルドされます:
docker-compose build
Dockerfile
の解説
ENTRYPOINT
に Shell Script を設定しCMD
でコマンドを指定する理由Rails Server の二重起動を防ぐための排他ファイルである
server.pid
が
何らかの原因で残ってしまった場合を想定して、
コンテナー起動時、Rails Server を起動する前に
entrypoint.sh
内でserver.pid
を削除する処理を実行しています。ここで重要なのは、
ENTRYPOINT
とCMD
命令を使った Dockerfile のデザインパターンで
イメージからコンテナーを起動したときの規定の動作を定義していることです。
ENTRYPOINT
とCMD
を両方とも配列形式で与えると、すべての配列の要素を並べたコマンドが実行されます。参考: Understand how CMD and ENTRYPOINT interact | Dockerfile reference | Docker Documentation
この例のように、
ENTRYPOINT
に Shell Script を設定し、
その Shell Script のコード内の最後でexec "$@"
を呼び出す設計は
Dockerfile のデザインパターンとして広く使われています。
憶えておいて損はありません。こうすることで、
CMD
で指定したコマンドを実行する前に何らかの初期化処理を実行することができるのです。参考:
- Docker - How to use an entrypoint script to initialize container data at runtime
- Exec form ENTRYPOINT example | Dockerfile reference | Docker Documentation
- Bourne Shell Builtins (Bash Reference Manual)
- Unix / Linux - Special Variables - Tutorialspoint
ここで出てきた命令一覧:
- CMD | Dockerfile reference | Docker Documentation
- ENTRYPOINT | Dockerfile reference | Docker Documentation
bundle install
の前にGemfile.lock
をCOPY
する理由このようにしないと、イメージを再ビルドしたときに、
Rails アプリケーションが開発時とは異なる動作や不具合を起こす可能性があります。
開発時とは異なるバージョンの Gem パッケージを使って動作することになる可能性があるためです。Gemfile と Gemfile.lock は、どちらもインストールする Gem パッケージを管理するためのファイルですが、
それぞれ次のように扱います:
Gemfile
- 開発者が目的に合わせて内容を編集します
- プロジェクトが直接呼び出す Gem パッケージを定義します
- 特別な理由がない限りバージョンを固定しません
Gemfile.lock
- 開発者が直接編集せず、
Gemfile
の内容をもとにコマンドでコンパイルして更新します- プロジェクトが直接呼び出さない Gem パッケージも含めた、すべての必要な Gem パッケージが定義されます
- すべてのパッケージがバージョンまで固定されています
bundle install
コマンドを実行したとき、Gemfile.lock
がなく、Gemfile
のみが存在すると、
Gemfile
で指定されている Gem パッケージの最新バージョンがインストールされます。
Gemfile.lock
が存在し、Gemfile
に特に更新がなければ
Gemfile.lock
の内容に従って、開発時と同じバージョンの Gem パッケージがインストールされます。参考:
- Summary | Bundler: The best way to manage a Ruby application's gems
- bundle install | Bundler: The best way to manage a Ruby application's gems
nodejs
をインストールする理由Rails は JavaScript 実行環境である Node.JS を利用しており、
nodejs
をインストールしていないと、Rails Server 実行時に次のようなエラーが発生します:web_1 | /usr/local/bundle/gems/execjs-2.7.0/lib/execjs/runtimes.rb:58:in `autodetect': Could not find a JavaScript runtime. See https://github.com/rails/execjs for a list of available runtimes. (ExecJS::RuntimeUnavailable)
どうして再ビルドが必要なの?
rails new
コマンドで上書きされたGemfile
には、
Rails 本体の他にも Rails アプリケーションを動作させるために必要な多くのパッケージが記載されています。しかし、先ほどの
docker-compose run
コマンドでビルドされたイメージには、
Rails 本体しかインストールされていません。
これは、docker-compose run
コマンドでビルドを行ったときのGemfile
には Rails しか記述されていなかったためです。なお、ここで次のような記述があります:
This, and changes to the Gemfile or the Dockerfile, should be the only times you’ll need to rebuild.
この意味についてはすべての手順を終えた後で解説しますので、
学習効率を考慮して、ひとまず次の手順に進むことをお奨めします。Connect the database
ここでは 2 つの設定を行っています:
- Rails アプリケーションのデータベース接続設定を
db
サービスに接続できるように変更db
サービスに Rails アプリケーションが利用するデータベースを新規作成Rails アプリケーションのデータベース接続設定を
db
サービスに接続できるように変更手順 2. Build the project で生成された
config/database.yml
のdefault: &default
に次の要素を追加します:config/database.ymlhost: db username: postgres password: passwordこの設定を行わずに
docker-compose up
を実行しても、ブラウザーでアクセスすると次のようなエラーが表示されます:PG::ConnectionBad could not connect to server: No such file or directory Is the server running locally and accepting connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?このエラーメッセージは、Rails アプリケーションが
ローカルに PostgreSQL が起動している前提で接続しようとして失敗していることを示しています。この場合、
config/database.yml
を更新してブラウザーを再読み込みするだけではエラーは解消しません。
これは、Rails がデータベース接続設定を読み込むのは Rails Server の起動時であるためです。
データベース接続設定を読み込み直すためには、
ターミナルでCtrl + C
を入力してコンテナーを停止し、docker-compose up
を再度実行します。
db
サービスに Rails アプリケーションが利用するデータベースを新規作成
docker-compose.yml
があるディレクトリーでもう 1 つターミナルを開き、次のコマンドを実行します:docker-compose run web rake db:create
この設定を行わずに
docker-compose up
を実行しても、ブラウザーでアクセスすると次のようなエラーが表示されます:ActiveRecord::NoDatabaseError FATAL: database "myapp_development" does not existView the Rails welcome page!
次のような画面が表示されましたでしょうか?:
この後の開発フローについて
Stop the application
この Quickstart では、アプリケーションを停止するときは、docker-compose down の利用が奨められています。
この記事に従ってdocker-compose.yml
を修正した場合、
docker-compose down
を実行すると、データベースの内容にアクセスできなくなります。データベースの内容を保持したいときは、
docker-compose up
を行ったターミナルでCtrl + C
を入力するか、
別のターミナルで docker-compose stop を実行すると、次に起動したときもデータベースの内容は保持されます。基本的には、開発のためのデータを保持する必要がある場合は PC 内に残すのではなく、
factory_bot をはじめとする
データベースフィクスチャー
を定義するための Gem パッケージを使ってコードに残します。
データの再利用の必要性を感じたら、コードに残す習慣をつけましょう。Rebuild the application
ここでは、イメージの再ビルドが必要な場合について述べられています。
ここで述べられている「イメージの再ビルドが必要な場合」とは、
「開発者が開発中に再ビルドを行うこと」を指しており、
「本番環境にデプロイするためのイメージをビルドすること」は指していません。このことを理解するために、まずは「本番環境にデプロイするためのイメージをビルドすること」を考えてみます。
本番環境にデプロイするためのイメージのビルド
手順 1. Define the project で
Dockerfile
コメントアウトしていた場合は、COPY . /myapp
をコメントインします:DockerfileFROM ruby:2.5 RUN apt-get update -qq && apt-get install -y nodejs RUN mkdir /myapp WORKDIR /myapp COPY Gemfile /myapp/Gemfile COPY Gemfile.lock /myapp/Gemfile.lock RUN bundle install COPY . /myapp # Add a script to be executed every time the container starts. COPY entrypoint.sh /usr/bin/ RUN chmod +x /usr/bin/entrypoint.sh ENTRYPOINT ["entrypoint.sh"] # Start the main process. CMD ["rails", "server", "-b", "0.0.0.0"]
COPY . /myapp
は Rails アプリケーションのコードをビルドしたイメージに含めます。
本番環境では GitHub などのバージョン管理リポジトリーからコードをデプロイするのではなく、
Docker Hub などのDocker レジストリー
から事前にビルドしたイメージをデプロイすることを想定しています。参考: Docker Registry | Docker Documentation
Gemfile
,Gemfile.lock
と一緒に一度にCOPY
してはいけないの?
Gemfile
,Gemfile.lock
とCOPY
を分けているのは、bundle install
に時間がかかるためです。Docker イメージのビルドは、命令毎に結果がキャッシュされるので、
変更の可能性が低い命令、実行に時間がかかる命令は
なるべくDockerfile
の上に記述した方が再ビルド時の効率が良くなります。
COPY . /myapp
以降の命令はそれほどビルドに時間がかかりません。
もし、/myapp
をGemfile
,Gemfile.lock
と一緒に一度にCOPY
していた場合、
COPY . /myapp
以降の命令を再ビルドしたいときであっても、
Rails アプリケーションのコードを更新しているとbundle install
が実行されることになり
ビルドに時間がかかってしまいます。開発者が開発中に再ビルド
Quickstart では、手順 2. Build the project で
この Docker を使った Rails 開発のワークフローに関する重要なことが述べられていまました:This, and changes to the Gemfile or the Dockerfile, should be the only times you’ll need to rebuild.
これは、日本語訳すると、大体次のような意味です:
このときと、
Gemfile
もしくはDockerfile
を変更したときだけが、再ビルドが必要なタイミングとなるはずです。これは、
docker-compose.yml
のvolume
で/myapp
をホストからbind
マウントしているので
開発のためにコンテナーを起動したとき、イメージに含めた Rails アプリケーションのコードではなく
ホスト側の最新の Rails アプリケーションのコードが実行されるためです。Q & A
Docker 公式ドキュメントの Quickstart に関する質問
rails new
コマンドでファイルが生成されたログが出力されるのに、実際にファイルが生成されませんWindows 10 でバージョンが 1709 までだと、
Docker Compose で相対パスを指定したときに想定通りにマウントされない不具合があるようです。
Windows Update の適用をおすすめします。
Ruby on Rails - dockerでRuby on Railsコンテナ起動時、Could not find public_suffix-4.0.5 in any of the sources エラー|teratailディレクトリーの名前を
myapp
以外に変更するとrails new
コマンド実行時にエラーが発生します正確にすべてのディレクトリー名を変更すればエラーは発生しません。
どこかで書き換えを誤っていないか確認しましょう。
Ruby on Rails - ローカルディレクトリにrails newをしてもファイルが存在しない|teratailDocker と Rails による Web サービス実行に関する質問
エラーメッセージの意味が何を指しているのかわかりません
複数のサービスを起動するときはコンテキストとなるディレクトリーを分けて設計していますか?
コンテキストとなるディレクトリーを分けると、原因の範囲が狭まり調査しやすくなります。
Ruby on Rails - Docker + Railsの No such file or directory エラーの解決方法について|teratailパッケージが足りないエラーが表示されるので gem install しても直りません
Docker が動いているコンピューターに gem をインストールしていませんか?
gem
のインストールはコンテナ内で行う必要があります。
Ruby on Rails - docker-compose upがうまくいかない|terataildb サービス以外のデータベースに接続したいです
Rails の
database.yml
と環境変数でデータベース接続情報を変更して起動します。
MySQL - [Docker, Rails, Nginx, MySQL, EC2]docker-compose run app rails db:createするとエラーが出る。|teratailmulti-stage builds にしたら bundle: not found でイメージがビルドできなくなりました
ベースイメージが Ruby のイメージではないステージで
ruby
やbundler
を使おうとしていませんか?
Ruby on Rails - "docker-compose build"実行時のエラー "Service 'web' failed to build: The command '/bin/sh -c bundle instal"|teratailGemfile はあるのに bundle install すると Could not locate Gemfile というエラーメッセージが表示されます
コマンドは Docker が動いているコンピューターで実行しているか、
それともコンテナの中で実行しているのかを確認し、
そこにGemfile
があるかを確認しましょう
GitHub - Dockerを用いたローカル環境構築で、Could not locate Gemfileが表示される|teratailDockerで起動したサーバーにlocalhost:3000でアクセスすると「このページは動作していません。」と表示されます
Docker で起動した web サービスのログを確認して、ログが増えるかどうかを確認します。
増えなければ、ファイアウォールの問題などの可能性があります。
MySQL - dockerで起動したサーバーにlocalhost:3000でアクセスしようとするが「このページは動作していません。」と返ってくる|teratail
- 投稿日:2020-08-06T19:24:03+09:00
docker-composeでjenkins構築
目的
「Docker/Kubernetes実践コンテナ入門」を読んでいて、
手順通りでは進まない箇所があったのでエラーを出さず進めるために書きます。修正箇所
コメントアウトで修正箇所と気になったとことをメモしています。
docker-compose.ymlversion: "3" services: master: container_name: master # jenkins:2.60.3からjenkins/jenkins:ltsに修正します。 image: jenkins/jenkins:lts ports: - 8080:8080 volumes: - ./jenkins_home:/var/jenkins_home links: - slave01 slave01: container_name: slave01 # slaveのイメージはこのままでOK。 image: jenkinsci/ssh-slave environment: # id_rsa.pubのキーをコピーします。 - JENKINS_SLAVE_SSH_PUBKEY=ssh-rsa AXXXXXXXX気になって調べた所
imageの取得元であるDockerHubのjenkins公式ページに行くと、使い方が書いてありました。
To use the latest LTS: docker pull jenkins/jenkins:lts
jenkinsci/ssh-slaveはそのままで使えました。
slaveの方もこのままで良いのか疑心暗鬼になったので、調べたら
DockerHubにページが有りました。
- 投稿日:2020-08-06T18:05:04+09:00
【Docker for Windows】コンテナ内で急にnpmコマンドが使えなくなった
環境
コンテナ内
Node.js npm 14.6.0 6.14.6 Docker desktop(Windows10)
困ったこと
WindowsのDocker環境でLaravel6+Vue.jsの開発をしている際、特にソースを変更していないにも関わらず
npm run dev
で以下のエラーが出るようになりました。root@e11dd10f07d4:/var/www/html# npm run dev npm ERR! code ENOSYS npm ERR! syscall read npm ERR! errno -38 npm ERR! ENOSYS: function not implemented, read npm ERR! A complete log of this run can be found in: npm ERR! /root/.npm/_logs/2020-08-06T08_36_06_323Z-debug.logコンテナを再起動しても事象は変わらず、
npm install
も同じエラーで実行不可です。解決策
タスクトレイの?から
Restart...
を押下してDocker desktopを再起動すると、コンテナ内で上記エラーが発生しなくなりました。参考
コンテナの中で身に覚えのないエラーが起きた場合はとりあえず再起動するのも手かもしれないです。
https://github.com/docker/for-win/issues/5955
- 投稿日:2020-08-06T15:18:28+09:00
【dokcer】EC2インスタンスでnginxとphp-fpmコンテナを連携させる
概要
EC2インスタンス上でdockerとdocker-composeをインストールして動かす方法メモ
OS: amazonLinux2ゴール
EC2のEIPに直アクセス(LB通さない)してphpinfoを見られる
dockerインストール
インストール -> 起動 -> ec2-userでも動かせるように権限調整
$ sudo su - # yum update -y # amazon-linux-extras install -y docker # systemctl enable docker # systemctl start docker # usermod -aG docker ec2-userdocker-composeインストール
docker-composeのバージョンは適時調整する
バージョン情報まで表示できたらOK!# curl -L https://github.com/docker/compose/releases/download/1.24.1/docker-compose-Linux-x86_64 -o /usr/local/bin/docker-compose # chmod 755 /usr/local/bin/docker-compose # docker-compose -v docker-compose version 1.24.1, build 4667896bnginxコンテナを作ってアクセス確認
以下はec2-userで操作
$ mkdir project $ cd project/ $ mkdir -p docker/nginx $ vi docker/nginx/Dockerfile $ vi docker-compose.yml $ docker-compose up -d EIPにアクセスして「welcome to nginx」が見れればOK!docker/nginx/DockerfileFROM nginx:alpine ENV LANG ja_JP.UTF-8docker-compose.ymlversion: "3" services: nginx: build: ./docker/nginx ports: - 80:80nginxコンテナに自前のindex.htmlを用意
$ vi docker/nginx/index.html $ vi docker/nginx/Dockerfile $ docker-compose --log-level CRITICAL down --rmi all --volumes $ docker-compose up -d EIPにアクセスして用意したhtmlファイルに変わっていればOKdocker/nginx/index.html<!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Hogehoge</h1> <p>Hogehoge</p> </body> </html>docker/nginx/DockerfileFROM nginx:alpine ENV LANG ja_JP.UTF-8 ADD ./index.html /usr/share/nginx/html/index.htmlphp-fpmコンテナを用意
nginxとの連携はまだ、とりあえずphp-fpmコンテナを立ち上げてphpが動かせることまで確認
$ mkdir -p docker/php-fpm $ vi docker/php-fpm/Dockerfile $ vi docker-compose.yml $ docker-compose --log-level CRITICAL down --rmi all --volumes $ docker-compose up -d $ docker-compose exec php-fpm sh ※php-fpmコンテナで実行して、バージョン情報が表示されればOK /var/www/html # php -v PHP 7.1.33 (cli) (built: Oct 25 2019 07:25:49) ( NTS ) Copyright (c) 1997-2018 The PHP Group Zend Engine v3.1.0, Copyright (c) 1998-2018 Zend Technologiesdocker/php-fpm/DockerfileFROM php:7.1-fpm-alpine ENV LANG ja_JP.UTF-8nginxコンテナとphp-fpmコンテナを連携
$ vi index.php $ cp index.php docker/nginx $ cp index.php docker/php-fpm $ vi docker/nginx/Dockerfile $ vi docker/php-fpm/Dockerfile $ vi docker/nginx/default.conf $ vi docker-compose.yml $ docker-compose --log-level CRITICAL down --rmi all --volumes $ docker-compose up -d EIPにアクセスしてphpinfoが表示されればOK!index.php<?php echo 'hogehoge'; phpinfo();docker/nginx/DockerfileFROM nginx:alpine ENV LANG ja_JP.UTF-8 ADD ./index.php /project/index.php ADD ./default.conf /etc/nginx/conf.d/default.confdocker/php-fpm/DockerfileFROM php:7.1-fpm-alpine ENV LANG ja_JP.UTF-8 ADD ./index.php /project/index.phpdocker/nginx/default.confserver { listen 80; server_name _; root /project; index index.php; location / { try_files $uri $uri/ /index.php$is_args$args; } location ~ \.(php|xml)$ { fastcgi_pass php-fpm:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name; include fastcgi_params; } }docker-compose.ymlversion: "3" services: nginx: build: ./docker/nginx ports: - 80:80 depends_on: - php-fpm php-fpm: build: ./docker/php-fpm
- 投稿日:2020-08-06T11:38:13+09:00
Dockerで最速Django、MariaDB、Gunicornの開発環境構築
docker-composeを用いて、DJangoの開発環境を整える、docker-compose.ymlを自分で作成しました。
https://github.com/yuta-hidaka/Docker-Django-MariaDB-Gunicorn
こちらを使って、Djangoの開発環境を整えます。
目次
1.レポジトリのクローン
2.設定ファイル(.env)/Requirements.txtのコピー
3.イメージのbuild
3.localhostにアクセス
4.settings.pyを編集
5.ご意見募集中!!!
5.おわりに1. レポジトリのクローン
git clone https://github.com/yuta-hidaka/Docker-Django-MariDB-Gunicorn.git/ hogehoge2. 設定ファイル(.env)/Requirements.txtのコピー
.envで必要な情報を書き換えてください
requirements.txtで必要なmoduleを調整してくださいcd hogehoge cp .env.sample .env cp django_data/requirements.txt.sample django_data/requirements.txt3. イメージのbuild
cd hogehoge docker-compose up --build4. localhostにアクセス
5. settings.pyを編集
接続先をMariaDBに変更し、Djnagoの初期設定に従って進んでください。
6. ご意見募集中!!!
Docker初心者が作ったファイルのため、改善意見や、これはダメなんじゃない?
といった意見をお待ちしています!!
- 投稿日:2020-08-06T10:39:17+09:00
コンテナレジストリ上にPREN(PostgreSQL、ReactJS、Express、NodeJS)アプリのCI/CDを設定する
このガイドでは、Alibaba Cloudのコンテナレジストリを使用してPREN(PostgreSQL, ReactJS, Express, NodeJS)アプリケーション用のCICDパイプラインをセットアップします。
本ブログは英語版からの翻訳です。オリジナルはこちらからご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。
Alibaba Cloud Tech Share執筆者 テミダヨ・オイェデレ(Temidayo Oyedele)著 Tech Shareは、技術的な知識やベストプラクティスをクラウドコミュニティ内で共有することを奨励するAlibaba Cloudのインセンティブプログラムです。
Jenkinsは、自己完結型のオープンソース自動化サーバであり、ソフトウェアの構築、テスト、配信、デプロイに関連するあらゆる種類のタスクを自動化するために使用することができます。
Jenkinsは、ネイティブシステムパッケージ、Dockerを通じてインストールすることができ、Javaランタイム環境(JRE)がインストールされているマシンであれば、スタンドアロンでも実行することができます。
Dockerは、開発者やシステム管理者がコンテナを使ってアプリケーションを開発、デプロイ、実行するためのプラットフォームです。Linuxのコンテナを使ってアプリケーションをデプロイすることをコンテナ化と呼びます。コンテナは新しいものではありませんが、アプリケーションを簡単にデプロイするための使用は新しいものです。
このガイドでは、PREN (PostgreSQL, ReactJS, Express, NodeJS) アプリケーションのための継続的インテグレーションとデプロイのパイプラインを設定します。Jenkinsを使用してGitHub上のコード変更を検出し、継続的なデリバリを行い、PRENアプリはDockerを使用してコンテナ化し、Alibaba Cloud Container Registryにプッシュします。今回使用するPRENアプリはこちらのGitHubでホストされています。
前提条件と要件
1、アリババクラウドのアカウント
2、新たにデプロイされたAlibaba Cloud Ubuntu 16.04 64ビットサーバーインスタンス
3、最低2GBのRAM(Docker化されたアプリサイズのため2GBを強く推奨
4、最低20GBのディスク容量(ただし40GBを推奨)
5、インスタンス・セキュリティ・グループはポート8080での侵入を許可しなければなりません。
6、Alibaba Cloud Elastic Container Registryのリポジトリステップ1:Jenkinsの設定
Alibabaクラウドのエラスティックコンピュートサービス上にJenkinsサーバをセットアップします。Alibaba Cloud ECSコンソールにログインします。インスタンスが起動していない場合は、こちらのリンクをクリックしてAlibaba Cloudのコンピュートサービスを起動させます。
JenkinsをインストールするにはJava実行環境(JRE)が必要なので、まずはそれをインストールします。
Javaプログラムのコンパイルなどが必要になることもあるので、Java実行環境も含まれているJDK(Java開発キット)をインストールするのが良いと思います。唯一の欠点はサイズが大きくなることです。
SSHキーペアを使用してローカルターミナルからECSインスタンスにSSHするか、設定や好みの方法に応じてVNCコンソール経由でログインし、以下の手順でJenkinsをインストールします。
Oracle PPAを追加し、以下のコマンドを実行してパッケージインデックスを更新します。
sudo apt-get update sudo apt-get install software-properties-common sudo add-apt-repository ppa:webupd8team/java sudo apt-get updateあとでadd-apt-repositoryを使うことができるように、ソフトウェアのプロパティの共通部分をインストールする必要があります。最後に、JDK 8を実行してインストールします。
sudo apt-get install oracle-java8-installer注意:Jenkinsは特にJavaのバージョン8がインストールされている必要があります。
以下のコマンドでリポジトリキーをシステムに追加します。
wget -q -O - https://pkg.jenkins.io/debian/jenkins-ci.org.key | sudo apt-key add -次に、Debian パッケージのリポジトリのアドレスをサーバの sources.list に追加します。
echo deb https://pkg.jenkins.io/debian-stable binary/ | sudo tee /etc/apt/sources.list.d/jenkins.listこの両方が揃ったら、apt-getが新しいリポジトリを使うようにupdateを実行します。
sudo apt-get update最後にJenkinsとその依存関係をインストールします。
sudo apt-get install jenkinsserviceを使って、Jenkinsを起動します。
sudo service jenkins startJenkinsのステータスは以下のコマンドで確認できます。
sudo service jenkins status出力の中にJenkinsのオートメーションサーバのようなものが実行されているのがわかるはずです。
次に、Jenkinsのウェブコンソールからインストールの設定を行います。http://internet_ip_address_of_your_instance:8080 にアクセスして Jenkins のウェブコンソールに移動します。ポート8080はJenkinsのデフォルトポートです。
すると「Unlock Jenkins」というページが表示されるはずですが、そこには初期パスワードの場所が赤文字で表示されています。これに似たようなものが表示されます。
VNCターミナルまたはECSインスタンスにログインしたローカルターミナルウィンドウに移動して、パスワードを表示するために
cat
コマンドを使用します。sudo cat /var/lib/jenkins/secrets/initialAdminPasswordターミナルから出力された32文字の英数字のパスワードをコピーして、Jenkinsコンソールの「Administrator password」欄に貼り付け、「Continue」をクリックします。次の画面では、提案されたプラグインをインストールするか、特定のプラグインを選択するかのオプションが表示されます。ここでは、提案されたプラグインをインストールするオプションを選択することにします。
インストールが完了すると、最初の管理ユーザーを設定するように促されます。このステップをスキップして、上で使用した初期パスワードを使用して管理者として続行することも可能ですが、ユーザーを作成するために少し時間がかかります。
覚えておく必要がある詳細を記入し、保存して次に進みます。
この段階では、このようなページが表示されるはずです。
Save and Finishをクリックし、次のページでStart using Jenkinsをクリックします。ダッシュボードにリダイレクトされます。この段階でインストールは完了です。
ステップ2:Dockerのセットアップ
まだVNCまたはあなたのターミナル/コマンドプロンプトからECSインスタンス上で。有効なdockerダウンロードを確実に取得するために、公式DockerリポジトリのGPGキーをシステムに追加します。
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -APTソースにDockerリポジトリを追加します。
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"次に、新しく追加したリポジトリのDockerパッケージでパッケージデータベースを更新します。
sudo apt-get update最後に、このコマンドでDockerをインストールします。
sudo apt-get install -y docker-ceこれでDockerがインストールされ、デーモンが起動し、起動時にプロセスが起動するようになったはずです。を使って実行していることを確認してください。
sudo service docker statusステップ3: JenkinsでGitHubのWebhookを設定する
WebブラウザからJenkinsダッシュボード「http://ECS_URL:8080」
にアクセスし、新規項目をクリックして新規Jenkinsジョブを作成します。適切な名前を入力し、フリースタイルプロジェクトを選択し、OKをクリックして次のページに移動します。次のページでは、ビルドトリガーの下で、トリガーのビルドをリモートで行うボックスにチェックを入れてください(例:スクリプトから)、認証トークンを提供する必要があります。自分にとっては覚えやすく、他の人にとってはかなり難しいであろう、任意のトークンを記入してください(パスワードのようなもの)。このトークンは、Jenkinsサーバーへのプッシュイベント(ここではGitHubから)を行うために必要です。入力欄の下にあるURLに注目してください。ビルドURLと呼ぶことにしますが、これは後ほどGitHubのwebhookに必要になります。
ビルドセクションでは、ドロップダウンから[ビルドステップの追加]と[シェルの実行]を選択します。テキストエリアに以下のコマンドを貼り付けます。
set +x if [ -d HelloBooks-Alibaba ]; then rm -rf HelloBooks-Alibaba; fi git clone https://github.com/babadee001/HelloBooks-Alibaba cd HelloBooks-Alibaba sudo docker build -t hellobooks . sudo docker login --username=yourusername registry-intl.yourregion.aliyuncs.com -p $password sudo docker tag [ImageId] registry-intl.yourregion.aliyuncs.com/yournamespace/yourrepositoryname:[tag] sudo docker push registry-intl.yourregion.aliyuncs.com/yournamespace/yourrepositoryname:[tag]私が使用しているサンプルプロジェクトでこのガイドに従っている場合、最初の5つのコマンドはそのままにしておいて、それ以外の場合は適宜修正してください。次の3つのコマンドは、Alibaba ECR (Elastic Container Registry) リポジトリから直接取得したものです。これについては、ECRを設定する次のステップ(ステップ4)で詳しく説明します。
Set +xは、コマンドとその引数が印刷されたり、ターミナルに返されたりしないことを確認します。次の行では、プロジェクトフォルダが存在するかどうかをチェックし、真であれば削除します。これにより、常に更新されたレポフォルダがあることを確認します。次に、レポをクローンして、プロジェクトフォルダかディレクトリにcd(ディレクトリ変更)します。その後、イメージをビルドするためのdockerコマンドを実行します。
最後に、Jenkinsジョブを保存する前に、環境変数を追加する必要があります。Build Environmentの下のUse secret text(s) or file(s)ボックスにチェックを入れます。新しいセクションがそのすぐ下に表示されます(Bindings)。変数フィールドに秘密のテキストの名前を入力します。Add」ドロップダウンをクリックし、「secret text」を選択します。追加]をクリックし、[Jenkins]をクリックします。kindをsecret textに変更し、ECR Dockerのログインパスワードを貼り付けます。IDフィールドを記入します(この名前は、後でシークレットファイルを参照するために使用するものになるので注意してください。保存します。
GitHub、Gitlab、Bitbucket などのような多くのソースコードホスティングサービスは、新しいコミットがリポジトリにプッシュされたときにウェブフックを送信する機能を持っています。ウェブフックは通常、JSONペイロードを含むHTTP POSTリクエストです。
デフォルトでは、Jenkins 2.x以降では「Prevent Cross Site Request Forgery exploits」というセキュリティ機能が有効になっており、有効な「crumb」トークンが関連付けられていないすべてのPOSTリクエストを拒否します。これは素晴らしいセキュリティ機能です。
ほとんどの Git ホスティングサービスには crumb を取得したり処理したりする仕組みがないので、デフォルトの設定で Jenkins をインストールした場合には、POST リクエストがブロックされてしまいます。"Prevent Cross Site Request Forgery exploits" を手動で無効にするか、サービス固有のプラグインをインストールする必要があります。
Bitbucket や GitHub のような多くの一般的なホスト用に作られたプラグインで、Crumb Exclusions を提供しています。これらのプラグインは CSRF が有効になっていることを確認し、プッシュ通知を行うことができますが、このチュートリアルの目的のために、サードパーティ製のプラグインをインストールするのではなく、手動で CSRF を無効にします。
JenkinsダッシュボードでCSRFを無効にするには、Jenkinsダッシュボードからmanage Jenkinsをクリックし、グローバルセキュリティを設定します。Authorizationの下で上にスクロールし、Logged-in users can do anythingを選択し、Allow anonymous read accessボックスにチェックを入れます。続けて上にスクロールすると、CSRF保護が表示されるはずなので、チェックを外します。保存して、これで完了です。
最後に、イメージをコンテナレジストリに送信するためのdockerコマンドにはsudoer権限が必要なので、Jenkinsユーザにsudo権限を与える必要があります。これは、以下のコマンドを実行して sudoers ファイルを修正することで行うことができます。
visudo -f /etc/sudoersそして、ファイルの最後に以下の行を追加して保存します。
jenkins ALL= NOPASSWD: ALLGitHub のリポジトリに移動し、左のナビゲーションペインから設定タブをクリックして webhooks をクリックします。
「add webhook」をクリックして Jenkins の webhook を作成します。ペイロードのURLは、ステップ3のJenkinsビルドのURLになります。Just the pushイベントボックスにチェックを入れます。このチュートリアルの目的のために、私たちはちょうどそれを行います。Let me select individual events boxを選択することで、プロジェクトに合ったイベントを探索して設定することができます。次に、作成するWebhookを追加をクリックします。これで、このリポジトリに変更(プッシュ)があったときに、Jenkinsジョブがビルドできるようになります。
ステップ4:コンテナレジストリの設定
ECR ダッシュボードに移動し、管理をクリックします。リポジトリセクションのプッシュイメージまでスクロールします。以下のようなものが表示されるはずです。
sudo docker login --username=yourusername registry-intl.yourregion.aliyuncs.com sudo docker tag [ImageId] registry-intl.yourregion.aliyuncs.com/yournamespace/yourrepositoryname:[tag] sudo docker push registry-intl.yourregion.aliyuncs.com/yournamespace/yourrepositoryname:[tag]先ほどのJenkinsジョブでビルドステップに追加したものです。
この段階では、アプリケーションに簡単な変更を加えてGitHubにプッシュすることで、全体のセットアップをテストすることができます。GitHubは変更内容をJenkinsに通知し、JenkinsジョブはdockerイメージをビルドしてECRリポジトリに送信します。これはECRリポジトリのダッシュボードで確認できます。管理をクリックしてからタグをクリックします。
結論
これで、すべての設定と実行が完了しました。
ECRにログインしてイメージを取り出し、アプリケーションを起動すると、8000番ポートで動作します。また、KubernetesやSwarmのようなコンテナクラスタにデプロイすることもできます。
アリババクラウドは日本に2つのデータセンターを有し、世界で60を超えるアベラビリティーゾーンを有するアジア太平洋地域No.1(2019ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
アリババクラウドジャパン公式ページ
- 投稿日:2020-08-06T10:10:14+09:00
AlibabaクラウドにJenkins Slave Poolを実装してCI/CDパイプラインのプロビジョニングを可能にする方法
この記事では、動的で並列なCI/CDパイプラインのプロビジョニングを可能にするAlibaba Cloud上に分散型でDocker化されたJenkins Slave Poolを実装する方法を共有しています。
本ブログは英語版からの翻訳です。オリジナルはこちらからご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。
ハイブリッドCI/CDとは
ハイブリッドCI/CDは、オンプレミスとパブリッククラウドを組み合わせた分散型のプラットフォームで、CI/CDを目的としています。ハイブリッドCI/CDは、基本的にプライベートクラウドとパブリッククラウドの間でワークロードを制御し、ニーズとコストのバランスを取ります。
高レベルでは、以下の図のようなアーキテクチャになっています。
ハイブリッドCI/CDのメリット
スケーラビリティと柔軟性
オンプレミスでも一定レベルのスケーラビリティは提供されていますが、これはデータセンターごとのものであり、予算に大きく依存します。また、あるシステムが予想以上にリソースを消費すると、他のすべてのシステムに影響が出ることがよくあります。そのため、予算の境界線をどのように設定するかが厄介な問題となります。パブリッククラウドサービスでは、より大きなクラウドインフラでより大きなスケーラビリティを提供することができます。CI/CDのジョブは通常、分離された短命のものであり、一般的にステートレスであることを考慮すると、パブリッククラウドサービスの方が拡張性が高く、CI/CDジョブをパブリック・クラウドに移行することで、組織はコア・サービスのためにスケーラビリティを確保することができます。
費用対効果
パブリッククラウドの方が、集中管理のコストをすべてのユーザーが共有するため、経済的な費用対効果が高くなる可能性が高くなります。
セキュリティ
純粋なパブリッククラウドソリューションと比較して、Hybrid CI/CDは、適用可能なCI/CDジョブにのみアクセスできるようにデータを常に制限することができるため、セキュリティ要求に対する感受性を確保しています。
Dockerがビルドスレーブとしてホストする理由
リソースの利用
Dockerがリソースを動的に割り当ててくれるので、複数のJenkins Slavesを並行して走らせることができます。これにより、CI/CDパイプラインのスループットが飛躍的に向上します。
アイソレーション
Dockerは、アプリケーションとリソースが分離・分離されていることを保証します。Jenkins Slaveが本当に徹底的にクリーンアップするかどうかを気にすることなく、ターゲットコンテナを破棄するだけでよいのです。
環境の標準化
標準イメージを継承したCI/CD環境を簡単に構築できます。
Jenkinsスレーブコンテナの実装
Jenkins MasterからJenkins Slavesへの通信プロトコルは2種類あります。Java Web Start(別名JNLP)とSSHです。SSH は Blocking I/O で暗号化されているため、スケーラビリティが制限されますが、ロードバランサへの依存度が低いため、最も一般的な方法です。そこで今回はsshスレーブの種類についてのみ解説します。
Jenkikikns Slave の docker イメージはプロジェクトによって環境が異なる場合があるので、具体的にビルドすることをお勧めします。https://github.com/jenkinsci/docker-ssh-slave に素晴らしい例が掲載されていますので、参考にしてみてください。
DockerfileFROM openjdk:8-jdk LABEL MAINTAINER="Nicolas De Loof <nicolas.deloof@gmail.com>" ARG user=jenkins ARG group=jenkins ARG uid=1000 ARG gid=1000 ARG JENKINS_AGENT_HOME=/home/${user} ENV JENKINS_AGENT_HOME ${JENKINS_AGENT_HOME} RUN groupadd -g ${gid} ${group} \ && useradd -d "${JENKINS_AGENT_HOME}" -u "${uid}" -g "${gid}" -m -s /bin/bash "${user}" # setup SSH server RUN apt-get update \ && apt-get install --no-install-recommends -y openssh-server \ && rm -rf /var/lib/apt/lists/* RUN sed -i /etc/ssh/sshd_config \ -e 's/#PermitRootLogin.*/PermitRootLogin no/' \ -e 's/#RSAAuthentication.*/RSAAuthentication yes/' \ -e 's/#PasswordAuthentication.*/PasswordAuthentication no/' \ -e 's/#SyslogFacility.*/SyslogFacility AUTH/' \ -e 's/#LogLevel.*/LogLevel INFO/' && \ mkdir /var/run/sshd VOLUME "${JENKINS_AGENT_HOME}" "/tmp" "/run" "/var/run" WORKDIR "${JENKINS_AGENT_HOME}" COPY entrypoint.sh /usr/local/bin/entrypoint.sh EXPOSE 22 ENTRYPOINT ["entrypoint.sh"]Jenkins
Slave entrypoint.sh
#!/bin/bash -ex write_key() { mkdir -p "${JENKINS_AGENT_HOME}/.ssh" echo "$1" > "${JENKINS_AGENT_HOME}/.ssh/authorized_keys" chown -Rf jenkins:jenkins "${JENKINS_AGENT_HOME}/.ssh" chmod 0700 -R "${JENKINS_AGENT_HOME}/.ssh" } if [[ $JENKINS_SLAVE_SSH_PUBKEY == ssh-* ]]; then write_key "${JENKINS_SLAVE_SSH_PUBKEY}" fi if [[ $# -gt 0 ]]; then if [[ $1 == ssh-* ]]; then write_key "$1" shift 1 else exec "$@" fi fi # ensure variables passed to docker container are also exposed to ssh sessions env | grep _ >> /etc/environment ssh-keygen -A exec /usr/sbin/sshd -D -e "${@}"Jenkinsマスタ設定
すでにJenkins Masterを設定したことがある方を想定しています。Alibaba Cloud上で新規に構築する場合は、以下の三部作の記事も参考にしてください。
- Jenkinsを使ったCI/CD - Part 1: UbuntuにJenkinsをインストールする
- Jenkinsを使ったCI/CD - Part 2:継続的インテグレーションにJenkinsを使う
- Jenkinsを使ったCI/CD - Part 3:継続的なデリバリにJenkinsを使う
その後、Jenkins Dashboard / Manage Jenkins / Manage Pluginsに移動し、"Docker Plugin "を検索してインストールします。
次に、Jenkins Dashboard / Manage Jenkins / Configure systemに移動し、dockerの下のDocker URLにECSのパブリックIPアドレスとdockerリモートAPIのポートを記入します。デフォルトでは
2375
です。test connection "ボタンがあるので、接続が成功するかどうか試してみることができます。その後、「Add Docker Template」を選択し、「docker template」をクリックします。そして、以下のように詳細を記入します。
- Dockerイメージ: jenkinsci/ssh-slave
- リモートファイリングシステムのルート:/home/jenkins
- ラベル: ssh-slave
- 証明書: the public key you have injected for ssh-slave container
すべての設定が完了したら、「保存」ボタンをクリックします。
テスト構成
「New item」に移動し、「ssh-slave-test」という名前の
フリースタイル
プロジェクトを作成します。「Restrict」の下に、スレーブテンプレートで与えたラベル名を入力します。ここでは「ssh-slave」とします。
Build で execute shell オプションを選択し、以下のように echo 文を入力します。
echo "hello {JOB_NAME}"このジョブを保存して「今すぐビルド」をクリックすると、以下のような出力が得られるはずです。
hello ssh-slave-test次やることは?
上記のすべてが終わったら、コードリポジトリと統合して、実世界のCI/CDジョブを作成します。また、実際の要件に応じてdockerイメージをカスタマイズすることもできます。
アリババクラウドは日本に2つのデータセンターを有し、世界で60を超えるアベラビリティーゾーンを有するアジア太平洋地域No.1(2019ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
アリババクラウドジャパン公式ページ
- 投稿日:2020-08-06T09:12:52+09:00
docker runに失敗したコンテナにログインして、デバッグする方法
docker runが失敗したコンテナの中身を確認したい場合、
docker commit
で失敗したコンテナをイメージ化して、ログインします。docker commit <コンテナID or コンテナ名> debug && docker run --rm -it debug sh
- docker runに失敗したコンテナのコンテナIDは、
docker ps -a
で調べられます。- "debug" がコンテナイメージ名となります。不要になったら、
docker rmi debug
で消しましょう。
- 投稿日:2020-08-06T08:50:45+09:00
Docker Vue Go
Docker
Dockerマウントできないよ〜
ERROR: for nginx Cannot start service nginx: OCI runtime create failed: container_linux.go:349: starting container process caused "process_linux.go:449: container init caused \"rootfs_linux.go:58: mounting \\\"/Users/ishidashogo/practice/goPractice/etc/nginx/nginx.conf\\\" to rootfs \\\"/var/lib/docker/overlay2/ac829670cc63c6bd9749802860c0b6dd9619d56f1883525650acc81db4dc4ee1/merged\\\" at \\\"/var/lib/docker/overlay2/ac829670cc63c6bd9749802860c0b6dd9619d56f1883525650acc81db4dc4ee1/merged/etc/nginx/nginx.conf\\\" caused \\\"not a directory\\\"\"": unknown: Are you trying to mount a directory onto a file (or vice-versa)? Check if the specified host path exists and is the expected typeマウントのディレクトリが違うみたいでした。
docker-compose.ymlファイル内で指定しているvolumeの場所に指定してある
欲しいファイルがないことによるエラーみたいでした。
- 投稿日:2020-08-06T08:07:50+09:00
【ElasticSearch Operator編】Kubernetes Operatorコードリーディング
ElasticSearch Operatorとは
ElasticSearch Operatorとは、ElasticSearch向けのKubernetes Operatorであり、OpenshiftのClusterLoggingの機能の一部として動作するOperatorである。
ElasticSearchを自動運用するためのOperationがこのOperatorとして実装されている。
openshift/elasticsearch-operatorというGithubリポジトリのためOpenshiftコミュニティによりメンテされているようである。
openshift/elasticsearch-operator
【補足】elasticsearch-operatorのコード量
Goのファイルが2500強あり、コードが1000k lineにも及ぶ
❯ cloc . 3297 text files. 3170 unique files. 367 files ignored. github.com/AlDanial/cloc v 1.80 T=10.38 s (283.8 files/s, 117872.8 lines/s) -------------------------------------------------------------------------------- Language files blank comment code -------------------------------------------------------------------------------- Go 2539 81218 112652 974429 ~ -------------------------------------------------------------------------------- SUM: 2945 89341 127274 1006349 --------------------------------------------------------------------------------vendorディレクトリ内で同様に見てみると、950 k lineはvendor関連コードという風に取れるため、実質20 k lineくらいがelasticsearch-operatorのコードといえそう。
❯ cloc . 3070 text files. 2948 unique files. 343 files ignored. github.com/AlDanial/cloc v 1.80 T=7.37 s (371.4 files/s, 161408.3 lines/s) -------------------------------------------------------------------------------- Language files blank comment code -------------------------------------------------------------------------------- Go 2411 77974 111744 956992 ~ -------------------------------------------------------------------------------- SUM: 2738 85146 124716 980068 --------------------------------------------------------------------------------ElasticSearchのReconcile処理詳解
Reconcile処理概要
elasticsearchのNode(Elasticsearchクラスタのメンバ)ごとに、正常性確認を行う
Elasticsearch nodeごとにdeploymentを持っていて、そのdeploymentごとにreconcileを行う
deployment内のpodステータスを確認する際に、コンテナのステータスも確認しreconcileを行っている。
Reconcile処理に関連するコードの呼び出しフロー
主な処理の流れとしては
- controller/erlasticsearch packageのadd()関数
- controller packageのreconcileHandler経由でReconcile()関数が呼ばれ
- さらにk8shandler内のReconcile()が呼ばれ
- KubernetesのDeployment, Pod, ContainerレベルのReconcileが行われる
となっている。(図1 下記の黒矢印部分)
図1. Reconcile処理に関連するコードの呼び出しフロー図上記のコールグラフは下記のツールを使用して描画した。インタラクティブに処理を追えるが処理が重いため上記1枚に留めた。
https://github.com/ofabry/go-callvis
処理の入り口 elasticsearch package内のadd()により、Controllerを登録
add()のコード(図2)をみると、reconcilerを与えることで新しくcontrollerを追加する、という関数である。
ここでElasticSearchをReconcileするためのcontrollerが生成される。
このadd()によって追加されたcontrollerのReconcileが、いわゆるReconcilation Loopと呼ばれる、KubernetesならびにKubernetes Operatorの主な役割である。
Reconcillation Loop
Reconcile()の定義は以下に記載されている。
openshift/elasticsearch-operator
図1で示した通り、Reconcile()からk8shandler package内のReconcile()を呼び出している。(図3)
このk8shandler.Reconcile()では、主にKubernetesリソースレベルでのReconcileを行う。
具体的には、
- ServiceAccount
- RBAC
- ConfigMaps
- Prometheus向けのServiceMonitor, PrometheusRule
などがある。
また、これに加えて
- Elasticsearch Cluster
- IndexManagement
についてのReconcile処理が定義されている。
これらについて、CreateOrUpdateHoge()という関数が用意されており、該当のリソースがなければ作り、理想状態じゃなければ更新をかける処理(Reconcilation Loop)が実装されていることになる。
CreateOrUpdateHoge郡の該当のコードは下記である。
openshift/elasticsearch-operator
ここでは、メインのReconcile処理であるCreateOrUpdateElasticsearchCluster()についてさらにDeep Diveすることにする。
ElasticSearchのReconcile処理であるCreateOrUpdateElasticsearchCluster()の実装確認
ここまで説明した通り、CreateOrUpdateElasticsearchCluster()とはElasticSearchを理想状態に保つための関数である。
実際にはDeploymentとして動作するためElasticSearch Deploymentを理想状態にすることをReconcileといっても大きな齟齬はないと思われる。
具体的な処理が気になる場合は、下記の処理から追うことができる。
openshift/elasticsearch-operator
ここでは、ElasticSearchに不具合が起きた場合にどのようにPodに対してReconcileを行うのかについて注目する。
k8shandler package内のcluster.goにて、ScheduledForUpgradeを監視することで、更新が必要なノード(elasticsearchクラスタのメンバの意でありk8s nodeではない)をupgradeNodesとして記憶している。(ScheduledForUpgradeの更新のされ方は後述して補足する)
openshift/elasticsearch-operator
上記でupgradeNodeとして認識されたNodeはk8shandler.UpgradeStatus()にて、Reconcile処理が適用される。
Reconcile処理内における、具体的な実装を確認
UpdateClusterStatus() 内にて、status.go内のupdateNodeConditions()を呼ぶことで、いよいよelasticsearch Nodeごとのreconcile処理に入る
openshift/elasticsearch-operator
Podの正常性を確認
Podがスケジュールされているかを確認
「Podがscheduleされていつつ、podのConditionがFalse」となっている場合に、podをunschedulableとしてフラグ付する。
unschedulableフラグがたった場合は後続処理である、Pod内のコンテナステータスを確認していく。
該当コードは下記
openshift/elasticsearch-operator
Pod内コンテナのステータスを確認
Pod内のelasticsearchコンテナの、StateがWaitingかTerminatedかをまず確認する
この場合は、updatePodNotReadyCondition()を呼ぶことで、Podが壊れている正確なReasonとMessageを付加している。
もう1つのproxyコンテナについても同様に確認をしている。
openshift/elasticsearch-operator
ディスク使用率観点での正常性確認
コンテナの正常性確認が終わるとディスク使用量観点の確認を行う
ディスク使用量が閾値を超えているかどうかを確認し、Disk Watermark Highもしくは、Disk Watermark Lowなどに引っかかっているかを確認する。
openshift/elasticsearch-operator
まとめ
Openshiftで用いられるElastichSearch Operatorの役割について、PodのReconcile部分に焦点を当てて実装を確認した。
実際のReconcile部分に限っていうとElasticsearch特有という部分は余り目立たず、他のOperatorのコードを読む上でも同様に読み進めるための材料として読むことは有用と感じる。
Operatorhub.ioにおいてelasticsearch-operatorは公開されておらず、"Elastic Cloud on Kubernetes" Operatorが公開されているため、こちらとの関連やその差分などについても考察の余地があるが、OperatorHub.ioに登録されている方がよりデファクトであると現時点では考えられる。そのため、本記事で紹介したelasticsearch-operatorはOpenshiftに特化した内容になっていると考えるのが妥当である。
https://operatorhub.io/operator/elastic-cloud-eck
参考資料
- Elasticsearch OperatorのGoDoc
elasticsearch-operator - GoDoc
- openshift/elasticsearch-operator Github
https://github.com/openshift/elasticsearch-operator
- openshiftのcluster-loggingのリポジトリ
https://github.com/openshift/cluster-logging-operator
【補足】ScheduledForUpgradeの更新のされ方
まずk8shandler package内のdeployment.goでdeploymentの状態を監視している
openshift/elasticsearch-operator
node.isChanged()にて、純粋にdeploymentのdesiredとcurrentを比較することで、更新が必要かを判断している。
node.isChanged()がtrueとなった場合に、api.ElasticsearchNodeStatus.UpgradeStatus.ScheduledForUpgradeというフラグを立てることで、reconcilationLoop内で再起動処理をフックする仕組みになっている。
- 投稿日:2020-08-06T01:13:48+09:00
DockerでRailsチュートリアルのローカル開発環境構築(Rails 6 + PostgreSQL + Webpack)
はじめに
最新(2020.8.5現在)のRailsチュートリアルではRails 6が使用されており、
これに対応した開発環境構築をDockerでやってみたいと思います。個人開発アプリの開発環境構築の際に、
私は新しいものが好きだから...とRails 6を導入しました。ところが...このRails 6からJavaScriptのモジュールバンドラーにWebpackが導入されたことにより、
BootstrapやFontawesomeといったツールの導入、管理方法が変わるだけでなく、
そもそも環境構築の際もRails 5では必要ない手順が必要だったりと、
Rails 6とWebpackの壁に盛大にぶつかることとなりました...せっかくなので、今回の試みを経て、知識、経験の整理定着を図りたいと思います。
また、実際にRailsチュートリアルを脱線しながら再走し、学びを深められたらと思っています。
個人開発アプリ
mdClip <オンラインmarkdownエディタ>以前Rails 5の環境構築をDockerでやってみた記事
はじめてのDockerでRails開発環境構築 [NGINX + Rails 5 (puma) + PostgreSQL] - Qiita環境
- Mac OS (Mojave)
- Docker for Mac
- Ruby 2.6.3-alpine
- Rails 6.0.3
- PostgreSQL 11.0-alpine
構成ファイル
以下の5つのファイルをワークスペースに用意します
Dockerfile
,docker-compose.yml
,Gemfile
,Gemfile.lock
,entrypoint.sh
https://github.com/naokit1030/sample_app_on_docker.git
git clone -b create-docker-files https://github.com/dev-naokit/sample_app_on_docker.git
Dockerfile
イメージの軽量化のため"alpine"を使用
nodejs, yarnはWebpack導入に必要
postgresql
だけでは駄目で、postgresql-dev
も必要bundle installの-j4オプションで
bundle install
が高速化されるbundle install後、不要ファイル削除はイメージサイズの削減に貢献
FROM ruby:2.6.3-alpine ENV LANG=ja_JP.UTF-8 ENV TZ=Asia/Tokyo ENV ROOT=/myapp \ GEM_HOME=/bundle \ BUNDLE_PATH=$GEM_HOME ENV BUNDLE_BIN=$BUNDLE_PATH/bin ENV PATH /app/bin:$BUNDLE_BIN:$PATH WORKDIR $ROOT RUN apk update && \ apk upgrade && \ apk add --no-cache \ gcc \ g++ \ libc-dev \ libxml2-dev \ linux-headers \ make \ nodejs \ postgresql \ postgresql-dev \ tzdata \ yarn && \ apk add --virtual build-packs --no-cache \ build-base \ curl-dev COPY Gemfile $ROOT COPY Gemfile.lock $ROOT RUN bundle install -j4 # 不要ファイル削除 RUN rm -rf /usr/local/bundle/cache/* /usr/local/share/.cache/* /var/cache/* /tmp/* && \ apk del build-packs COPY . $ROOT # Add a script to be executed every time the container starts. COPY entrypoint.sh /usr/bin/ RUN chmod +x /usr/bin/entrypoint.sh ENTRYPOINT ["sh", "/usr/bin/entrypoint.sh"] EXPOSE 3000
docker-compose.yml
- macでストレージのアクセスが遅い問題に対応するためvolumeに
:cahed
オプションを追加- webpack-dev-serverを別コンテナで起動させて、hot reloadに対応させています. (ファイル構成に変更があった場合にブラウザのリロード、必要に応じてjavascript周りのコンパイルをしてくれる)
- dbのhost, user, passwordは後で再利用
version: '3' services: db: image: postgres:11.0-alpine volumes: - postgres:/var/lib/postgresql/data:cached environment: - TZ=Asia/Tokyo ports: - '5432:5432' environment: PGDATA: /var/lib/postgresql/data/pgdata POSTGRES_USER: postgres POSTGRES_PASSWORD: password POSTGRES_INITDB_ARGS: '--encoding=UTF-8 --locale=ja_JP.UTF-8' TZ: Asia/Tokyo app: build: . command: ash -c "rm -f tmp/pids/server.pid && ./bin/rails s -p 3000 -b '0.0.0.0'" volumes: - .:/myapp:cached - rails_cache:/myapp/tmp/cache - bundle:/bundle:cached tmpfs: - /tmp tty: true stdin_open: true ports: - "3000:3000" environment: RAILS_ENV: development NODE_ENV: development DATABASE_HOST: db DATABASE_PORT: 5432 DATABASE_USER: postgres DATABASE_PASSWORD: password WEBPACKER_DEV_SERVER_HOST: webpacker depends_on: - db - webpacker links: - db - webpacker webpacker: build: . command: ./bin/webpack-dev-server volumes: - .:/myapp:cached environment: RAILS_ENV: development NODE_ENV: development WEBPACKER_DEV_SERVER_HOST: 0.0.0.0 tty: false stdin_open: false ports: - '3035:3035' volumes: rails_cache: postgres: bundle:
Gemfile
source 'https://rubygems.org' gem 'rails', '6.0.3'
Gemfile.lock
空のファイルで良いので
touch
コマンドのみtouch Gemfile.lock
entrypoint.sh
#!/bin/bash set -e # Remove a potentially pre-existing server.pid for Rails. rm -f /myapp/tmp/pids/server.pid # Then exec the container's main process (what's set as CMD in the Dockerfile). exec "$@"手順
Rails 6.0.3をインストールします
docker-compose run app rails new . --force --no-deps --database=postgresql --skip-bundle
Gemfile
Railsチュートリアルに準じて以下のように変更
(Development, test環境でもPostgreSQLを使用するように変更してあります。)source 'https://rubygems.org' git_source(:github) { |repo| "https://github.com/#{repo}.git" } gem 'rails', '6.0.3' gem 'puma', '4.3.4' gem 'pg', '1.1.4' gem 'sass-rails', '5.1.0' gem 'webpacker', '4.0.7' gem 'turbolinks', '5.2.0' gem 'jbuilder', '2.9.1' gem 'bootsnap', '1.4.5', require: false group :development, :test do gem 'byebug', '11.0.1', platforms: [:mri, :mingw, :x64_mingw] end group :development do gem 'web-console', '4.0.1' gem 'listen', '3.1.5' gem 'spring', '2.1.0' gem 'spring-watcher-listen', '2.0.1' end group :test do gem 'capybara', '3.28.0' gem 'selenium-webdriver', '3.142.4' gem 'webdrivers', '4.1.2' gem 'rails-controller-testing', '1.0.4' gem 'minitest', '5.11.3' gem 'minitest-reporters', '1.3.8' gem 'guard', '2.16.2' gem 'guard-minitest', '2.4.6' end group :production do end # Windows ではタイムゾーン情報用の tzinfo-data gem を含める必要があります #gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]Gemfile.lockをアップデート(必要ないかもしれません)
docker-compose run app bundle updatewebpackerのインストール
Rails 6ではwebpackerが必要ですが、
このままではインストールされていないためインストールしますdocker-compose run app rails webpacker:installデータベースの設定
config/database.yml
host, username, passwordをdocker-compose.yml
と一致させるdefault: &default adapter: postgresql encoding: unicode host: db username: postgres password: password pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> #省略...
docker-compose build
DockerfileやGemfileを変更する度に'build'が必要です
bundle installも実施されるため少し時間がかかりますdocker-compose buildいよいよコンテナを起動
docker-compose upデータベース作成
このままだとDBがないよと言われるので、development環境のDBを作成
docker-compose run app rake db:create動作確認
docker ps
で起動しているコンテナ確認
DB, Rails, webpack-dev-serverの3つのコンテナが起動しています。$ docker ps CONTAINER ID IMAGE COMMAND ... PORTS NAMES 1fb4f53d5652 sample_app_on_docker_app "sh /usr/bin/entrypo…" ... 0.0.0.0:3000->3000/tcp sample_app_on_docker_app_1 ccd40c018d53 sample_app_on_docker_webpacker "sh /usr/bin/entrypo…" ... 3000/tcp, 0.0.0.0:3035->3035/tcp sample_app_on_docker_webpacker_1 74392532098a postgres:11.0-alpine "docker-entrypoint.s…" ... 0.0.0.0:5432->5432/tcp sample_app_on_docker_db_1ブラウザで
localhost:3000
にアクセスするとお疲れさまでした"Yay! You’re on Rails!"
Trouble shoot
check_yarn_integrity
関連コンテナを
docker-compose up
で起動したときに出るエラーapp_1 | ======================================== app_1 | Your Yarn packages are out of date! app_1 | Please run `yarn install --check-files` to update. app_1 | ======================================== app_1 | app_1 | app_1 | To disable this check, please change `check_yarn_integrity` app_1 | to `false` in your webpacker config file (config/webpacker.yml). app_1 | app_1 | app_1 | yarn check v1.16.0 app_1 | info Visit https://yarnpkg.com/en/docs/cli/check for documentation about this command. app_1 | app_1 | app_1 | Exiting sample_app_on_docker_app_1 exited with code 1
config/webpacker.yml
以下のように変更します#...省略 development: <<: *default compile: false # true -> falseに変更 # Verifies that correct packages and versions are installed by inspecting package.json, yarn.lock, and node_modules check_yarn_integrity: true #省略..."webpack-dev-server" not found
同じくコンテナを
docker-compose up
で起動したときに出るエラーwebpacker_1 | yarn run v1.16.0 webpacker_1 | error Command "webpack-dev-server" not found. webpacker_1 | info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command. sample_app_on_docker_webpacker_1 exited with code 1
package.json
にwebpack-dev-serverが記述されていないはずなので
webpack-dev-serverをインストールdocker-compose run app yarn add webpack-dev-serverおまけ
イメージサイズ 477MB
先人の知恵を多々お借りして軽量化したつもりです。
Dockerを学び始めた頃に作ったのイメージは1.5GBほどありました...
$docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
sample_app_on_docker_app latest 84aed607a3d2 31 minutes ago 477MB
sample_app_on_docker_webpacker latest 84aed607a3d2 31 minutes ago 477MB