20200406のdockerに関する記事は15件です。

プロキシ環境下でGrowiから社内のMattermostにwebhookで通知

はじめに

どうも!生産技術部のエンジニアです。GrowiとMattermostをひとつのサーバに同居させ、社内のプロキシ環境下で、Mattermost宛てのwebhookをしようとしたところ、うまく通知が飛ばない問題がありました。解決する方法を紹介します。

環境

  • CentOS : 7.6.1810
  • Docker-CE : 19.03.1
  • Docker Compose : 1.25.0
  • Growi :以下 systeminfo.png

※現在、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/Dockerfile
ENV 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に乗り換えてくれえええ

ご参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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 ansible

sshのインストール

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 all

sshの設定

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_key

sshdの起動

sshの設定が終わったので,sshdを起動します.

systemctl start sshd.service

Dockerfileに落とし込む

上記までの内容を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で操作することができます.

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

さわっておぼえるDocker入門?#1(コンテナを作ったり壊したり)

はじめに

とにかくクジラ?がかわいいですよね。
Dockerを触りながら基本をさらっていきましょう。

目的

Dockerを触りながら、どんなことができるのか確認する

コンテナを起動したり、削除したりしながら、コンテナに慣れていきたいと思います。

今回は

  • コンテナの起動
  • コンテナの一覧を取得
  • コンテナのログを確認
  • コンテナを削除

していきます。

環境

  • macOS Mojave 10.14.6
  • Docker engine 19.03.5

まずはDockerのインストール

https://www.docker.com/

コンテナを作ったり壊したりしてみる

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_jennings

3つのコンテナが起動中です。これらを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

ID197とID704は削除できたようですが、同時にエラーメッセージが出ました。

起動中のコンテナは削除できないことがエラーの理由です。

container rm -f

-fオプションをつけることで、起動中のコンテナも強制削除することができます。

docker container rm -f 00b 

これで全てのコンテナを削除できました。

まとめ

本当に簡単なコマンドで、

  • コンテナ起動したり、
  • コンテナの一覧を取得したり、
  • コンテナのログを確認したり、
  • コンテナを削除したり

できました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

さわっておぼえるDocker入門?#1

はじめに

とにかくクジラ?がかわいいですよね。
Dockerを触りながら基本をさらっていきましょう。

目的

Dockerを触りながら、どんなことができるのか確認する

環境

  • macOS Mojave 10.14.6
  • Docker engine 19.03.5

まずはDockerのインストール

https://www.docker.com/

コンテナをアレコレしてみる

コンテナを起動したり、削除したりしながら、コンテナに慣れていきたいと思います。

今回は

  • コンテナの起動
  • コンテナの一覧を取得
  • コンテナのログを確認
  • コンテナを削除

していきます。

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_jennings

3つのコンテナが起動中です。これらを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

ID197とID704は削除できたようですが、同時にエラーメッセージが出ました。

起動中のコンテナは削除できないことがエラーの理由です。

container rm -f

-fオプションをつけることで、起動中のコンテナも強制削除することができます。

docker container rm -f 00b 

これで全てのコンテナを削除できました。

まとめ

本当に簡単なコマンドで、

  • コンテナ起動したり、
  • コンテナの一覧を取得したり、
  • コンテナのログを確認したり、
  • コンテナを削除したり

できました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

よく使う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

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Docker debian系imageでterminalの日本語入力環境のタレ

Dockerのdebian系イメージで日本語入力環境を作るレシピ。
ちなみに、Dockerのimageの基本はdebianから作ることを公式が推奨しており、大抵はdebianイメージのextendである。

私がよく使うnode imageもそう。ruby imageも多分そうだった気がする。

Dockerfile
FROM 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以外も入りそう。私は容量より設定の容易さを優先してこの方法にした。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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

事前準備

  • 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-meet

Jisti 環境変数用ファイル .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                                  latest              

Docker 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」を押せば大丈夫です。

image.png

音声、動画、テキストでのチャットだけでなく、画面共有機能もあります。

Screenshot_2020-04-07 Jitsi Meet(1).png

Enjoy!

その他、今後の考慮点など

  • 必要に応じてファイアウォール等は検討。このままだと、URLが分かるので誰でもアクセスできてしまう
  • Jitsi には認証機能があるようなので、それも試してみたいところ
  • 利用者が増えた時のネットワーク帯域を計測しないと
  • 長期運用する場合、このまま Compose でよいのだろうか
  • 拡張機能として、録画、文章共有、ディクテーション機能があるので試したい

参考情報

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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

Docker イメージの参照

まずは 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.0dev10

PowerShell 関数として定義

以降のコマンドを簡略化するため、コマンドを関数として定義します。まずは 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.0dev10

AWS への接続設定

次に、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 test

S3 上にバケットが存在していれば、その一覧が応答で返ってきます。これにより、AWS サービスとの接続が確認できました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Docker amazonlinux2 で systemctl を使いたい人生だった

TLDR;

Dockerfile
FROM amazonlinux:2

RUN yum update -y \
    && yum install systemd-sysv -y

CMD ["/sbin/init"]
docker-compose.yml
version: "2"
services:
  web:
    image: amazonlinux:2
    build: .
    container_name: al2c
    privileged: true
    ports:
      - 8080:80
$ docker-compose up --build -d

amazonlinux2では systemctl がデフォルトでは使えない

amazonlinux2のコンテナを普通に立ち上げただけだと、 systemctl は使えない。
コマンド自体は存在する様だが、権限がないよーと怒られる。

Failed to get D-Bus connection: Operation not permitted

色々情報を読み齧った結果、次の要素が必要であることがわかった。

  • privileged を有効にする
  • /sbin/init で起動する

チャレンジその1

じゃぁこれでいけるだろう。 privilegedtrue にして起動コマンドに /sbin/init を設定した。

docker-compose.yml
version: "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)もこちらに移動した。

Dockerfile
FROM amazonlinux:2

RUN yum update -y \
    && yum install systemd-sysv -y

CMD ["/sbin/init"]
docker-compose.yml
version: "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
...

無事動いたみたいです。:raised_hands:

nginxとかでもよさそう

上では systemd-sysv を入れていますが、 nginx を入れただけでも依存パッケージの解決でいけました。多分 apache でもいけるんじゃないかな、試してませんが。どうせいずれかは入れると思うので、それならそれでよろしいのではないかと存じます。

Dockerfile
FROM amazonlinux:2

RUN yum update -y \
    && amazon-linux-extras install nginx1

CMD ["/sbin/init"]

Amazon Linux では、 nginxamazon-linux-extras コマンドでインストールできます。

お世話になった記事

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

その 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.yaml
version: '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 0

Docker Compose は「複数のコンテナを一気に起動するために使うもの」と思われているかもしれませんが、上記のように docker-compose.yaml に docker run コマンドのオプションをまとめておくという使い方もできます。

任意のコマンドを実行可能にした docker-compose.yaml

シェルスクリプトの場合のように実行時に command を切り替えたい場合、環境変数を使えば実現できます。

docker-compose.yaml
version: '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.yaml
version: '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.yaml
version: '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 は便利ですが、使い方によっては面倒になることもあります。少しでも楽に使っていきましょう。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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

It should be simply done by below command.

upgrade
git pull origin master
./install.sh

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

First 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`.sql

Let's prune volume and then reinstall.

reinstall
$ docker volume prune
$ ./install.sh

Let'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+D

Finally restore data.

Restore
$ cat <backup file>.sql | docker exec -i onpremise_postgres_1 psql -U postgres
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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へ接続する時に使う環境変数が文字列に変換されてしまっているのだろう。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS Lambdaでgitコマンドを使う

AWS Lambdaでgitコマンドを使う

AWS Lambdaでgitコマンドを使いたい場合があります。
githubのAPIを呼んだり、dulwichを使ってもいいのですが、新しく勉強するよりは、できれば、いつもの使い慣れたgitコマンドを使いたいものです。

使う物

AWS Lambda用にコマンドとライブラリをいい感じにまとめてくれるDockerコンテナ
https://hub.docker.com/r/qualitiaco/lambda-build-pack

gitコマンドとライブラリを抽出

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

AWS Lambdaにアップロードする

Lambda Functionの作成

今回はPythonで作成してみます。
さっきできたoutputディレクトリの中に作成します。

output/lambda_function.py
import 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で確認することはできません。

実行すると、

lambda1.png

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さんに作成して頂きました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS ECR/ECS 勉強メモ① Dockerコンテナ起動

やること

Cloud9環境でDockerイメージをビルドして
ECRにDockerイメージをpushして
ECSでDockerコンテナを起動する

参考リンク

構成

今回つくる環境

構成図

  • 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接続許可、みたいな権限

line.png

  • 用語説明
  • ECR(Amazon Elastic Container Registry)
    • Dockerコンテナレジストリ
    • Dockerイメージの保存と取得
    • マネージドサービス
  • ECS(Amazon Elastic Container Service)
    • コンテナオーケストレーションサービス
    • マネージドサービス
    • クラスターをFargateで構成するとクラスター部分の管理もAWSお任せにできる

やっていきます

1.Dockerイメージを作成する

ECSで起動するDockerコンテナのため、Dockerイメージを作成

図2.png

1-1.準備(環境構築)

cloud9の作成の詳細は省略(デフォルトVPCに作成するだけ)。
cloud9には、Dockerがインストールされている。
ec2-user をdockerグループに配属させる。

Cloud9-Terminal
$ sudo usermod -a -G docker ec2-user

Docker 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-compose

IAMロール作成し、Cloud9 のEC2インスタンスにアタッチする。

image.png

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
# -> 編集内容は後に記載してある
Dockerfile
FROM 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-Terminal
docker 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 の情報を確認

MountsSource がホストのパス

"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-Terminal
sudo 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する

2.DockerイメージをECRにpush

ECRでリポジトリを作成する ( リポジトリ名前 blackriverrepo ) 他の設定はデフォルト値を使用

image.png

Cloud9からECSにアクセス

Cloud9-Terminal
$ aws ecr get-login --no-include-email --region ap-northeast-1
# -> Dockerログインコマンドでてくる(長くてビビる)

取得したDockerログインコマンドをCloud9上のターミナルで実行し、login Succeeded と表示でれば成功。

ECRで作成したリポジトリ blackriverrepo を選択し、プッシュコマンドの通知 ボタンをクリックすると、基本コマンドでてくる ※ 手順1,2は実施済み

image.png

ECS上のリポジトリにイメージをプッシュするために、Dockerイメージにタグを付ける

Cloud9-Terminal
$ docker tag volumedemo:latest xxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/blackriverrepo:latest
# タグが付いたか確認
$ docker image ls

ECRで作成したリポジトリ 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 blackriverrepo

AWSコンソールで確認するとこんな感じ

image.png

(おまけ)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.html

3.クラスターを作成する

ECSにクラスターを作成。今回はFargate使わずEC2(linux)にする

3.クラスターを作成

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

設定時の画面 *クリックで拡大

作成がはじまる

image.png

ECSインスタンスが2つACTIVEになると成功

image.png

4.(オプション)キャパシティープロバイダーを設定する

キャパシティープロバイダーは設定しなくてもDockerコンテナを起動できる
なので、この章(4章) はやらなくてもよい。(←これに気が付かず苦労した)

キャパシティープロバイダー

キャパシティープロバイダーの設定は、ECSに作ったクラスターに対する設定
設定するには、ECSに紐づくAutoScalling側でスケールイン保護の設定が必要

4-1.AutoScalling スケールインから保護

ECSに紐づくAutoScallingを編集

image.png

インスタンス保護を設定
キャパシティの最小値は 0 になっているが 1 以上にすることをオススメ
0だと、EC2インスタンスが0になる可能性がある
EC2インスタンスが0の状態で、ECSでタスク実行すると『キャパシティーが無い』旨のメッセージがでる ※本記事のトラブルシュート参照

image.png

4-2.AutoScalling スケールイン保護の設定

所属するEC2インスタンスを選択し、スケールイン保護の設定を設定する

image.png

4-3.ECS のクラスター clustre01 にキャパシティー作成

image.png

image.png

image.png

image.png

5.タスク定義を作成->実行する

タスク定義を作り実行すれば、Dockerコンテナが起動する。

  • タスク定義とは?を粗く理解
    • json形式
    • コンテナ起動の設計書

5.タスク定義を作成->実行

5-1.タスク定義を作成

image.png

起動タイプ EC2 を選択

image.png

image.png

image.png

コンテナ追加
コンテナ名, リポジトリのURI, ポートマッピング を設定

image.png

こんな感じで登録される

image.png

作成する

image.png

5-2.タスク定義を実行

image.png

4.(オプション)キャパシティープロバイダーを設定するを実施していない場合は、このような画面になる。赤枠のメッセージは、4を実施していないため、その下の起動タイプへ切り替えるをクリックし、(今回であれば)EC2を選択すればよい。

image.png

※おまけ※ 4.(オプション)キャパシティープロバイダーを設定するを実施した場合は、このように赤枠のメッセージが出ない。

image.png

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>

今回はこれでおわり

line.png

トラブルシュート

タスク実行したときにキャパシティープロバイダー戦略のエラー発生

image.png

↓赤枠のメッセージ↓

キャパシティープロバイダー戦略
クラスターのデフォルト戦略
指定されたクラスターのデフォルトのキャパシティープロバイダー戦略にキャパシティープロバイダーが含まれていません。デフォルトのキャパシティープロバイダー戦略を更新して、1 つ以上のキャパシティープロバイダーを関連付けてから、もう一度お試しください。

  • <考えられる原因>
    • (1) ECSに作成したクラスターにキャパシティープロバイダーの設定がない
    • (2) キャパシティープロバイダーに設定したAuto Scalling にスケールイン保護の設定されたEC2インスタンスがない
  • <考えられる対策>
    • (1)の対策案-1:本記事【4.(オプション)キャパシティープロバイダーを設定する】を実施しキャパシティープロバイダーを設定する
    • (1)の対策案-2:キャパシティープロバイダーを使わない。起動タイプへ切り替えるをクリックする。本記事【5-2.タスク定義を実行】参照
    • (2)の対策案:本記事【4-1.AutoScalling スケールインから保護】を参照し、Auto Scalling に最低1つスケールイン保護の設定されたEC2インスタンスが含まれるようにする。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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 AzureCloud

VMを起動してみます。

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上にコンテナを作って実行してみたいと思ってます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む