- 投稿日:2020-04-06T23:36:28+09:00
プロキシ環境下でGrowiから社内のMattermostにwebhookで通知
はじめに
どうも!生産技術部のエンジニアです。GrowiとMattermostをひとつのサーバに同居させ、社内のプロキシ環境下で、Mattermost宛てのwebhookをしようとしたところ、うまく通知が飛ばない問題がありました。解決する方法を紹介します。
環境
※現在、Growiのバージョンは3.7.2が最新ですが、webhookの設定ができなかったため、バージョンを落としています。この問題についてはSlackにて連絡し、即座に修正いただきました。お忙しい中ありがとうございました。
fix notification setting can't update without slack token #1849前提条件
Growiの導入が実施済みであること。プロキシ環境下で立ち上げる場合は以下を参考にしてください。
「プロキシ環境下でDocker Composeを用いてGrowiを立ち上げる」
ただし、以下の様にgrowiのバージョンを指定して導入しました。# FROM weseek/growi:3 FROM weseek/growi:3.7.0まず試したこと
mattermostの公式ドキュメントを参考にcurlコマンドを使って、webhookが正常に動作しているか確認しました。
1.growi,mattermost同居のサーバ⇒mattermostにcurlを実行
curl -i -X POST -H 'Content-Type: application/json' -d '{"text": "Hello, this is some text\nThis is more text. :tada:"}' http://<サーバIP:ポート>/hooks/xxx-generatedkey-xxx通知できず失敗
2.社内にある別PC⇒mattermostにcurlを実行
コマンドは1と同様。通知できず失敗。どうやらプロキシを使っているからうまく届いていない様だ。
3.プロキシを使用しないように設定し、curlを実行
curl --noproxy <サーバIP> -i -X POST -H 'Content-Type: application/json' -d '{"text": "Hello, this is some text\nThis is more text. :tada:"}' http://<サーバIP:ポート>/hooks/xxx-generatedkey-xxx--noproxyオプションを追加することで、growi,mattermost同居のサーバからでも、社内にある別PCからでも通知成功。あとは、growiにnoproxyを設定するだけ!
noproxyを設定し、growiからwebhookする
Dockerfileに環境変数を設定することで、解決します。
growi/DockerfileENV http_proxy 'proxy.example.com:8888' ENV https_proxy 'proxy.example.com:8888' # 以下の行を追加 ENV no_proxy '<サーバIP>'docker-composeでbuildし直し、動作確認すると、うまく通知が出来るようになりました。
最後に
これでwebhookも利用でき、必要な設定がある程度完了しました。これで運用が開始できます。
ただし、
社内では、growiでサポートされていないIEしか使わない人がほとんどなので、ここが一番の問題ですw みんなChromeに乗り換えてくれえええご参考
- 投稿日:2020-04-06T23:07:48+09:00
Ansible学習用Dockerコンテナの作成
概要
Ansibleの実行環境にVagrant+Virtualboxを使っている例が多いと感じたものの,
せっかくなのでDockerで環境を作ってみました.環境
- Mac OS X 10.15
- Docker version 19.03.5
作成手順
まずは普通にインストールする場合のコマンドを並べ,最後にDockerfileに落とし込んだ上でビルドします.
元イメージの決定
今回はCentOS7で作ってみます.
他OSでも問題ないですが,以下の手順は適宜読み替えて下さい.ansibleのインストール
CentOS7でansibleをインストールするにはepelリポジトリを追加する必要があるため,以下コマンドで追加した上でインストール.
yum install -y epel-release yum install -y ansiblesshのインストール
CentOS7のイメージにはsshサーバ/クライアントが含まれていないため,これらをインストール.
ちなみにサーバはopenssh-server
ですが,クライアントはopenssh-clients
(末尾にsが必要)なので注意(自分はここでハマり,コンテナ起動後にsshコマンドが打てず泣きました).
sshpass
はパスワード認証の際に必要.yum install -y openssh-server yum install -y openssh-clients yum install -y sshpassその他のコマンドのインストール
無くても良いものの,あると便利なコマンドをインストール.
自分はIPアドレスの確認にip
コマンドを使いたいので,追加でインストールしました.
他に欲しいコマンドがあれば追記していきます.yum install -y iproute軽量化
yum関係の不要なキャッシュを削除することで,イメージを軽量化します.
rm -rf /var/cache/yum/* yum clean allsshの設定
rootログインの許可,rootパスワードの設定等を行います.
あくまで検証用なので,セキュリティ的な観点は無視しています.sed -ri 's/^#PermitRootLogin yes/PermitRootLogin yes/' /etc/ssh/sshd_config && \ echo 'root:password' | chpasswd && \ ssh-keygen -t rsa -N "" -f /etc/ssh/ssh_host_rsa_keysshdの起動
sshの設定が終わったので,sshdを起動します.
systemctl start sshd.serviceDockerfileに落とし込む
上記までの内容をDockerfileに書くと,以下のようになります.
FROM centos:7 RUN yum update -y && \ yum install -y epel-release && \ yum install -y \ ansible \ openssh-server \ openssh-clients \ sshpass \ iproute && \ rm -rf /var/cache/yum/* && \ yum clean all && \ sed -ri 's/^#PermitRootLogin yes/PermitRootLogin yes/' /etc/ssh/sshd_config && \ echo 'root:password' | chpasswd && \ ssh-keygen -t rsa -N "" -f /etc/ssh/ssh_host_rsa_key CMD ["usr/sbin/sshd", "-D"]イメージのビルド
以下のコマンドで上記のDockerfileからイメージをビルドします.
docker build -t <イメージ名> .完成
ビルド完了後,
docker run
でコンテナを作成し,ansibleがインストールされていることを確認.$ docker run -itd --name test --rm --privileged <イメージ名> /sbin/init $ docker exec -it test /bin/bash $ ansible --version ansible 2.9.6 ///省略sshサーバ,クライアント両方を入れているので,コンテナを2つ起動することで一方からもう一方をansibleで操作することができます.
- 投稿日:2020-04-06T22:46:19+09:00
さわっておぼえるDocker入門?#1(コンテナを作ったり壊したり)
はじめに
とにかくクジラ?がかわいいですよね。
Dockerを触りながら基本をさらっていきましょう。目的
Dockerを触りながら、どんなことができるのか確認する
コンテナを起動したり、削除したりしながら、コンテナに慣れていきたいと思います。
今回は
- コンテナの起動
- コンテナの一覧を取得
- コンテナのログを確認
- コンテナを削除
していきます。
環境
- macOS Mojave 10.14.6
- Docker engine 19.03.5
まずはDockerのインストール
コンテナを作ったり壊したりしてみる
container run
以下のコマンドでnginxサーバーのコンテナが起動します。
ブラウザでlocalhost
にアクセスすることで、サーバーが立ち上がっていることを確認することができます。docker container run --publish 80:80 nginx
docker container run
は、新しいコンテナを起動するコマンドです。--publish
は、ローカルポートを開きます。nginx
は、ここではイメージ名です。メモ
- この時、イメージがローカルにない場合には、
Docker Hub
というサービスから自動でダウンロードされます。ちなみにダウンロードされるのは最新のパッケージです。--publish
オプションを指定しない場合は、どのポートも開かれません。80:80
はもちろん80(ホストのポート):80(コンテナのポート)
です。ホストの80番ポートへの通信は全てコンテナのポートへ転送しています。- http通信のポートは80を使用することが多いので
80:80
を指定していますが、例えば8080:80
としてホストで待ち受けるポート番号に8080
を指定しても問題ありません。プロセスを終了する時
もちろん、
ctrl + C
でプロセスを終了できます。
--detach
今度は、
--detach
というオプションをつけて実行しました。
このオプションを付け加えることで、バックグランドでコンテナプロセスが実行されます。つまり、コンテナを実行した後も、ターミナルは別のコマンドを受け付ける状態になっています。docker container run --publish 80:80 --detach nginxコマンドを実行した時に表示されるのは、起動したコンテナのIDです。
$ docker container run --publish 80:80 --detach nginx #コンテナID: 19773d0f7ab574f9e7a9ba47df86426787ea865c0e7610dfc67b7b5fb1c50e52
docker container ls
起動中のコンテナの一覧を取得します。
container ls
container ls -a
全てのコンテナの一覧を取得します。
docker container ls -a以下のように、コンテナの情報が取得できます。
docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 19773d0f7ab5 nginx "nginx -g 'daemon of…" 13 minutes ago Exited (0) 3 minutes ago optimistic_lovelace 704100449b0c nginx "nginx -g 'daemon of…" 27 minutes ago Exited (0) 14 minutes ago flamboyant_jennings
--name
container run
して起動したコンテナには、自動で名前がつけられています。
先ほどls
コマンドで確認した情報のname
の列から確認できます。
--name
オプションを使用することで、自由に名前をつけることができます。docker container run --publish 80:80 --detach --name webhost nginx
ls
コマンドで確認すると、確かに指定した名前が確認できます。docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 00b50a6ae905 nginx "nginx -g 'daemon of…" 6 seconds ago Up 4 seconds 0.0.0.0:80->80/tcp webhost
container stop
コンテナを停止するには、
stop
コマンドにコンテナIDを指定します。docker container stop 19773指定するIDは、全部打ち込まなくても一意であれば補完してくれます。
ls
コマンドで、本当にコンテナが停止したかどうか確認できます。
container logs
指定したコンテナのログを取得します。
以下では、先ほど名前つきで起動したwebhost
コンテナのログを取得しています。docker container logs webhost
container top
起動中コンテナのプロセスを確認できます。
docker container top webhost PID USER TIME COMMAND 2384 root 0:00 nginx: master process nginx -g daemon off; 2426 101 0:00 nginx: worker process今回のnginxコンテナの場合は、マスタープロセスとワーカープロセスが走っていることが確認できました。
container rm
使わないコンテナを削除します。
まずは
ls -a
コマンドで、全てのコンテナを確認し、その後全て削除してみます。docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 00b50a6ae905 nginx "nginx -g 'daemon of…" 9 minutes ago Up 9 minutes 0.0.0.0:80->80/tcp webhost 19773d0f7ab5 nginx "nginx -g 'daemon of…" 30 minutes ago Exited (0) 20 minutes ago optimistic_lovelace 704100449b0c nginx "nginx -g 'daemon of…" 44 minutes ago Exited (0) 30 minutes ago flamboyant_jennings3つのコンテナが起動中です。これらを
rm
コマンドで全て削除します。rm の引数には、コンテナIDを一気に3つ指定していますが、例によってIDは全桁を入力する必要はありません。最初の3桁だけでも削除できます。
docker rm 00b 197 704 197 704 Error response from daemon: You cannot remove a running container 00b50a6ae90511bf80bece7ebbca5dadcabde96d0481c61ec0fb1d572bb1a1d7. Stop the container before attempting removal or force remove
ID
197
とID704
は削除できたようですが、同時にエラーメッセージが出ました。起動中のコンテナは削除できないことがエラーの理由です。
container rm -f
-f
オプションをつけることで、起動中のコンテナも強制削除することができます。docker container rm -f 00bこれで全てのコンテナを削除できました。
まとめ
本当に簡単なコマンドで、
- コンテナ起動したり、
- コンテナの一覧を取得したり、
- コンテナのログを確認したり、
- コンテナを削除したり
できました。
- 投稿日:2020-04-06T22:46:19+09:00
さわっておぼえるDocker入門?#1
はじめに
とにかくクジラ?がかわいいですよね。
Dockerを触りながら基本をさらっていきましょう。目的
Dockerを触りながら、どんなことができるのか確認する
環境
- macOS Mojave 10.14.6
- Docker engine 19.03.5
まずはDockerのインストール
コンテナをアレコレしてみる
コンテナを起動したり、削除したりしながら、コンテナに慣れていきたいと思います。
今回は
- コンテナの起動
- コンテナの一覧を取得
- コンテナのログを確認
- コンテナを削除
していきます。
docker container run
以下のコマンドでnginxサーバーのコンテナが起動します。
ブラウザでlocalhost
にアクセスすることで、サーバーが立ち上がっていることを確認することができます。docker container run --publish 80:80 nginx
docker container run
は、新しいコンテナを起動するコマンドです。--publish
は、ローカルポートを開きます。nginx
は、ここではイメージ名です。メモ
- この時、イメージがローカルにない場合には、
Docker Hub
というサービスから自動でダウンロードされ、実行されます。ちなみにダウンロードされるのは最新のパッケージです。--publish
オプションを指定しない場合は、どのポートも開かれません。80:80
はもちろん80(ホストのポート):80(コンテナのポート)
です。ホストの80番ポートへの通信は全てコンテナのポートへ転送しています。- http通信のポートは80を使用することが多いので
80:80
を指定していますが、例えば8080:80
としてホストで待ち受けるポート番号に8080
を指定しても問題ありません。プロセスを終了する時
もちろん、
ctrl + C
でプロセスを終了できます。
--detach
今度は、
--detach
というオプションをつけて実行しました。
このオプションを付け加えることで、バックグランドでコンテナプロセスが実行されます。つまり、コンテナを実行した後も、ターミナルは別のコマンドを受け付ける状態になっています。docker container run --publish 80:80 --detach nginxコマンドを実行した時に表示されるのは、起動したコンテナのIDです。
$ docker container run --publish 80:80 --detach nginx #コンテナID: 19773d0f7ab574f9e7a9ba47df86426787ea865c0e7610dfc67b7b5fb1c50e52
docker container ls
起動中のコンテナの一覧を取得します。
container ls
container ls -a
全てのコンテナの一覧を取得します。
docker container ls -a以下のように、コンテナの情報が取得できます。
docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 19773d0f7ab5 nginx "nginx -g 'daemon of…" 13 minutes ago Exited (0) 3 minutes ago optimistic_lovelace 704100449b0c nginx "nginx -g 'daemon of…" 27 minutes ago Exited (0) 14 minutes ago flamboyant_jennings
--name
container run
して起動したコンテナには、自動で名前がつけられています。
先ほどls
コマンドで確認した情報のname
の列から確認できます。
--name
オプションを使用することで、自分で任意の名前をつけることができます。docker container run --publish 80:80 --detach --name webhost nginx
ls
コマンドで確認すると、確かに指定した名前が確認できます。docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 00b50a6ae905 nginx "nginx -g 'daemon of…" 6 seconds ago Up 4 seconds 0.0.0.0:80->80/tcp webhost
container stop
コンテナを停止するには、
stop
コマンドにコンテナIDを指定します。docker container stop 19773指定するIDは、全部打ち込まなくても一意であれば補完してくれます。
ls
コマンドで、本当にコンテナが停止したかどうか確認できます。
container logs
指定したコンテナのログを取得します。
以下では、先ほど名前つきで起動したwebhost
コンテナのログを取得しています。docker container logs webhost
container top
起動中コンテナのプロセスを確認できます。
docker container top webhost PID USER TIME COMMAND 2384 root 0:00 nginx: master process nginx -g daemon off; 2426 101 0:00 nginx: worker process今回のnginxコンテナの場合は、マスタープロセスとワーカープロセスが走っていることが確認できました。
container rm
使わないコンテナを削除します。
まずは
ls -a
コマンドで、全てのコンテナを確認し、その後全て削除してみます。docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 00b50a6ae905 nginx "nginx -g 'daemon of…" 9 minutes ago Up 9 minutes 0.0.0.0:80->80/tcp webhost 19773d0f7ab5 nginx "nginx -g 'daemon of…" 30 minutes ago Exited (0) 20 minutes ago optimistic_lovelace 704100449b0c nginx "nginx -g 'daemon of…" 44 minutes ago Exited (0) 30 minutes ago flamboyant_jennings3つのコンテナが起動中です。これらを
rm
コマンドで全て削除します。rm の引数には、コンテナIDを一気に3つ指定していますが、例によってIDは全桁を入力する必要はありません。最初の3桁だけでも削除できます。
docker rm 00b 197 704 197 704 Error response from daemon: You cannot remove a running container 00b50a6ae90511bf80bece7ebbca5dadcabde96d0481c61ec0fb1d572bb1a1d7. Stop the container before attempting removal or force remove
ID
197
とID704
は削除できたようですが、同時にエラーメッセージが出ました。起動中のコンテナは削除できないことがエラーの理由です。
container rm -f
-f
オプションをつけることで、起動中のコンテナも強制削除することができます。docker container rm -f 00bこれで全てのコンテナを削除できました。
まとめ
本当に簡単なコマンドで、
- コンテナ起動したり、
- コンテナの一覧を取得したり、
- コンテナのログを確認したり、
- コンテナを削除したり
できました。
- 投稿日:2020-04-06T21:19:04+09:00
よく使うDocker コマンド覚書
Dockerコマンド覚書
コンテナ操作に不慣れな私の備忘録
実行中のコンテナをリスト
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dffbdaebcd67 ibm-workload-automation-agent-dynamic:9.5.0.00.201903080412 "/opt/wautils/wa_s..." 12 days ago Up 12 days modest_swartz
5be02e1472cc ibm-workload-automation-server:9.5.0.00.201903080358 "/opt/wautils/wa_s..." 2 weeks ago Up 2 weeks xenodochial_sinoussi
53e263c5aec7 ibm-workload-automation-console:9.5.0.00.201903080738 "/opt/wautils/wa_s..." 2 weeks ago Up 2 weeks hardcore_haibt
7f55c57b70a0 7afd43c3fd50 "/opt/wautils/wa_s..." 3 weeks ago Up 3 weeks distracted_jonesコンテナ内でコマンド実行(/bin/bash)
$ docker exec -it container_id /bin/bash
Setting CLI environment variables....
IBM Workload Scheduler Environment Successfully Set !!!
IBM Workload Automation Environment Successfully Set !!!
wauser@5be02e1472cc:/$コンテナのログを見る
$ docker logs container_id
exitしてしまったコンテナ内のファイルなどを確認する
$ docker run --rm -it container_id sh
- 投稿日:2020-04-06T21:02:13+09:00
Docker debian系imageでterminalの日本語入力環境のタレ
Dockerのdebian系イメージで日本語入力環境を作るレシピ。
ちなみに、Dockerのimageの基本はdebianから作ることを公式が推奨しており、大抵はdebianイメージのextendである。私がよく使うnode imageもそう。ruby imageも多分そうだった気がする。
DockerfileFROM node # debianだったりいろいろ RUN apt-get update && apt-get install -y \ locales-all \ && apt-get clean -y \ && rm -rf /var/lib/apt/lists/* ENV LANG=ja_JP.UTF-8似ている情報
apt-get install language-pack-ja
などをせよとの記事が多いが、これは多分ubuntuベースのimageのレシピだろう。debianにこんなパッケージはなかった。
locale-gen && update-locale
せよとの記事を見かけたが、localesパッケージではなくてlocales-allパッケージを入れればやらなくていいっぽい。でもja以外も入りそう。私は容量より設定の容易さを優先してこの方法にした。
- 投稿日:2020-04-06T19:32:14+09:00
Jitsi Meet(ビデオ会議システム)のサーバを Docker Compose で起動する手順
Jitsi 概要
Jitsi Meet (ジッチ・ミート)とはオープンソース(Apache License 2.0)として開発・利用できるビデオ会議用のシステムです。利用者はブラウザから URL にアクセスするだけで、すぐにビデオ会議が利用できます。ブラウザ以外にも、iOS や Android 対応のアプリが公開されています。
この Jitsi Meet 用のサーバ環境は Docker に対応しています 。自分のドメイン名を使い、自分のサーバ上に Docker Compose で起動する手順をまとめました。 公式ドキュメント をベースに、自分が持つドメイン名のホストで Jitsi Meet を立ち上げるまでの手順です。(なお、ドメイン名を準備しているのは Let's Encrypt の HTTPS 通信にも対応させるためです。単なるセットアップ確認であれば、HTTPS は必須ではありません。)
事前準備
- Jitsi Meet を動かす Linux サーバ環境(本手順は CentOS 7.x を前提としています) ※本手順は 2GB のメモリ環境で試しました
- Docker Engine と Docker Compose のインストール
- DNS サーバ側で、何らかのホスト名をサーバに対して設定(レコードの追加)
- ここでは
meet.toaru.site
というホスト名での設定を想定- Let's Encrypt で SSL 証明書を利用するため。利用しなくても Jitsi Meet を試せられるものの、ブラウザ側のセキュリティ設定によっては映像・音声通話が出来ない可能性
Jitsi 設定手順
GitHub リポジトリのクローン
まず GitHub 上のリポジトリを
git clone
でローカルに保存し、ディレクトリを移動します。git clone https://github.com/jitsi/docker-jitsi-meet && cd docker-jitsi-meetJisti 環境変数用ファイル
.env
の編集次に、設定ファイルを準備するため、サンプル用のファイルをコピーします。なお、このファイル
.env
は Docker Compose で起動する時、環境変数として読み込むために使います。cp env.example .envそれから
.env
ファイルを編集します。vi .env
などでファイルを開きます。編集箇所を上からみていきます。基本設定
基本設定として、9~18行目までは、次のように書き換えます。
# # Basic configuration options # # Directory where all configuration will be stored CONFIG=~/.jitsi-meet-cfg ← Let's Encrypt の証明書など、基本的な情報などが格納されるディレクトリ # Exposed HTTP port HTTP_PORT=80 ← 一般的な HTTP 用ポートにします # Exposed HTTPS port HTTPS_PORT=443 ← 一般的な HTTPS 用ポートにします # System time zone TZ=Asia/Tokyo ← タイムゾーンを日本にします # Public URL for the web service PUBLIC_URL=https://meet.toaru.site ←このホスト名は皆さんの環境にあわせ変更します。先頭の # を外すのを忘れずにしますLet's Encrypt 設定
Let's Encrypt の設定を追加します(30~36行目)。
# # Let's Encrypt configuration # # Enable Let's Encrypt certificate generation ENABLE_LETSENCRYPT=1 ←「1」が有効です。先頭の # を消します。 # Domain for which to generate the certificate LETSENCRYPT_DOMAIN=meet.toaru.site ←こちらは、環境にあわせて書き換えます # E-Mail for receiving important account notifications (mandatory) LETSENCRYPT_EMAIL=alice@example.jp ← ここは、皆さんのメールアドレスを入力します(Let's Encrypt の有効期限通知が届きます)
.env
で最低限の編集が必要なのは、以上の項目です。設定ファイル等の保存用ディレクトリ作成
それから、設定情報を格納するディレクトリを作成します。
mkdir -p ~/.jitsi-meet-cfg/{web/letsencrypt,transcripts,prosody,jicofo,jvb}メモ:ここで作成する
~/.jitsi-meet-cfg
ディレクトリは Let's Encrypt の証明書を格納するなど、重要な場所です。一通りの稼働を確認したら、バックアップ用に控えておくのをおすすめします。また、ホスト名を変更した場合など、トラブルシューティングに困ったら、一旦このディレクトリを別名に変えるなどして、再度 Docker Compose の起動を試すとスムーズに起動できる場合もあります。Docker イメージの取得と確認
それから、Docker Compose で使うイメージをダウンロードします。コマンドを実行すると、必要な Docker イメージを順次ダウンロードします。
docker-compose pull
docker images
コマンドを実行すると、実行に必要な Docker イメージを確認できます。REPOSITORY TAG IMAGE ID CREATED SIZE jitsi/jvb latest fd8201652975 11 days ago 276MB jitsi/jicofo latest 773ffe263260 11 days ago 277MB jitsi/prosody latest 5734ef478ff3 11 days ago 256MB jitsi/web latestDocker Compose で Jitsi の起動
あとは Docker Compose で起動します。
docker-compose up -d
docker-compose ps
コマンドを実行すると、各サービスが稼働中 ( Up ) なのが分かります。Name Command State Ports ---------------------------------------------------------------------------------------------- dockerjitsimeet_jicofo_1 /init Up dockerjitsimeet_jvb_1 /init Up 0.0.0.0:10000->10000/udp, 0.0.0.0:4443->4443/tcp dockerjitsimeet_prosody_1 /init Up 5222/tcp, 5269/tcp, 5280/tcp, 5347/tcp dockerjitsimeet_web_1 /init Up 0.0.0.0:8443->443/tcp, 0.0.0.0:8000->80/tcpこのコマンドを実行しているバックグラウンドで、 Let's Encrypt 用の証明書発行や、様々な初期設定が進行しています。
どのような処理が進行しているかは 、
docker-compose logs -f
コマンドで確認できます。ここではweb
サービス(Nginxが稼働しています)のログを確認します。docker-compose logs -f webログを辿ると、次のように証明書の取得が成功したり、有効期限などが表示されています。
web_1 | Obtaining a new certificate web_1 | Performing the following challenges: web_1 | http-01 challenge for meet.toaru.site web_1 | Waiting for verification... web_1 | Cleaning up challenges web_1 | IMPORTANT NOTES: web_1 | - Congratulations! Your certificate and chain have been saved at: web_1 | /etc/letsencrypt/live/meet.toaru.site/fullchain.pem web_1 | Your key file has been saved at: web_1 | /etc/letsencrypt/live/meet.toaru.site/privkey.pem web_1 | Your cert will expire on 2020-07-05. To obtain a new or tweakedもし
- The following errors were reported by the server:
のようなエラーメッセージやnginx: [emerg] open() "/config/nginx/nginx.conf" failed (2: No such file or directory)
というエラーメッセージが出る場合、証明書の作成に失敗しています。.env
の記述が誤っているか、あるいはファイアウォール等でサーバに HTTP (TCP/80)での通信が出来ない可能性があります。通信に関連する諸設定を確認します。また、ホスト名の記述が間違っている場合は~/.jitsi-meet-cfg
を別名にするなどして、作り直すのも1つです。最終的には、次のようなログが表示されれば問題ありません。ログの表示は
Ctrl-C
で中断できます。web_1 | [cont-init.d] 10-config: exited 0. web_1 | [cont-init.d] done. web_1 | [services.d] starting services web_1 | [services.d] done.ウェブブラウザでアクセス・動作確認
あとは、ブラウザで https://設定したホスト名 にアクセスするだけです。
「新しいミーティングを開始」でミーティング名(ルーム名に相当します)を入力し、「GO」を押せば大丈夫です。
音声、動画、テキストでのチャットだけでなく、画面共有機能もあります。
Enjoy!
その他、今後の考慮点など
- 必要に応じてファイアウォール等は検討。このままだと、URLが分かるので誰でもアクセスできてしまう
- Jitsi には認証機能があるようなので、それも試してみたいところ
- 利用者が増えた時のネットワーク帯域を計測しないと
- 長期運用する場合、このまま Compose でよいのだろうか
- 拡張機能として、録画、文章共有、ディクテーション機能があるので試したい
参考情報
- 投稿日:2020-04-06T18:22:35+09:00
PowerShell から amazon/aws-cli の Docker イメージを起動して AWS に接続する
AWS CLI の Docker イメージが公開されたので、Docker for Windows + PowerShell という環境から、これを利用する手順について確認しました。
参考:
動作環境は以下の通りです。
PS > docker --version Docker version 19.03.6, build 369ce74a3c PS > $PSVersionTable Name Value ---- ----- PSVersion 6.2.4 PSEdition Core GitCommitId 6.2.4 OS Microsoft Windows 10.0.18363 Platform Win32NT PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…} PSRemotingProtocolVersion 2.3 SerializationVersion 1.1.0.1 WSManStackVersion 3.0Docker イメージの参照
まずは Docker イメージを pull します。
PS > docker pull amazon/aws-cli Using default tag: latest latest: Pulling from amazon/aws-cli a7583ef20c9d: Pull complete 7d4c8ec0c058: Pull complete cd590779e8ea: Pull complete a37a98af08a9: Pull complete 0a765160c849: Pull complete Digest: sha256:7a27c26c2937a3d0b84171675709df1dc09aa331e86cad90f74ada6df7b59c89 Status: Downloaded newer image for amazon/aws-cli:latest docker.io/amazon/aws-cli:latest
docker run
により、CLI ツールのバージョンが返ってくることを確認します。PS > docker run --rm -ti amazon/aws-cli --version aws-cli/2.0.6 Python/3.7.3 Linux/4.15.0-91-generic botocore/2.0.0dev10PowerShell 関数として定義
以降のコマンドを簡略化するため、コマンドを関数として定義します。まずは PowerShell プロファイルのパスを確認します。
PS > echo $PROFILE C:\Users\__USER_NAME__\Documents\PowerShell\Microsoft.PowerShell_profile.ps1プロファイルを編集し、以下の記述を追加します。
function aws { $location = Get-Location docker run --rm -v ${HOME}/.aws:/root/.aws -v ${location}:/aws amazon/aws-cli $Args }PowerShell を再起動し、関数が利用できることを確認します。
PS > aws --version aws-cli/2.0.6 Python/3.7.3 Linux/4.15.0-91-generic botocore/2.0.0dev10AWS への接続設定
次に、AWS 接続用の設定ファイルを生成します。
PS > aws configure AWS Access Key ID [None]: AKIA**************** AWS Secret Access Key [None]: **************************************** Default region name [None]: ap-northeast-1 Default output format [None]: jsonこれにより、以下の設定ファイルが生成されたことを確認できます。
PS > ls $HOME\.aws Directory: C:\Users\__USER_NAME__\.aws Mode LastWriteTime Length Name ---- ------------- ------ ---- -a---- 2020/04/06 16:59 48 config -a---- 2020/04/06 16:59 116 credentialsチュートリアルに合わせ、S3 上のディレクトリを参照してみます。
PS > aws s3 ls 2020-03-31 00:47:53 testS3 上にバケットが存在していれば、その一覧が応答で返ってきます。これにより、AWS サービスとの接続が確認できました。
- 投稿日:2020-04-06T18:09:07+09:00
Docker amazonlinux2 で systemctl を使いたい人生だった
TLDR;
DockerfileFROM amazonlinux:2 RUN yum update -y \ && yum install systemd-sysv -y CMD ["/sbin/init"]docker-compose.ymlversion: "2" services: web: image: amazonlinux:2 build: . container_name: al2c privileged: true ports: - 8080:80$ docker-compose up --build -damazonlinux2では
systemctl
がデフォルトでは使えないamazonlinux2のコンテナを普通に立ち上げただけだと、
systemctl
は使えない。
コマンド自体は存在する様だが、権限がないよーと怒られる。Failed to get D-Bus connection: Operation not permitted色々情報を読み齧った結果、次の要素が必要であることがわかった。
privileged
を有効にする/sbin/init
で起動するチャレンジその1
じゃぁこれでいけるだろう。
privileged
をtrue
にして起動コマンドに/sbin/init
を設定した。docker-compose.ymlversion: "2" services: web: image: amazonlinux:2 container_name: al2c command: /sbin/init privileged: true ports: - 8080:80だめでした。
ERROR: for al2c Cannot start service web: OCI runtime create failed: container_linux.go:349: starting container process caused "exec: \"/sbin/init\": stat /sbin/init: no such file or directory": unknown
/sbin/init
なんてものは存在しませんと。先んじて何かを導入してやる必要がありそう。チャレンジその2
Dockerfile
を用意して必要な物を入れてから起動。ついでに起動コマンド(/sbin/init
)もこちらに移動した。DockerfileFROM amazonlinux:2 RUN yum update -y \ && yum install systemd-sysv -y CMD ["/sbin/init"]docker-compose.ymlversion: "2" services: web: image: amazonlinux:2 build: . container_name: al2c privileged: true ports: - 8080:80$ docker exec -it al2c sh sh-4.2# systemctl UNIT LOAD ACTIVE SUB JOB DESCRIPTION dev-sda1.device loaded activating tentative /dev/sda1 dev-ttyS0.device loaded inactive dead start dev-ttyS0.device -.mount loaded active mounted / dev-hugepages.mount loaded active mounted Huge Pages File System dev-mqueue.mount loaded active mounted POSIX Message Queue File System ...無事動いたみたいです。
nginxとかでもよさそう
上では
systemd-sysv
を入れていますが、nginx
を入れただけでも依存パッケージの解決でいけました。多分apache
でもいけるんじゃないかな、試してませんが。どうせいずれかは入れると思うので、それならそれでよろしいのではないかと存じます。DockerfileFROM amazonlinux:2 RUN yum update -y \ && amazon-linux-extras install nginx1 CMD ["/sbin/init"]Amazon Linux では、
nginx
はamazon-linux-extras
コマンドでインストールできます。お世話になった記事
- 投稿日:2020-04-06T15:13:44+09:00
その Dockerfile、本当に必要ですか ? マウントで解決できませんか ?
ローカルにインストールされていないプログラミング言語・ミドルウェアなどを使いたいとき、Docker は非常に便利です。
「Docker でサクッと環境構築したい」というとき、Docker をどう使うといいのでしょうか。Docker を使い慣れていないと「とりあえず Dockerfile を書こう」と思うかもしれません。
しかし、実は Dockerfile は不要な場合も少なくないです。
この記事では、マウントを使うことで、不要な Dockerfile を書かず、サクッと環境構築する方法を説明します。例えば - PHP スクリプトを手元で実行したい
「これを手元で実行してほしい」と言われ、PHP スクリプトを渡されたとします。
hello.php<?php echo 'Hello World'; ?>このスクリプトを Docker で実行したいときの環境構築について
- Dockerfile を書く場合
- Dockerfile を書かない場合
の各種手順を比較してみます。
Dockerfile を書く場合
Docker に慣れていない場合、「Docker を使う」 = 「Dockerfile を書く」と思われるかもしれません。
上記の PHP スクリプトを Dockerfile を書いて実行する手順は、以下のようになります。
1. Dockerfile を書く
FROM php:7.4.0-cli-alpine COPY hello.php . ENTRYPOINT ["php", "hello.php"]2. コンテナイメージをビルドする
$ docker build -t hello-php .3. コンテナを起動する
$ docker run --rm hello-php Hello Worldこの手順でも確かに実行できるのですが、この方法には以下のような欠点があります。
- スクリプト 1 つ実行したいだけなのに、手順がやたらと多い
- PHP スクリプトを変更したら、docker build からやり直すことになる
- PHP のファイル名が変わったら、Dockerfile を書き直し、docker build し直すことになる
正直、これだけ手順が長いと、ローカルに PHP をインストールした方が早いと感じるでしょう。
Dockerfile を書かなければ、これらの欠点は解消します。
Dockerfile を書かない場合
1. docker run する
$ docker run --rm -v "${PWD}":/usr/src/myapp -w /usr/src/myapp php:7.4.0-cli-alpine php hello.php Hello World実は、PHP のスクリプトを実行するだけであれば、上記の 1 コマンドで OK です。
このコマンドでは、マウント機能を使うことで、ホストに置いてある PHP スクリプトをコンテナ内と共有し、それを実行しています。
Dockerfile を書く場合と比べて、こちらの方がはるかに楽に実行できます。既存のイメージそのままで実現できることは、既存のイメージを使ってしまうのが一番楽なのです。
この方法は、DockerHub の PHP のページ にも書かれています。
Run a single PHP script
For many simple, single file projects, you may find it inconvenient to write a complete Dockerfile. In such cases, you can run a PHP script by using the PHP Docker image directly:
$ docker run -it --rm --name my-running-script -v "$PWD":/usr/src/myapp -w /usr/src/myapp php:7.4-cli php your-script.php
こんな長いコマンドは辛いという場合
長いコマンドはタイピングが辛いと思うかもしれません。
それならば、シェルスクリプトを書いてしまえば OK です。最小限のシェルスクリプト
最小限のシェルスクリプトは、以下のようになります。
docker_php.sh#!/bin/bash docker run \ --rm \ -v "${PWD}":/usr/src/myapp \ -w /usr/src/myapp \ php:7.4.0-cli-alpine \ php hello.php実行は簡単です。
$ ./docker_php.sh Hello World任意のコマンドを実行可能にしたシェルスクリプト
または以下のようにして、任意のコマンドを引数として与えるようにしてもいいかもしれません。
docker_php.sh#!/bin/bash docker run \ --rm \ -v "${PWD}":/usr/src/myapp \ -w /usr/src/myapp \ php:7.4.0-cli-alpine \ php "$@"$ ./docker_php.sh hello.php Hello Worldこのようにシェルスクリプト化すれば、実行も簡単ですし、チーム内での共有も容易になります。
Docker Compose を使う場合
シェルスクリプトでは、人によって書き方も変わってしまいます。
docker run コマンドのオプションをまとめるには、Docker Compose を使う手もあります。最小限の docker-compose.yaml
docker-compose.yamlversion: '3' services: php: image: php:7.4.0-cli-alpine command: php hello.php volumes: - "${PWD}:/usr/src/myapp" working_dir: /usr/src/myapp$ docker-compose up Creating network "php_default" with the default driver Creating php_php_1 ... done Attaching to php_php_1 php_1 | Hello World php_php_1 exited with code 0Docker Compose は「複数のコンテナを一気に起動するために使うもの」と思われているかもしれませんが、上記のように docker-compose.yaml に docker run コマンドのオプションをまとめておくという使い方もできます。
任意のコマンドを実行可能にした docker-compose.yaml
シェルスクリプトの場合のように実行時に command を切り替えたい場合、環境変数を使えば実現できます。
docker-compose.yamlversion: '3' services: php: image: php:7.4.0-cli-alpine command: php "${ARGS}" volumes: - "${PWD}:/usr/src/myapp" working_dir: /usr/src/myapp$ ARGS='hello.php' docker-compose up Creating network "php_default" with the default driver Creating php_php_1 ... done Attaching to php_php_1 php_1 | Hello World php_php_1 exited with code 0ここまでのまとめ
このように、マウント機能を使うことで、面倒な Dockerfile を書かずともコンテナを利用することができました。
「Docker を使う」 = 「Dockerfile を書く」ではないのです。
マウント機能の他の使い方
ここから、マウント機能の使い方をもう少し紹介していきます。
MySQL の公式イメージ + マウント機能
ローカル環境で MySQL などのコンテナを起動する場合も、マウントを上手に使うと便利です。
有名かもしれませんが、MySQL の公式イメージには、「起動時にコンテナ内の /docker-entrypoint-initdb.d というディレクトリ内の SQL などを実行する」という機能があります。
このディレクトリをマウントしてやれば、起動時にホストにある SQL ファイルなどを実行できるのです。
例えば、以下のように docker-compose.yaml を記述します。
docker-compose.yamlversion: '3' services: mysql: image: mysql:5.7.29 ports: - 3306:3306 environment: MYSQL_ROOT_PASSWORD: password MYSQL_DATABASE: database MYSQL_USER: user MYSQL_PASSWORD: password volumes: - "${PWD}/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d"逆に、Dockerfile を使って /docker-entrypoint-initdb.d ディレクトリに SQL ファイルを配置するようにすると、コンテナに入れたいデータが変わるたびに、イメージからビルドし直さないといけなくなってしまいます。
Dockerfile を書いた方がいい場面もあるかもしれませんが、マウントの方が楽なことも多いのではないでしょうか。
使用するプログラミング言語のライブラリがある場合
Dockerfile を書かず、マウントを駆使して環境構築する方法は、各種プログラミング言語のライブラリを扱う場合に特に便利だったりします。
例えば、JavaScript の開発環境を構築するとしましょう。
以下の docker-compose.yaml を作成すれば、
docker-compose up
のコマンド 1 つで開発環境が起動します。docker-compose.yamlversion: '3' services: node: image: node:13.12.0-alpine3.10 volumes: - "${PWD}:/usr/src/myapp" working_dir: /usr/src/myapp command: sh -c 'npm install && npm start'この方法であれば、コンテナを破棄しても、ダウンロードしたライブラリがホストに残り、ライブラリ追加時も差分だけがダウンロードされます。
※ もちろん、Docker Compose ではなく docker run コマンドを使っても同じです。
マルチステージビルドとマウント
ライブラリのキャッシュといえば、「マルチステージビルドを使った docker build のたびにライブラリが大量にダウンロードされて困る」ということもあるのではないでしょうか。
これもマウントで解決することができます。
普通にマルチステージビルドすると ...
様々な書籍や記事でマルチステージビルドがオススメされていますが、通常のマルチステージビルドではマウントが使えないため、アプリケーションのビルド時に毎回全てのライブラリがダウンロードされてしまいます。
アプリケーションをコンテナ上でビルドするのはいいのですが、ライブラリを毎回ダウンロードするのは面倒です。
アプリケーションのビルドをコンテナ上で実行しつつ、ライブラリのキャッシュも駆使する方法は、大きく 2 つあります。
解決策 1. アプリケーションのビルドは docker run で実行する
解決策の 1 つ目は、マルチステージビルドを使わないことです。
代わりに、アプリケーションのビルドは Dockerfile に記述せず、dokcer run で実行します。
例えば Node.js の場合以下のようになります。
build.sh#!/bin/bash docker run \ --rm \ -v "${PWD}":/usr/src/myapp \ -w /usr/src/myapp \ node:13.12.0-alpine3.10 \ sh -c 'npm install && npm run build'このビルド成果物がホストの例えば dist ディレクトリにできているので、それを Dockerfile で COPY すれば OK です。
解決策 2. BuildKit + マルチステージビルドを使う
別の解決策として、BuildKit を使うという方法があります。
BuildKit を使えば、マルチステージビルドの中でホストのファイルをマウントすることができます。
こちらの記事 にサンプルがあります。
マウント活用の注意事項
ここまでマウントをうまく使うと便利という説明をしてきましたが、いくつか注意事項があります。
動作保証性
マウント機能を使う場合、コンテナからホストへの依存が強くなり、コンテナの「どこでも動く」という性質が弱まります。
例えば、以下のような現象に遭遇したことがあります。
- ホスト側のファイルの権限の影響で、コンテナ内でファイルがうまく操作できない
- OS に依存するライブラリをマウントしてしまい、そのライブラリがコンテナ内で動かない
「Mac では動くのに Windows では動かない」といったこともありました。
セキュリティ
「既存のイメージそのままで実現できることは、既存のイメージを使ってしまうのが一番楽」と書きましたが、DockerHub にあるイメージが全て信用できる訳ではありません。
たとえ公式のイメージであっても脆弱性が含まれることはよく指摘されています。
参考
本番環境
本番環境でコンテナを使う場合、マウントで環境構築する手法はオススメしません。
本番環境でマウントを使ってコンテナにアプリケーションを注入しようとすると、アプリケーションが入った EBS などを作成し、それをマウントすることになります。
EBS を作るより、アプリケーション入りのコンテナイメージを作る方が楽です。また、本番環境でコンテナを使うメリットの 1 つは、「ビルドした時点で諸々インストールされているため、動作保証しやすい」ということです。
アプリケーションをマウントする構成では、コンテナの外にあるデータによってコンテナの挙動が大きく変わるため、このメリットが損なわれます。開発環境ではその逆で、コンテナの外からサクッとコンテナの挙動を変えたいからこそ、マウントを使うというわけです。
まとめ
本番環境でコンテナを動かす場合、ほぼ確実に Dockerfile を書くことになります。
しかし、ローカルでちょっと何かを動かすくらいなら、必ずしも Dockerfile を書く必要はありません。マウントで工夫してみると、より楽に環境構築できることも多いです。
個人的に、「ローカルで Docker を使おうとして Dockerfile を書き始めそうになったら、もっと良い方法を考えてみる」ことにしています。
Docker は便利ですが、使い方によっては面倒になることもあります。少しでも楽に使っていきましょう。
- 投稿日:2020-04-06T15:13:26+09:00
How to backup and restore PostgreSQL using Docker
How to backup and restore PostgreSQL using Docker
Let's backup data
When managing Sentry.io on premise,
I encountered an issue.I need to backup data.
Sentry v10 is ready
Sentry v10 has been released (https://blog.sentry.io/2020/01/07/self-hosted-sentry-10-is-ready-to-serve-get-it-while-its-hot),
and I was trying to upgrade from v9.1.2It should be simply done by below command.
upgradegit pull origin master ./install.shBut I should care about failure cases
so that I started investigating how to rollback.Handle PostgreSQL version's diff
Sentry v9.1.2 uses PostgreSQL v9.5,
and v10 is based one psql v9.6First I tried to checkout to tag9.1.2 after version up.
and downgrade on perpose.But one error was shown.
I'm not sure about the cause,
but only thing I can say is that
backup data before up grade and restore after rollback should be good idea.So I started investigation how to backup and restore data of PostgreSQL with Docker.
Here it is
Backup current all data.
Backup$ docker exec -t -u postgres onpremise_postgres_1 pg_dumpall -c > dump_`date +%d-%m-%Y"_"%H_%M_%S`.sqlLet's prune volume and then reinstall.
reinstall$ docker volume prune $ ./install.shLet's initialize db (drop all tables) before restoring data.
initializedb$ docker exec -it onpremise_postgres_1 bash #into psql container $ su postgres #default user: postgres $ psql -U postgres #login to psql drop schema public cascade; create schema public; grant usage on schema public to public; grant create on schema public to public; ctrl+D ctrl+DFinally restore data.
Restore$ cat <backup file>.sql | docker exec -i onpremise_postgres_1 psql -U postgres
- 投稿日:2020-04-06T13:44:09+09:00
Elastic Beanstalkでrails on Docker した時のメモ
mysqlへの接続エラー
Elastic Beanstalk(EB)で環境を作成する時にmysql(RDS)も一緒に作成した。
この時にmysqlのpassword(8文字以上)の設定をしたのだが、適当に数字を入力しただけでは、Railsがmysqlに接続できない。
Mysql2::Error: Access denied for user 'username'@'host' (using password: YES)ここで設定したpasswordは環境変数(RDS_PASSWORD)で定義されているので、Railsのdatabase.ymlで以下のように使える。
password: <%= ENV["RDS_PASSWORD"] %>
エラーの原因を探ろうと、アプリケーションに直接潜入してみることに。
ローカルからsshでEBのEC2に入って、そこで
$ sudo docker run -i -t コンテナid bash
でdockerコンテナに入り、以下を入力しコンソールからmysqlへ接続。
$ mysql -h $RDS_HOSTNAME -u $RDS_USERNAME -p $RDS_DB_NAME
でEnter、passwordの入力を求めれ、EBで設定した先ほどのpasswordをベタ打ち、最後にEnterしてみると......繋がった。
この結果から考えれる原因は
1. セキュリティーグループやサブネット周り
2. 環境変数が正しく定義できていない最初はセキュリティーグループやサブネット周りの問題かと思って色々調べて試してみたが、繋がらなかった。
憔悴しきったところでまさかと思いEBのコンソールからmysqlのpasswordを変更してみると...
繋がった。
解決策
mysqlのpasswordの設定で一文字でも文字列を入れてあげると問題なく繋がるようだ。数字だけ では、繋がらない。
考えられる原因
おそらく、Railsがmysqlへ接続する時に使う環境変数が文字列に変換されてしまっているのだろう。
- 投稿日:2020-04-06T09:27:33+09:00
AWS Lambdaでgitコマンドを使う
AWS Lambdaでgitコマンドを使う
AWS Lambdaでgitコマンドを使いたい場合があります。
githubのAPIを呼んだり、dulwichを使ってもいいのですが、新しく勉強するよりは、できれば、いつもの使い慣れたgitコマンドを使いたいものです。使う物
AWS Lambda用にコマンドとライブラリをいい感じにまとめてくれるDockerコンテナ
→ https://hub.docker.com/r/qualitiaco/lambda-build-packgitコマンドとライブラリを抽出
gitコマンドを取り出すスクリプト
src/build.sh#!/bin/sh yum install -y git cp -a /usr/bin/git ${OUTPUT_PATH} cp -a /usr/libexec/git-core/git-remote-https ${OUTPUT_PATH} cp -a /usr/libexec/git-core/git-remote-http ${OUTPUT_PATH}yum でgitをインストールし(もしかしたら既に入っているかもしれませんが)、gitコマンド実行に必要な/usr/bin/gitとhttps通信に必要な、/usr/lib/exec/git-code/git-remote-http(s) を${OUTPUT_PATH}ディレクトリにコピーします。
この後のdockerコマンドが、${OUTPUT_PATH}にあるコマンドに必要なライブラリを自動的に抽出してくれます。
今回はyumで入れましたが、最新がよければ、gitこまんどをbuild.shスクリプト内でコンパイルしても構いません。
AWS Lambda環境用のgitコマンドとライブラリの取り出し
docker run -it --rm -v $(pwd)/src:/src -v $(pwd)/output:/output qualitiaco/lambda-build-packAWS Lambdaにアップロードする
Lambda Functionの作成
今回はPythonで作成してみます。
さっきできたoutputディレクトリの中に作成します。output/lambda_function.pyimport subprocess import os def lambda_handler(event, context): cwd = os.getcwd() os.chdir("/tmp") subprocess.call([ os.path.join(cwd, "git"), f"--exec-path={cwd}", "clone", "https://github.com/qualitiaco/action-lambda-build-pack-sample.git"]) print(open("/tmp/action-lambda-build-pack-sample/src/build.sh", "r").read())githubのhttps://github.com/qualitiaco/action-lambda-build-pack-sample.git からgit cloneして、その中にあるsrc/build.shを出力するだけのプログラムです。
zipする
outputディレクトリの中から圧縮します。
シンボリックリンクを含みますので、「-y」オプションを忘れないよう付けてください。cd output zip -9yr ../lambda_function.zip *
確認
AWS Lambda Functionをあらかじめ作成してzipファイルをアップロードします。
少しサイズが大きいので、関数のソースコードをWebで確認することはできません。実行すると、
githubからgit cloneして取得したソースコードが表示されました。
終わりに
Dockerコンテナqualitiaco/lambda-build-packを使用してAWS Lambdaに必要なgitコマンドとライブラリを取得し、AWS Lambdaでgitコマンドを実行してみました。
本記事で使用したソースコードは、
https://github.com/qualitiaco/action-lambda-build-pack
にも置いてありますので、併せてご覧ください。*本記事は @qualitia_cdevの中の一人、@hirachanさんに作成して頂きました。
- 投稿日:2020-04-06T06:41:13+09:00
AWS ECR/ECS 勉強メモ① Dockerコンテナ起動
やること
Cloud9環境でDockerイメージをビルドして
ECRにDockerイメージをpushして
ECSでDockerコンテナを起動する参考リンク
- AWS Cloud9環境でdocker-composeをできるようにする
- 今から追いつくDocker講座!AWS ECSとFargateで目指せコンテナマスター!
- Capacity Providerとは?ECSの次世代スケーリング戦略を解説する
構成
今回つくる環境
- ECSは、クラスターをEC2(linux)で構成
- クラスターを構成するEC2はCloud9と同じVPCに配置
- クラスターを構成するEC2とCloud9は通信可
各IAMロールの概要
No Name 概要 IAM-1 ecsrole Cloud9からECS,ECRにアクセス IAM-2 ー ← これ無いわ、間違えた IAM-3 ー クラスターとしてEC2が機能するためのアクセス権
今回はクラスター作成時に自動生成するIAM-4 ecsTaskExecutionRole Dockerコンテナのアクセス権
RDS接続許可、みたいな権限
- 用語説明
- ECR(Amazon Elastic Container Registry)
- Dockerコンテナレジストリ
- Dockerイメージの保存と取得
- マネージドサービス
- ECS(Amazon Elastic Container Service)
- コンテナオーケストレーションサービス
- マネージドサービス
- クラスターをFargateで構成するとクラスター部分の管理もAWSお任せにできる
やっていきます
1.Dockerイメージを作成する
ECSで起動するDockerコンテナのため、Dockerイメージを作成
1-1.準備(環境構築)
cloud9の作成の詳細は省略(デフォルトVPCに作成するだけ)。
cloud9には、Dockerがインストールされている。
ec2-user をdockerグループに配属させる。Cloud9-Terminal$ sudo usermod -a -G docker ec2-userDocker Composeをインストールする。
Cloud9-Terminal$ sudo curl -L "https://github.com/docker/compose/releases/download/1.25.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose $ sudo chmod +x /usr/local/bin/docker-composeIAMロール作成し、Cloud9 のEC2インスタンスにアタッチする。
IAMロール名
ecsrole
(図のIAM-1
)に適用したポリシー
AmazonEC2ContainerRegistryFullAccess
AmazonECS_FullAccess
1-2.Dockerイメージをビルドする
cloud9上でDockerイメージをビルドする。ビルドイメージ名
volumedemo
Cloud9-Terminal$ mkdir docker $ mkdir docker/volumes $ touch docker/volumes/Dockerfile $ nano docker/volumes/Dockerfile # -> 編集内容は後に記載してある $ touch docker/volumes/index.html $ nano docker/volumes/index.html # -> 編集内容は後に記載してあるDockerfileFROM centos:latest RUN yum install -y httpd COPY ./index.html /var/www/html/index.html VOLUME /var/www/html EXPOSE 80 443 CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]index.html<html><head><title>test</title></head><body><h1>TEST</h1></body></html>ビルドする
Cloud9-Terminal$ cd docker/volumes $ docker build -t volumedemo ./ # -> Successfully tagged volumedemo:latest となれば成功ビルドが成功し、Dockerイメージがつくれたか確認
Cloud9-Terminaldocker images # -> REPOSITORY名 `centos`, `volumedemo` の2つが追加されてれば成功
Dockerコンテナを起動
cloud9-Terminal$ docker run --name volumedemo -d -p 8080:80 volumedemo:latest $ docker container ls # -> NAMES `volumedemo` の STATUS が `UP xxx` となれば成功Webが開くか動作確認
Cloud9-Terminal$ curl http://localhost:8080/index.html # -> `<html><head><title>test</title></head><body><h1>TEST</h1></body></html>`と出力されたら成功1-3.ホスト側からDockerコンテナ内のファイル(html)を更新する
Dockerコンテナのマウントボリュームを確認
Cloud9-Terminal$ docker inspect {CONTAINER ID} # -> 出力結果から Mounts の情報を確認
Mounts
のSource
がホストのパス"Mounts": [ { "Type": "volume", "Name": "951214538382d48c336a02bcd34d5d61e2cb88654587ec45f14996a2cda43024", "Source": "/var/lib/docker/volumes/a02b1214538382d48c336c45fcd34d5d61e2cb88654587e9514996a2cda43024/_data", "Destination": "/var/www/html", "Driver": "local", "Mode": "", "RW": true, "Propagation": "" }ホスト側からindex.htmlを編集し、Webサイトが更新されたことを確認
Cloud9-Terminalsudo nano /var/lib/docker/volumes/a02b1214538382d48c336c45fcd34d5d61e2cb88654587e9514996a2cda43024/_data/index.html
[更新前] <html><head><title>test</title></head><body><h1>TEST</h1></body></html> [更新後] <html><head><title>test</title></head><body><h1>TEST123456789</h1></body></html>↑の手法はパス探し面倒(Cloud9はアクセス権も絡み更に面倒)
なのでホスト側の格納パスを指定してバインドマウントするCloud9-Terminal$ mkdir /home/ec2-user/environment/docker/bindmount $ touch /home/ec2-user/environment/docker/bindmount/index.html $ nano /home/ec2-user/environment/docker/bindmount/index.html # 中身 <html><head><title>test</title></head><body><h1>TEST-ABCDEFG</h1></body></html> $ docker container run --name bindmount1 -d -p 80:80 -v /home/ec2-user/environment/docker/bindmount:/var/www/html volumedemo:latest動作確認
Webサイトにアクセスして
<html><head><title>test</title></head><body><h1>TEST-ABCDEFG</h1></body></html>
となれば成功次にホスト側で /home/ec2-user/environment/docker/bindmount/index.html を編集し、Webサイトにアクセスして更新されてたら成功
2.DockerイメージをECRにpushする
作成したDockerイメージにECRの規則に沿ったタグを付与しECRにpushする
ECRでリポジトリを作成する ( リポジトリ名前
blackriverrepo
) 他の設定はデフォルト値を使用Cloud9からECSにアクセス
Cloud9-Terminal$ aws ecr get-login --no-include-email --region ap-northeast-1 # -> Dockerログインコマンドでてくる(長くてビビる)取得したDockerログインコマンドをCloud9上のターミナルで実行し、
login Succeeded
と表示でれば成功。ECRで作成したリポジトリ
blackriverrepo
を選択し、プッシュコマンドの通知
ボタンをクリックすると、基本コマンドでてくる ※ 手順1,2は実施済みECS上のリポジトリにイメージをプッシュするために、Dockerイメージにタグを付ける
Cloud9-Terminal$ docker tag volumedemo:latest xxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/blackriverrepo:latest # タグが付いたか確認 $ docker image lsECRで作成したリポジトリ
blackriverrepo
にDockerイメージをpushするCloud9-Terminal$ docker push 602744163118.dkr.ecr.ap-northeast-1.amazonaws.com/blackriverrepo:latest
ECR のリポジトリを確認し、イメージURI
xxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/blackriverrepo:latest
があれば成功Cloud9-Terminal# ECR のリポジトリはコマンドでも確認できる $ aws ecr describe-repositories --region ap-northeast-1 # コマンドでリポジトリの内容確認もできる $ aws ecr describe-repositories --region ap-northeast-1 --repository-name blackriverrepoAWSコンソールで確認するとこんな感じ
(おまけ)ECRからCloud9にDockerイメージをpullできるか確認
Cloud9-Terminal# Cloud9からのDockerイメージを消す $ docker rmi xxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/blackriverrepo # Cloud9でpullしてECRからDcokerイメージ取得 $ docker pull xxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/blackriverrepo # -> キャッシュに残ってる場合はすぐ取得できる # -> docker images で xxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/blackriverrepo があれば成功Cloud9-Terminal# pullしたイメージでDockerコンテナ起動してみる # コンテナ起動 $ docker run --name blackriver -d -p 8080:80 xxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/blackriverrepo:latest # コンテナ確認 $ docker ps -ls # Webサイト確認 $ curl http://localhost:8080/index.html3.クラスターを作成する
ECSにクラスターを作成。今回はFargate使わずEC2(linux)にする
ECSでクラスターを作成する(今回は EC2(linux) で作る) ※cloud9と同じVPCにする
- クラスターの構成
- クラスター名:cluster01
- プロビジョニングモデル:オンデマンドインスタンス
- EC2インスタンスタイプ:t2.small
- インスタンス数:2
- EC2 Ami Id:Amazon Linux 2 AMI
- EBSストレージ:22
- キーペア:{既存のキーペア指定} <- コンテナに入るなら設定しておく
- VPCはcloud9と同じデフォルトVPC
- セキュリティグループ:
新しいセキュリティグループ
- コンテナインスタンスIAMロール:
新しいロールの作成
- Tags:
Name
,ECSInstance01
設定時の画面 *クリックで拡大
作成がはじまる
ECSインスタンスが2つ
ACTIVE
になると成功4.(オプション)キャパシティープロバイダーを設定する
キャパシティープロバイダーは設定しなくてもDockerコンテナを起動できる
なので、この章(4章) はやらなくてもよい。(←これに気が付かず苦労した)キャパシティープロバイダーの設定は、ECSに作ったクラスターに対する設定
設定するには、ECSに紐づくAutoScalling側でスケールイン保護の設定が必要4-1.AutoScalling
スケールインから保護
ECSに紐づくAutoScallingを編集
インスタンス保護を設定
キャパシティの最小値は0
になっているが 1 以上にすることをオススメ
0
だと、EC2インスタンスが0になる可能性がある
EC2インスタンスが0の状態で、ECSでタスク実行すると『キャパシティーが無い』旨のメッセージがでる ※本記事のトラブルシュート参照4-2.AutoScalling
スケールイン保護の設定
所属するEC2インスタンスを選択し、
スケールイン保護の設定
を設定する4-3.ECS のクラスター
clustre01
にキャパシティー作成5.タスク定義を作成->実行する
タスク定義を作り実行すれば、Dockerコンテナが起動する。
- タスク定義とは?を粗く理解
- json形式
- コンテナ起動の設計書
5-1.タスク定義を作成
起動タイプ EC2 を選択
コンテナ追加
コンテナ名
,リポジトリのURI
,ポートマッピング
を設定こんな感じで登録される
作成する
5-2.タスク定義を実行
4.(オプション)キャパシティープロバイダーを設定する
を実施していない場合は、このような画面になる。赤枠のメッセージは、4
を実施していないため、その下の起動タイプへ切り替える
をクリックし、(今回であれば)EC2を選択すればよい。※おまけ※
4.(オプション)キャパシティープロバイダーを設定する
を実施した場合は、このように赤枠のメッセージが出ない。5-3.動作確認
Webサイトが開けば成功。
※ Cloud9(Webサイトにアクセスする環境)とクラスターに所属するEC2インスタンスが通信できるようSG(セキュリティグループ)を設定する。Dockerコンテナが起動しているEC2インスタンスのローカルIPを確認するとアクセスするURLがわかる。
Cloud9-Terminal$ curl http://{Dockerコンテナが起動しているEC2インスタンスのローカルIP}/index.html # -> 以下のような結果になれば成功 # <html><head><title>test</title></head><body><h1>TEST</h1></body></html>今回はこれでおわり
トラブルシュート
タスク実行したときにキャパシティープロバイダー戦略のエラー発生
↓赤枠のメッセージ↓
キャパシティープロバイダー戦略
クラスターのデフォルト戦略
指定されたクラスターのデフォルトのキャパシティープロバイダー戦略にキャパシティープロバイダーが含まれていません。デフォルトのキャパシティープロバイダー戦略を更新して、1 つ以上のキャパシティープロバイダーを関連付けてから、もう一度お試しください。
- <考えられる原因>
- (1) ECSに作成したクラスターにキャパシティープロバイダーの設定がない
- (2) キャパシティープロバイダーに設定したAuto Scalling に
スケールイン保護の設定
されたEC2インスタンスがない- <考えられる対策>
- (1)の対策案-1:本記事【4.(オプション)キャパシティープロバイダーを設定する】を実施しキャパシティープロバイダーを設定する
- (1)の対策案-2:
キャパシティープロバイダー
を使わない。起動タイプへ切り替える
をクリックする。本記事【5-2.タスク定義を実行】参照- (2)の対策案:本記事【4-1.AutoScalling スケールインから保護】を参照し、Auto Scalling に最低1つ
スケールイン保護の設定
されたEC2インスタンスが含まれるようにする。
- 投稿日:2020-04-06T01:10:36+09:00
DockerコンテナからAzure PowerShellを実行する
今更ながらDockerに触れてみましたのでAzure PowerShellをDockerコンテナから実行してみます。
実行環境
- WSL2(Ubuntu)
- Docker Desktop for Windows
コンテナの作成
Docker HubでMicrosoft社公式のイメージが提供されていますのでこちらを使用します。
https://hub.docker.com/_/microsoft-azure-powershell
コンテナ作成手順も公開されていますので手順に従っていきます。
https://docs.microsoft.com/ja-jp/powershell/azure/azureps-in-docker?view=azps-3.7.0まずはイメージの取得。
sudo docker pull mcr.microsoft.com/azure-powershell Using default tag: latest latest: Pulling from azure-powershell 5bed26d33875: Pull complete f11b29a9c730: Pull complete 930bda195c84: Pull complete 78bf9a5ad49e: Pull complete 3183894b4ae2: Pull complete 5d930b42a49c: Pull complete 95d0de46cc6e: Pull complete 9bab5da02730: Pull complete Digest: sha256:c06ab1162d6236b053ab425e54fb9f1feca0d6385865dd6e5c225076732007ad Status: Downloaded newer image for mcr.microsoft.com/azure-powershell:latest mcr.microsoft.com/azure-powershell:latest対話モードでコンテナを作成。
PowerShellのバージョンは7.0でした。sudo docker run -it mcr.microsoft.com/azure-powershell pwsh PS /> $PSVersionTable Name Value ---- ----- PSVersion 7.0.0 PSEdition Core GitCommitId 7.0.0 OS Linux 4.19.84-microsoft-standard #1 SMP Wed Nov 13 11:44:37 UTC 2019 Platform Unix PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…} PSRemotingProtocolVersion 2.3 SerializationVersion 1.1.0.1 WSManStackVersion 3.0
Azure PowerShellの実行
Azureにログインしてみます。
PS /> Login-AzAccount WARNING: To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code xxxxxxxx to authenticate.PowerShell Coreのため、アカウント選択前に認証が必要です。
メッセージのURLにブラウザでアクセスし認証コードを入力します。
認証コード入力後の次の画面でログインするAzureアカウントを選択してください。無事にログインできました。
Account SubscriptionName TenantId Environment ------- ---------------- -------- ----------- xxxxxxxxxx subscriptionA xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxx AzureCloudVMを起動してみます。
PS /> Start-AzVM -ResourceGroupName hoge-rg -Name hoge-vm OperationId : 02ef9231-7972-4fc8-880c-5367c0c59d37 Status : Succeeded StartTime : 4/5/2020 3:32:14 PM EndTime : 4/5/2020 3:34:31 PM Error :やったぜ(起動できました。)
まとめ
少ない手順で簡単に作成、実行できました。
イメージも公式から提供されていますので安心ですね。
次はAzure上にコンテナを作って実行してみたいと思ってます。