- 投稿日:2021-03-14T23:50:49+09:00
ポータブルなGlusterFSコンテナを作成する(レプリカ数2の場合)
1. はじめに
複数のサーバでコンテナを運用する際、コンテナ内で動作するアプリケーションが保存するファイルをどのように保持するかを考える必要があります。Kubernetesでは、CephやGlusterFSなどの分散ストレージが利用できます。この記事では、十数台程度の小規模なオンプレミスのdocker実行環境で、GlusterFSによるデータ保持機構を構築するときに検討した内容をまとめたものです(下図のように、コンテナの参照先をファイルサーバにすることで、どのサーバでコンテナが稼働しても同じデータを参照できます。)。
記事にまとめるにあたり、「オンプレミスな環境で0からGluster側の構築を如何に簡単に行うか」に焦点を当てるため、以降の説明ではアプリケーションサーバは1台、Glusterサーバは2台とします。
2. ねらい
参考1:GlusterFS Containers
参考2:Official GlusterFS Image [ CentOS-7 + GlusterFS ]
- 本番環境の構築を易化するため、Glusterサーバはコンテナで構築する。検証として、Glusterコンテナは、Officialのものを活用する。
- 本番環境は、ホスト側にネットワークが構築された環境であり、参考1にあるよう本番環境では、--net=hostオプションを使用する。ただし、開発環境で常に2サーバ用意するのは手間なので、開発環境ではdokcer networkを用いて本番環境を模擬する。(ネットワークアドレスは仮のものです)
3. 検討
3.1. 基本的なこと
- 本番環境のGlusterサーバのホスト名は、それぞれserver1とserver2とする。
- Glusterコンテナの内部ホスト名は、gluster-server-1とgluster-server-2とする。
- 参考1より、Glusterコンテナは/sbin/initで起動し、glusterdをサービス起動する。D-Bus関連のサービスはdisableとなっているが、privilegedオプションを使用する。
- systemdを使用する関係で、CMD設定を/sbin/initから変更できないので、entry-pointを仕込むためにentry-point.service(このサービスでentry-point.shを呼び出す)を設定する。
- Glusterのボリューム名はVOL1とし、それぞれ/home/HDD1にBrickを作成する。
3.2. Glusterの設定を構築し、コンテナイメージに組み込む方法
参考3:CentOS7でGlusterFSの環境構築
* 開発環境に、以下のようなdocker-compose.ymlでコンテナを構築する。マウントディレクトリの選定は、参考1で示されたディレクトリに加えて、Brickの隠しディレクトリがあるHDD1を指定している。version: "3.7" services: gluster-server-1: hostname: gluster-server-1 image: gluster/gluster-centos:gluster3u10_centos7 volumes: - ${PWD}/volume/gluster-server-1/etc-glusterfs:/etc/glusterfs - ${PWD}/volume/gluster-server-1/var-lib-glusterd:/var/lib/glusterd - ${PWD}/volume/gluster-server-1/HDD1:/home/HDD1 extra_hosts: - "gluster-server-2:192.168.3.20" privileged: true networks: app_net: ipv4_address: 192.168.3.10 gluster-server-2: hostname: gluster-server-2 image: gluster/gluster-centos:gluster3u10_centos7 volumes: - ${PWD}/volume/gluster-server-2/etc-glusterfs:/etc/glusterfs - ${PWD}/volume/gluster-server-2/var-lib-glusterd:/var/lib/glusterd - ${PWD}/volume/gluster-server-2/HDD1:/home/HDD1 extra_hosts: - "gluster-server-1:192.168.3.10" privileged: true networks: app_net: ipv4_address: 192.168.3.20 networks: app_net: name: app_net driver: bridge ipam: driver: default config: - subnet: 192.168.3.0/24
- docker-compose up -dでコンテナ起動後、参考3に従って設定を行う。この設定を行うことで、必要なコンフィグファイルをマウントディレクトリに格納される。
- docker buildでコンテナイメージ内に組み込むのだが、設定ファイルを以下のように配置する。リンク作成やディレクトリ移動は、起動時に呼ばれるentry-point.serviceを組み込み、その中で実施する。
- Dockerfileは以下のように作成した。
FROM gluster/gluster-centos:gluster3u10_centos7 COPY ./volume /tmp/volume COPY ./script /tmp/script RUN systemctl disable glusterd.service; systemctl disable gluster-setup.service; \ mkdir -p /home/gluster; \ mv /tmp/volume/gluster-server-1 /home/gluster/; mv /tmp/volume/gluster-server-2 /home/gluster/; \ mkdir -p /home/HDD1; \ mv /tmp/script/entry-point.service /etc/systemd/system/; \ systemctl enable entry-point.service; \ mv /tmp/script/entry-point.sh /entry-point.sh; \ rm -rf /tmp/*
- entry-point.shは以下のように作成した。
#!/bin/bash function main() { echo "entry-point start." > /tmp/start.log # delete default gluster setting rm -rf /etc/glusterfs rm -rf /var/lib/glusterd # gluster-server-1 ? echo $HOSTNAME | grep "gluster-server-1" >/dev/null local ret=$? local gluster="" if [ $ret = "0" ]; then gluster="gluster-server-1" fi # gluster-server-2 ? echo $HOSTNAME | grep "gluster-server-2" >/dev/null ret=$? if [ $ret = "0" ]; then gluster="gluster-server-2" fi mv /home/gluster/$gluster/etc-glusterfs /etc/glusterfs mv /home/gluster/$gluster/var-lib-glusterd /var/lib/glusterd local init_flag="0" if [ -d /home/HDD1/.glusterfs ]; then # non-first start echo "exist /home/HDD1/.glusterfs" >>/tmp/start.log else # first start echo "no exist /home/HDD1/.glusterfs" >>/tmp/start.log echo "mv /home/gluster/$gluster/HDD1/.glusterfs /home/HDD1/" >>/tmp/start.log mv /home/gluster/$gluster/HDD1/.glusterfs /home/HDD1/ init_flag="1" fi sleep 1 # starting glusterd systemctl restart glusterd if [ $init_flag != "0" ]; then sleep 10 # gluster force-restart echo "gluster vol start VOL1 force" >>/tmp/start.log gluster vol start VOL1 force fi echo "entry-point started." >>/tmp/start.log return 0 } main exit 03.3 本番環境へデプロイする設定
- 実行環境で動作させるためのdocker-compose.ymlを以下のように作成し、コンテナイメージのsaveデータを展開して動作させる。(コンテナイメージ名は適当につけているため、docker build時に適切な名前を設定すること。)
version: "3.7" services: gluster-server-1: hostname: gluster-server-1 image: my-gluster:0.0 volumes: - ${PWD}/HDD1:/home/HDD1 - ${PWD}/log:/var/log/glusterfs extra_hosts: - "gluster-server-1:192.168.3.10" - "gluster-server-2:192.168.3.20" privileged: true network_mode: host gluster-server-2: hostname: gluster-server-2 image: my-gluster:0.0 volumes: - ${PWD}/HDD1:/home/HDD1 - ${PWD}/log:/var/log/glusterfs extra_hosts: - "gluster-server-1:192.168.3.10" - "gluster-server-2:192.168.3.20" privileged: true network_mode: host3.4 プロジェクトの全体構成
上記の情報をまとめると、以下のような構成となった。setupが開発環境で構築する内容で、deployが本番環境の設定をまとめるところ、としている。
4. まとめ
自分がこの構成を検討するとき、なかなかGlusterの設定内容をコンテナイメージ内に組み込んでデプロイする事例が見つからなかったため、備忘録として記事にまとめてみました。コンテナ内でglusterを起動するときに、事前にコンフィグを移動したり、強制起動し直す、といったハマるポイントがあったので注意が必要です。
また、検証の側面が強かったので、IPアドレスとかの設定が直書きです。そのあたりを環境変数にするなど、実際にデプロイするものに仕上げるにはもう少し改良が必要です。
- 投稿日:2021-03-14T23:48:43+09:00
HostとContainerの繋がり
【HostとContainerの繋がり】
かめさん いつもありがとうございます。
米国AI開発者がゼロから教えるDocker講座・ファイルシステムの共有
・ファイルへのアクセス権限
・ポートを繋げる
・コンピュータリソースの上限→ $docker run コマンド時のオプションで設定
ホストのファイルシステムをコンテナにマウント
-v < host/path >:< container/path >オプション
HostのファイルシステムにあるcodeをContainerにあるかのように扱える。
これによって、Containerのファイルが大きくならない。$ cd ~/Documents
$ mkdir mounted_folder
$ touch mounted_folder/file_at_host
$ docker build .
$ docker run -it -v ~/Documents/mounted_folder:/new_dir < image > bash
$ ls /new_dirユーザIDとグループIDを指定してコンテナをrunする
-u < user id >:< group id >オプション
Containerを起動する時にrootじゃなくて、指定したユーザIDとグループIDでrunをするようにする。
セキュリティを向上させる。$ cd ~/Documents
$ docker build .
$ docker run -it -u 501:20 -v ~/Documents/mounted_folder:/created_in_run < image > bash
$ touch /created_in_Docker/sample_file
$ touch /created_in_run/sample_fileホストのポートをコンテナのポートに繋げる
-p < host_port >:< container_port >オプション
コンテナをWebサービスとして立てるといった使い方はよくさせる。
HostのポートからContainerのポートにアクセス(publish)するために繋げる必要がある。$ docker run -it -p 8888:8888 --rm jupyter/datascience-notebook bash
$ jupyter notebookコンテナがアクセスできる上限のCPU、メモリを設定
コンテナがアクセスできる上限のCPUを設定
→ --cpus < # ofCPUs >コンテナがアクセスできる上限のメモリを設定
→ --memory < byte >$ docker run -it --rm --cpus 4 --memory 2g ubuntu bash
$ docker ps
$ docker inspect < container >
→ コンテナの詳細を表示する。
$ docker inspect < container > | grep -i < something >補足
1 K byte = 1024 byte
1 M byte = 1024 * 1024 byte
1 G byte = 1024 * 1024 * 1024 byte※1024 = 2^10
- 投稿日:2021-03-14T23:23:44+09:00
docker内でGem(特にbundler)のdefault設定を解除したい!
概要
ローカル環境でも厄介なGemのdefault設定。
「このバージョンのGemで運用していきたいのに!」といった気持ちに反して、bundle installすると、default設定されたバージョンでインストールされてしまう。。。ローカル環境ではその解除はできるが、Dockerのコンテナ内では少しだけ訳が違ったので、まとめたいと思い本記事を制作しました。
不足点、誤りがあれば遠慮なくご指摘いただけますと幸いです。
経緯
これまでローカル環境にて開発を行い、いざ本番環境へデプロイ!となるとエラーが返され、苦い思いをしてきた私。
今回はdocker-compose up
で立ち上げたコンテナ内でgem list
を見ると、ローカルでのgem list
とバージョンの違いが生じていました。
そこで、コンテナ内でも指定したバージョンのGemで運用したく奮闘したのが経緯です。方法
①コンテナ内に入る
ローカルにて自身のアプリのディレクトリにて
% docker-compose exec web bash root@コンテナID:/アプリ名# 以降プロンプト以外は省略します②Gemを確認(省略可能)
# gem list bundler ※ちなみに全てのGemをリスト化するには"bundler"を省略 *** LOCAL GEMS *** bundler (2.1.4, default: 1.17.2)**この忌々しいdefaultを解除していきます。
③default設定されているGemのありかを探る。
# gem environment RubyGems Environment: ...略 - INSTALLATION DIRECTORY: /usr/local/bundle - USER INSTALLATION DIRECTORY: /root/.gem/ruby/2.6.0 ...略 - GEM PATHS: - /usr/local/bundle - /root/.gem/ruby/2.6.0 - /usr/local/lib/ruby/gems/2.6.0 ...略ここでちなみにローカルで同様に
gem environment
コマンドを実施した時の結果を下記に記します。% gem environment RubyGems Environment: ...略 - INSTALLATION DIRECTORY: /Users/ユーザー/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0 - USER INSTALLATION DIRECTORY: /Users/ユーザー/.gem/ruby/2.6.0 ...略 - GEM PATHS: - /Users/ユーザー/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0 - /Users/ユーザー/.gem/ruby/2.6.0 ...略INSTALLATION DIRECTORYに注目してください。
指定されているディレクトリがわずかに違います。
⑤の項目にてさらに解説します。④ホームに戻る
# cd root@コンテナID:~#⑤default設定のあるディレクトリまでたどり着く
ここで、ローカル環境でのたどり着き方の場合は、INSTALLATION DIRECTORYに記載されているパスまで
cdコマンド
で行けばいいのですが・・・ローカルの場合!
% cd /Users/ユーザー/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0 ユーザー@PC 2.6.0 %コンテナ内の場合!!
# cd /usr/local/lib/ruby/gems/2.6.0 root@コンテナID:/usr/local/lib/ruby/gems/2.6.0#INSTALLATION DIRECTORYに記載されているパスでは「そんなディレクトリは無い!!」と怒られたので、別のディレクトリを探したところ,
GEM PATHSに記載のあったディレクトリが正解だったようです。⑥specificationsの中のdefaultを削除する
lsコマンド
を使ってみると、このディレクトリの中にspecifications
というディレクトリがあるはずです。
この中にdefault設定があります。
※気になる方はここで、cd specifications
して、lsコマンド
をすると、default
と記載のあるGemがいくつかあると思います。# rm -rf specifications/default/これでspecifications内のdefaultディレクトリが全て削除されます。
⑦念の為、確認。
# gem list bundler *** LOCAL GEMS *** bundler (2.1.4)bundlerのdefaultが解除されています。
ここでbundle installし、Gemfile.lockを確認すると最後の行に・・・BUNDLED WITH 2.1.4と、自分の好きなバージョンでバンドルされていることが確認できました!
考察
ここで学んだことが2つあります。
まず1つ
当然ではありますが、ローカル環境とコンテナ環境は別物。Gemのバージョンの相違に気づけたこと。もう1つ
同じgem environment
に返される結果は、似てこそあれども微妙な違いがあること。
自分の求める情報はどこに記載があるのか注視しなければならない。これまでデプロイの時に何かしらのエラーに叩きのめされていたので、docker使用時に未然にGemのバージョンを合わせれて良かったと思います。
誰かの参考になれば幸いです。
ありがとうございました。
- 投稿日:2021-03-14T22:42:22+09:00
Dockerfileのコマンドについてなるべくわかりやすく説明する
はじめに
先日、Dockerfileを真面目に書く機会があったので、そこで色々と調べ理解したことを少し書き記します。
前提
以下の記事でDockerおよびDockerfileの概念を理解していること。
なお、ここでは冷凍チャーハンの種類はあんかけチャーハンとします。
Dockerfileのコマンド一覧
Dockerfileの主要なコマンドを以下に示します。
コマンド 説明 イメージ FROM <image>
ベースイメージを指定 冷凍チャーハンに使うお米の種類を指定 RUN <command>
コマンドを実行 卵・ネギ等を追加/調味料を投入 CMD [<command1>, <command2>,...]
コンテナ立上げ時にコマンドを実行 ラップを外す LABEL <key>=<value>
イメージにメタデータを追加 賞味期限を刻印 EXPOSE <port>
外部に公開するポートを設定 食べる時に使う食器を設定 ENV <key>=<value>
環境変数を設定 加熱温度・時間、冷凍温度・時間等を設定 COPY <frompath> <topath>
ホストからイメージにファイル/ディレクトリをコピー あんかけをチャーハンに追加 WORKDIR <dir>
コマンド実行時のディレクトリを指定 調理に使う鍋を固定 マルチステージビルド
最終的なイメージの容量を抑えられるメリットが得られるDockerfileの書き方です。
例えば、Vue.jsで作ったアプリをnginxで公開するためにDockerfileを書く場合、1つのDockerfileの中で
- Vueアプリビルドイメージ作成ステージ
- ビルド成果物デプロイ用イメージ作成ステージ
のように複数のステージを定義でき、デプロイ用イメージにはビルドされた最低限のリソースしか含まれなくなることでイメージ容量の削減につながるという具合です。(参考: Vue.js アプリケーションを Docker 化する)
チャーハンを炒めている鍋にあんかけの材料をぶち込んでそこであんかけチャーハンにしていたのを、チャーハンを炒める鍋とは別の鍋であんかけを作って、完成したあんかけを完成したチャーハンにかけることができ、カロリーも抑えられるということですね。
RUN cd <dir>
とWORKDIR <dir>
どちらも作業ディレクトリを指定するという意味では同じですね。ただ、例えばcentosのベースイメージにnginxをバージョン指定(1.18.0とする)でインストールするためにソースからビルドする場合、深く考えずに
Dockerfile(抜粋)RUN cd /usr/local/src RUN curl -O https://nginx.org/download/nginx-1.18.0.tar.gz RUN tar xvzf nginx-1.18.0.tar.gz RUN cd nginx-1.18.0 RUN ./configure RUN make RUN make installとかかいて
docker build
しようとすると、/bin/sh: ./configure: No such file or directoryとなったりします。
このとき、curlでファイル取れてない?とかtarで解凍失敗した?とか色々考えるんですが、実際には4行目で /nginx-1.18.0 に移動できていないことが原因だったりします。RUN cd nginx-1.18.0
とだけ書いてしまうと、/nginx-1.18.0
を一瞬覗いただけで実際には移動しておらず、その後のコマンドはカレントディレクトリで実行されてしまうため、configureなんてファイルないよ、と言われているという次第です。
(なので一行目のcdも機能しておらず、結果的に全てのコマンドが/
で実行されている形になっています)こんなときに、
WORKDIR
を用いて、Dockerfile(抜粋)WORKDIR /usr/local/src RUN curl -O https://nginx.org/download/nginx-1.18.0.tar.gz RUN tar xvzf nginx-1.18.0.tar.gz WORKDIR /usr/local/src/nginx-1.18.0 RUN ./configure RUN make RUN make installみたいに書きかえてあげるとちゃんとディレクトリを渡り歩いてうまく動いてくれます1。
ちなみに、RUN cd
を使って4行目以降をRUN cd /usr/local/src/nginx-1.18.0 && ./configure && make && make installのように書くこともできます。
というか、私は見栄え的にWORKDIRを使う書き方をしていたのですが、どうやらRUN
を書くとその都度イメージのレイヤーが作られて容量が増えてしまうので、RUN cd
を使った例のようにコマンドを&&
で繋げてレイヤを節約するのが推奨されてるようです。いずれにせよ調理鍋を固定してから卵を割るか鍋をとったらすかさず卵を割ることで、卵を無駄にしないようにしましょう。
終わりに
気を抜くと冷凍チャーハン製造工場の動画をみていました。目的を見失わないように引き続き精進していきたいです。
- 投稿日:2021-03-14T20:31:40+09:00
【実験】Dockerを使用してGitLabを構築してみる part1
今回は仮想化技術である「コンテナ化」の代表的なプラットフォームであるDockerを使用してGitLabを構築してみます。
恐らく長くなりそうなので、複数回に分けて投稿予定です。
加えて今回は実施しませんが次回以降に以前使用していたGitLabとデータの共有を出来るように設定したいと思います。事前準備
まずはサーバーにDockerをインストールします。
以下のコマンドでインストールを行います。sudo yum -y install dockerインストール完了後、起動と自動起動の有効化を行います。
sudo systemctl start docker sudo systemctl enable docker sudo systemctl status dockerDockerを起動後、テスト用イメージである
hello-world
を取得します。
プル完了後、docker images
コマンドでイメージが追加されたか確認します。※以降、sudo省略 docker images docker pull hello-world docker images #正常にプル出来ていればlatestというタグ名のイメージが存在している取得の確認が出来たら、上記イメージはもう不要なので、削除します。
削除は以下のコマンドで実行します。docker images #削除対象のIMAGE IDを確認する docker rmi <削除対象IMAGE ID> docker images #削除されているか確認する以上で動作確認を含めた事前準備は完了です。
GitLabイメージの取得・インストール
GitLabの取得は以下のコマンドで実施出来ます。
docker pull gitlab/gitlab-ce docker images #表示結果にgitlab-ceが存在していれば正常にプル完了続いてGitLabのインストールを実施しますが、その前にGitLabの各種ファイルを保存するローカル環境変数を指定します。
mkdir /srv/gitlab export GITLAB_HOME=/srv/gitlab準備が整いましたら、以下のコマンドでGitLabのインストールを行います。
docker run --detach \ --hostname gitlab.example.com \ --publish 443:443 --publish 80:80 --publish 22:22 \ --name gitlab \ --restart always \ --volume $GITLAB_HOME/config:/etc/gitlab \ --volume $GITLAB_HOME/logs:/var/log/gitlab \ --volume $GITLAB_HOME/data:/var/opt/gitlab \ gitlab/gitlab-ce:<タグ名(変更していなければlatest)>上記コマンド実行後すぐにプロンプトに戻ります。
現在のインストール状況を知りたい場合は以下のコマンドを実行し、そのまましばらく待ちます。
プロンプトへ戻りましたら完了です。docker logs -f gitlabトラブルシュート
インストール時にぶち当たったトラブルとその回避策を残します。
ポート番号の重複
もし以下のようなエラーが返ってきた場合は、GitLabインストールコマンドのうち、「--publish 22:22」の部分を「--publish <任意のポート番号>:22」といった形で変更します。
当然のことながら指定するポート番号はウェルノウンポート(0~1023)以外でなおかつ使われていないポート番号を指定します。Error response from daemon: driver failed programming external connectivity on endpoint gitlab-ce (~省略~): Error starting userland proxy: listen tcp 0.0.0.0:22: bind: address already in use.謎のパーミッション拒否
docker logs -f gitlab
コマンド実行中に、permission deniedといったメッセージが表示されてプロンプトに戻される場合がありますが、これはSElinuxの仕業です。
対処方法としてはSElinuxを無効にするか、インストールコマンドの--volumeの値の後ろに以下のように:Z
を追加します。~中略~ --volume $GITLAB_HOME/config:/etc/gitlab:Z \ --volume $GITLAB_HOME/logs:/var/log/gitlab:Z \ --volume $GITLAB_HOME/data:/var/opt/gitlab:Z \ ~以下略~インストール失敗によるプロセス名重複
一度エラーでインストールが失敗すると、プロセスが不完全な状態で起動されてしまうので、そのまま再度インストールしようとすると同名プロセスが存在しているといったエラーで弾かれます。
そんな時は以下の流れでゴミプロセスを削除します。docker ps -a #gitlabプロセスが存在している docker rm -f gitlab docker ps -a #gitlabプロセスが消えていればOKプロセスの削除完了後、念の為GitLab関連のディレクトリも全て削除しておきます。
rm -rf /srv/gitlab/config/ rm -rf /srv/gitlab/data/ rm -rf /srv/gitlab/logs/インストール処理が無限ループする(原因不明)
こちらは原因不明ですが、同じ処理を延々と繰り返している状態となります。
どこから発生しているか正確にはわかりませんが、以下のlogが起点となりそれ以降延々と繰り返しているように見受けられます。Running handlers: Running handlers complete Chef Infra Client finished, 526/1456 resources updated in 04 minutes 21 seconds Notes: It seems you haven't specified an initial root password while configuring the GitLab instance. On your first visit to your GitLab instance, you will be presented with a screen to set a password for the default admin account with username `root`. gitlab Reconfigured! Checking for an omnibus managed postgresql: OK Checking if postgresql['version'] is set: OK Checking if we already upgraded: OK The latest version 12.5 is already running, nothing to do ==> /var/log/gitlab/sshd/current <== ~以降ループ発生~対処方法としては、まず一度
ctrl + c
でdocker logs -f gitlab
を中断し、続けて以下のコマンドでreconfigureを手動実行します。docker exec -it gitlab gitlab-ctl reconfigure ※「gitlab Reconfigured!」と表示された次の行でプロンプトに戻れば成功GitLabインストール実行時にそのままreconfigureを実行する流れのようですが、どういう訳かそれだとうまく行かないようです。
GitLabのweb画面にアクセス
インストール完了後、ブラウザにて
http://<サーバーのIPアドレス>
へアクセスします。
rootパスワードの設定画面が表示されれば無事成功です。
rootパスワードを設定し、ログイン画面に移行します。
ログインができて以下の画面が表示されていればGitLabインストールの一連の流れは完了です。
今回はここまでです。
次回へ続きます。
- 投稿日:2021-03-14T17:27:43+09:00
生のPHPとLaravelの、二通りの類似ポートフォリオを作った話
はじめに
こんにちは、おーもとと申します。エンジニアに転職をするため学習している初学者です。
私は車が好きで、「近年の若者の車離れ」という問題にフォーカスしたアプリを制作しようと思いました。制作背景
若者が車を持たない理由には様々な理由があると思いますが、
「欲しいと思えるほど魅力を感じる車に出会っていないからなのでは?」
と思い、
・かわいいやかっこいいというスタイル
・大きさ
・国産か外車か
・アウトドアや街乗りという用途
これらの項目に当てはまる車を、結果として表示するアプリを制作することにしました。
(これらの特徴は全て私が定めているため、投票などにより特徴を決める機能をつけたいです)11月 PHPでアプリ開発
10月からPHPの学習を始めていたので、そのアプリはPHPで制作しました。
カーセンサーAPIを使用して、車の情報を取得します。
解説動画:https://www.youtube.com/watch?v=ZXbgUtjxKM8
機能
ユーザー登録関連
⚪︎ ログイン
⚪︎ ログアウト
⚪︎ 新規登録
⚪︎ ユーザー件数を表示車の検索機能
⚪︎ 車の見た目→「かわいい」「かっこいい」「シンプル」「おしゃれ」「レトロ」
⚪︎ 車のサイズ→「ふつう」「すごくおおきい」「おおきい」「ちいさい」
⚪︎ 車の製造国→「国産車」「外車」
⚪︎ 車の用途 →「街乗り」「アウトドア」「スポーツ」カーセンサーAPI連携
⚪︎ DBにある車情報と合致した車情報を取得
⚪︎ cronでキャッシュファイル自動生成苦労した点
検索結果の画像表示高速化
検索の度にAPIからデータを取得していたので、電波の悪い場所では結果の表示に1分以上かかっていました。
毎日APIからデータを自動取得しキャッシュ化することで、ユーザーにストレスのない速度で結果を表示させることができました。EC2へデプロイ
公式ドキュメントを参考にしデプロイしました。
その際、インフラの知識が不足していたため、デプロイに一週間以上かかりました。APIのサービス終了!!
転職活動を始めようとした際、一週間後にカーセンサーAPIサービスが終了すると知りました。
急いで提供元へ問い合わせたところ、
「完全に提供が終了すること」「24時間以上のキャッシュデータの保有も禁止」、ということを告げられました。
その後、他の車データAPIの提供元を調べましたが他にありませんでした。
画像だけでもどうにかならないかと思い、ト◯タや◯産などの画像利用規約を確認しましたが、
営利目的ではない&提供元のURLなどの情報を記載する
としても、利用は禁止でした。
そのためLaravelの勉強も兼ねて、画像問題を解決できるアプリの制作に取り掛かりました。1月 Laravelでアプリ開発
12月末からLaravelの学習を始め、1月からアプリの制作に取り掛かりました。
前回のPHPで制作したポートフォリオとの違い
画像の取得にAPIを用いていましたが、ユーザーから愛車の画像を提供してもらう方針に変更し、機能の追加などを行いました。
完成
アプリのURL:https://pf-kurushira.com
(スマホサイズにも対応しています)
使用技術
使用言語
⚪︎ HTML
⚪︎ CSS
⚪︎ SCSS
⚪︎ PHP 7.4.14
⚪︎ Laravel 6.20.11インフラ
⚪︎ Github Actions 自動デプロイ
⚪︎ Docker 20.10.2 / docker-compose 1.27.4
⚪︎ nginx 1.18
⚪︎ mysql 5.7.31 / PHPMyAdmin
⚪︎ AWS ( EC2, ALB, ACM, S3, RDS, Route53, VPC, EIP, IAM)インフラ構成図
機能一覧
機能 概要 ユーザー管理機能 新規登録・ログイン・ログアウトができます 簡単ログイン機能 ログイン画面のゲストログインをクリックすることで、ゲストユーザーとしてログインできます おすすめ車種検索機能 条件を選択すると、それにあった車種一覧を表示します 検索履歴機能 直近の検索履歴・結果を表示します 画像提供機能 ユーザーの所有している車の画像を提供できます 提供した画像の削除機能 提供した画像を削除できます 提供画像一覧表示機能 自身が提供した画像一覧を表示します。 ユーザー情報編集機能 ご登録いただいたユーザー名・メールアドレスを変更できます Twitterシェア機能 車の検索結果をツイートすることができます レスポンシブ機能 スマホサイズ(320~540px)にも対応しています DB設計
各テーブルについて
テーブル名 説明 users 登録ユーザー情報 cars 登録車情報 histories 直近の検索結果の情報 car_images 提供画像の情報 苦労した点
ユーザー情報編集ページのバリデーション
LaravelのAuth機能のバリデーションを使いまわそうとしましたが、ブラックボックスになっていて苦労しました。
→新しくバリデーションを作成。S3からオブジェクト削除
画像の削除機能でDBからだけでなく、S3からもオブジェクトを削除する必要があり苦労しました。
→解決方法を記事にしました
laravel6でS3に画像アップロード&削除今後の課題
機能
機能 概要 英訳機能 Google Cloud Translation APIを利用して翻訳 通報機能 ユーザーの投票で不適切な画像を削除 技術
⚪︎ テスト
⚪︎ Dockerを用いた本番環境の構築
⚪︎ ECSへデプロイ参考にした学習教材など
PHP/Laravel
・【Udemy】PHP+MySQL(MariaDB) Webサーバーサイドプログラミング入門
・【書籍】詳細!PHP 7+MySQL 入門ノート
・【書籍】PHPフレームワークLaravel入門 第2版
・【書籍】PHPフレームワーク Laravel実践開発
・Laravel6.0(PHP7.3)+MySQL+Laradockで簡易的なECサイトを作るAWS
・【Udemy】AWS:ゼロから実践するAmazon Web Services。手を動かしながらインフラの基礎を習得
Docker
・【超入門】20分でLaravel開発環境を爆速構築するDockerハンズオン
さいごに
生のPHPでひとつPFを制作したのは、基礎力が身についたので良かったと思います。
今回ポートフォリオ完成を優先したため、ECSではなくEC2へデプロイしました。
まだ課題も多いですが、ブラッシュアップしていきたく思っています。
長くなりましたが、ここまで読んでくださりありがとうございました!!
- 投稿日:2021-03-14T15:34:40+09:00
【Docker】Docker環境内でmysqlの操作方法
はじめに
ローカル環境だと
mysql -u root -p
でデータベースに触れることができますが、Docker環境にいると一工夫必要です。この記事では、Docker環境内でmysqlの操作方法について紹介します。
環境
Docker version 20.10.0
docker-compose version 1.27.4
Docker内の環境
ruby:2.6.5
Rails:6.0.0
mysql8.0コマンド紹介
やり方は非常に簡単で、作ったコンテナのデータベース側に入って作業することです。
なので、下記のコマンドでデータベースのコンテナに入り、いつも通りmysqlのコマンドを打てば操作できます。コンテナのデータベースに入る
ターミナルdocker-compose exec db bashmysqlのコマンドでデータベースにアクセスする。
パスワードはdetabase.ymlで指定してるパスワードです。
ターミナルmysql -u root -p Enter password後はmysqlのコマンドを打つだけです。
どのんなデータベースがあるか確認した時
ターミナルmysql> show databases; +--------------------+ | Database | +--------------------+ | exam_development | | exam_test | | information_schema | | mysql | | performance_schema | | sys | | test-database | +--------------------+ 7 rows in set (0.07 sec)特定のデータベースのテーブルをみたい時
ターミナルmysql> show tables from データベース名; +----------------------------+ | Tables_in_exam_development | +----------------------------+ | admins | | ar_internal_metadata | | comments | | replies | | schema_migrations | | users | +----------------------------+ 6 rows in set (0.01 sec)特定のテーブルのカラムがみたい時
ターミナルmysql>SHOW COLUMNS FROM テーブル名 FROM データベース名; +---------------+-------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +---------------+-------------+------+-----+---------+----------------+ | id | bigint | NO | PRI | NULL | auto_increment | | text | text | YES | | NULL | | | comment_id_id | bigint | YES | MUL | NULL | | | user_id_id | bigint | YES | MUL | NULL | | | admin_id_id | bigint | YES | MUL | NULL | | | created_at | datetime(6) | NO | | NULL | | | updated_at | datetime(6) | NO | | NULL | | +---------------+-------------+------+-----+---------+----------------+データ取得を取得したい時
ターミナルmysql> USE データベース名 Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -Aターミナルmysql> SELECT * FROM テーブル名; +----+------+---------+----------+----------------------------+----------------------------+ | id | text | user_id | admin_id | created_at | updated_at | +----+------+---------+----------+----------------------------+----------------------------+ | 3 | ??? | 1 | NULL | 2021-02-21 02:34:34.818467 | 2021-02-21 02:34:34.818467 | +----+------+---------+----------+----------------------------+----------------------------+ 1 row in set (0.00 sec)mysqlのコマンド自体はまだまだあるので下記の参考にさせていただいた記事を参照してみてください。
参考
- 投稿日:2021-03-14T15:24:40+09:00
AWS EC-2 docker + wordpress インストール
AWSにEC2作る
ec2でdockerとwordpressをインストール
sshでログイン
__| __|_ ) _| ( / Amazon Linux 2 AMI ___|\___|___| https://aws.amazon.com/amazon-linux-2/ [ec2-user@ip-x-x-x-x ~]$yumをアップデート
[ec2-user@ip-x-x-x-x ~]$ sudo yum update -y Loaded plugins: extras_suggestions, langpacks, priorities, update-motd amzn2-core | 3.7 kB 00:00:00 No packages marked for updatedocker準備
dockerをインストール
sudo amazon-linux-extras install docker -y [ec2-user@ip-172-31-20-108 ~]$ sudo amazon-linux-extras install docker -y Installing docker Loaded plugins: extras_suggestions, langpacks, priorities, update-motd Cleaning repos: amzn2-core amzn2extra-docker 10 metadata files removed 4 sqlite files removed 0 metadata files removed Loaded plugins: extras_suggestions, langpacks, priorities, update-motd amzn2-core | 3.7 kB 00:00:00 amzn2extra-docker | 3.0 kB 00:00:00 (1/5): amzn2-core/2/x86_64/group_gz | 2.5 kB 00:00:00 (2/5): amzn2extra-docker/2/x86_64/updateinfo | 76 B 00:00:00 (3/5): amzn2extra-docker/2/x86_64/primary_db | 75 kB 00:00:00 (4/5): amzn2-core/2/x86_64/updateinfo | 350 kB 00:00:00 (5/5): amzn2-core/2/x86_64/primary_db | 50 MB 00:00:00 Resolving Dependencies --> Running transaction check ---> Package docker.x86_64 0:19.03.13ce-1.amzn2 will be installed --> Processing Dependency: runc >= 1.0.0 for package: docker-19.03.13ce-1.amzn2.x86_64 --> Processing Dependency: containerd >= 1.3.2 for package: docker-19.03.13ce-1.amzn2.x86_64 --> Processing Dependency: pigz for package: docker-19.03.13ce-1.amzn2.x86_64 --> Processing Dependency: libcgroup for package: docker-19.03.13ce-1.amzn2.x86_64 --> Running transaction check ---> Package containerd.x86_64 0:1.4.1-2.amzn2 will be installed ---> Package libcgroup.x86_64 0:0.41-21.amzn2 will be installed ---> Package pigz.x86_64 0:2.3.4-1.amzn2.0.1 will be installed ---> Package runc.x86_64 0:1.0.0-0.1.20200826.gitff819c7.amzn2 will be installed --> Finished Dependency Resolution Dependencies Resolved ============================================================================================================================================================================ Package Arch Version Repository Size ============================================================================================================================================================================ Installing: docker x86_64 19.03.13ce-1.amzn2 amzn2extra-docker 37 M Installing for dependencies: containerd x86_64 1.4.1-2.amzn2 amzn2extra-docker 24 M libcgroup x86_64 0.41-21.amzn2 amzn2-core 66 k pigz x86_64 2.3.4-1.amzn2.0.1 amzn2-core 81 k runc x86_64 1.0.0-0.1.20200826.gitff819c7.amzn2 amzn2extra-docker 3.7 M Transaction Summary ============================================================================================================================================================================ Install 1 Package (+4 Dependent packages) Total download size: 65 M Installed size: 270 M Downloading packages: (1/5): libcgroup-0.41-21.amzn2.x86_64.rpm | 66 kB 00:00:00 (2/5): pigz-2.3.4-1.amzn2.0.1.x86_64.rpm | 81 kB 00:00:00 (省略)dockerサービス起動
[ec2-user@ip-x-x-x-x ~]$ sudo systemctl start dockerdockerサービス状態確認
[ec2-user@ip-x-x-x-x ~]$ sudo systemctl status docker ● docker.service - Docker Application Container Engine Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled; vendor preset: disabled) Active: active (running) since Sun 2021-03-14 05:59:36 UTC; 25s ago Docs: https://docs.docker.com Process: 3722 ExecStartPre=/usr/libexec/docker/docker-setup-runtimes.sh (code=exited, status=0/SUCCESS) Process: 3709 ExecStartPre=/bin/mkdir -p /run/docker (code=exited, status=0/SUCCESS) Main PID: 3731 (dockerd) Tasks: 8 Memory: 36.6M CGroup: /system.slice/docker.service mq3731 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --default-ulimit nofile=1024:4096 Mar 14 05:59:36 ip-172-31-20-108.us-east-2.compute.internal dockerd[3731]: time="2021-03-14T05:59:36.354394783Z" level=info msg="scheme \"unix\" not registered, f...le=grpc Mar 14 05:59:36 ip-172-31-20-108.us-east-2.compute.internal dockerd[3731]: time="2021-03-14T05:59:36.354629298Z" level=info msg="ccResolverWrapper: sending update...le=grpc Mar 14 05:59:36 ip-172-31-20-108.us-east-2.compute.internal dockerd[3731]: time="2021-03-14T05:59:36.354858217Z" level=info msg="ClientConn switching balancer to ...le=grpc Mar 14 05:59:36 ip-172-31-20-108.us-east-2.compute.internal dockerd[3731]: time="2021-03-14T05:59:36.394039324Z" level=info msg="Loading containers: start." Mar 14 05:59:36 ip-172-31-20-108.us-east-2.compute.internal dockerd[3731]: time="2021-03-14T05:59:36.858998545Z" level=info msg="Default bridge (docker0) is assig...ddress" Mar 14 05:59:36 ip-172-31-20-108.us-east-2.compute.internal dockerd[3731]: time="2021-03-14T05:59:36.915341056Z" level=info msg="Loading containers: done." Mar 14 05:59:36 ip-172-31-20-108.us-east-2.compute.internal dockerd[3731]: time="2021-03-14T05:59:36.942822332Z" level=info msg="Docker daemon" commit=4484c46 gra...3.13-ce Mar 14 05:59:36 ip-172-31-20-108.us-east-2.compute.internal dockerd[3731]: time="2021-03-14T05:59:36.943274164Z" level=info msg="Daemon has completed initialization" Mar 14 05:59:36 ip-172-31-20-108.us-east-2.compute.internal systemd[1]: Started Docker Application Container Engine. Mar 14 05:59:36 ip-172-31-20-108.us-east-2.compute.internal dockerd[3731]: time="2021-03-14T05:59:36.967245548Z" level=info msg="API listen on /var/run/docker.sock" Hint: Some lines were ellipsized, use -l to show in full.dockerをec2-userで実行可能にする
[ec2-user@ip-x-x-x-x ~]$ sudo usermod -a -G docker ec2-user [ec2-user@ip-x-x-x-x ~]$ exit※ここで一度ログアウトして再度ログインすることで権限が反映される
docker-compose
docker-composeインストール
[ec2-user@ip-x-x-x-x ~]$ sudo curl -L "https://github.com/docker/compose/releases/download/1.28.5/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 633 100 633 0 0 9447 0 --:--:-- --:--:-- --:--:-- 9447 100 11.6M 100 11.6M 0 0 22.2M 0 --:--:-- --:--:-- --:--:-- 44.5M [ec2-user@ip-x-x-x-x ~]$ sudo chmod +x /usr/local/bin/docker-composecurlのURLは↓ここでdocker-composeのバージョンを確認して適宜書き換える。(2021/03/14時点は1.28.5)
https://docs.docker.com/compose/install/#install-compose-on-linux-systemsバージョン確認
[ec2-user@ip-x-x-x-x ~]$ docker-compose --version docker-compose version 1.28.5, build c4eb3a1fwordpress
docker-compose.ymlファイルを用意
[ec2-user@ip-x-x-x-x ~]$ pwd /home/ec2-user [ec2-user@ip-x-x-x-x ~]$ mkdir wordpress [ec2-user@ip-x-x-x-x ~]$ vi ~/wordpress/docker-compose.ymldocker-compose.ymlversion: '3.1' services: wordpress: container_name: wp-trial image: wordpress restart: always ports: - 55555:80 environment: WORDPRESS_DB_HOST: db WORDPRESS_DB_USER: exampleuser WORDPRESS_DB_PASSWORD: examplepass WORDPRESS_DB_NAME: exampledb volumes: - wordpress:/var/www/html db: container_name: wp-db image: mysql:5.7 restart: always environment: MYSQL_DATABASE: exampledb MYSQL_USER: exampleuser MYSQL_PASSWORD: examplepass MYSQL_RANDOM_ROOT_PASSWORD: '1' volumes: - db:/var/lib/mysql volumes: wordpress: db:
wordpressをビルドして起動
docker-compose.ymlが入っているディレクトリに移動して
docker-compose up
する。[ec2-user@ip-x-x-x-x ~]$ cd wordpress/ [ec2-user@ip-x-x-x-x wordpress]$ pwd /home/ec2-user/wordpress [ec2-user@ip-x-x-x-x wordpress]$ ls -la total 4 drwxrwxr-x 2 ec2-user ec2-user 32 Mar 14 06:12 . drwx------ 5 ec2-user ec2-user 142 Mar 14 06:12 .. -rw-rw-r-- 1 ec2-user ec2-user 638 Mar 14 06:12 docker-compose.yml[ec2-user@ip-x-x-x-x wordpress]$ docker-compose up --build -d Creating network "wordpress_default" with the default driver Creating volume "wordpress_wordpress" with default driver Creating volume "wordpress_db" with default driver Pulling wordpress (wordpress:)... latest: Pulling from library/wordpress 6f28985ad184: Pull complete db883aae18bc: Pull complete ffae70ea03a9: Pull complete 1e8027612378: Pull complete 3ec32e53dce5: Pull complete 3bb74037bf77: Pull complete feda0fbd85b1: Pull complete b2244185b327: Pull complete 8852ae668073: Pull complete 985e21deb66e: Pull complete f262da4e7afa: Pull complete 157f3d683e13: Pull complete 990684a56233: Pull complete c80999e49328: Pull complete 02585da80b89: Pull complete d68ab7635a0a: Pull complete 5a577fb48682: Pull complete d27e8a2c96b8: Pull complete f94fa08d2764: Pull complete 6db2ebd4cef9: Pull complete 9c4c1399bbb1: Pull complete Digest: sha256:92fb18e472ce46f289b475457289075c20387374d79bc41724689aa88112eab1 Status: Downloaded newer image for wordpress:latest Pulling db (mysql:5.7)... 5.7: Pulling from library/mysql 6f28985ad184: Already exists e7cd18945cf6: Pull complete ee91068b9313: Pull complete b4efa1a4f93b: Pull complete f220edfa5893: Pull complete 74a27d3460f8: Pull complete 2e11e23b7542: Pull complete 39ac93d44c47: Pull complete dfd9db50d4ea: Pull complete 4e97f54f11a3: Pull complete ebfb95795c5f: Pull complete Digest: sha256:5f649e87093a5b6b863f5c5277b2d2aa797b04d68657494e0f28ffabfa25e781 Status: Downloaded newer image for mysql:5.7 Creating wp-trial ... done Creating wp-db ... done[ec2-user@ip-172-31-20-108 wordpress]$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES d0296aeb5318 mysql:5.7 "docker-entrypoint.s…" About a minute ago Up About a minute 3306/tcp, 33060/tcp wp-db c01446d87997 wordpress "docker-entrypoint.s…" About a minute ago Up About a minute 0.0.0.0:55555->80/tcp wp-trialWordpressにアクセスしてみる
参考
AWS公式 Dockerインストール手順
AWS EC2インスタンスにdockerとdocker-composeをインストールして簡単なWEBサービスを立ち上げる方法
- 投稿日:2021-03-14T15:24:40+09:00
AWS EC2 docker + wordpress インストール
AWSにEC2作る
AMIの選択
インスタンスタイプの選択
インスタンスの詳細の設定
自動割り当てパブリックIPを「有効」にした以外はデフォルト設定。
ストレージの追加
タグの追加
タグはなにも設定していない。
セキュリティグループの設定
セキュリティグループは事前に作成してあったものを利用した。
- 22番ポート: SSH接続
- 55555番ポート: WordPress接続
インスタンス作成の確認
内容に問題なければ「起動」。
キーペアの確認
事前に作ったあったキーペアを使った。
ec2でdockerとwordpressをインストール
sshでログイン
__| __|_ ) _| ( / Amazon Linux 2 AMI ___|\___|___| https://aws.amazon.com/amazon-linux-2/ [ec2-user@ip-x-x-x-x ~]$yumをアップデート
[ec2-user@ip-x-x-x-x ~]$ sudo yum update -y Loaded plugins: extras_suggestions, langpacks, priorities, update-motd amzn2-core | 3.7 kB 00:00:00 No packages marked for updatedocker準備
dockerをインストール
[ec2-user@ip-x-x-x-x ~]$ sudo amazon-linux-extras install docker -y Installing docker Loaded plugins: extras_suggestions, langpacks, priorities, update-motd Cleaning repos: amzn2-core amzn2extra-docker 10 metadata files removed 4 sqlite files removed 0 metadata files removed Loaded plugins: extras_suggestions, langpacks, priorities, update-motd amzn2-core | 3.7 kB 00:00:00 amzn2extra-docker | 3.0 kB 00:00:00 (1/5): amzn2-core/2/x86_64/group_gz | 2.5 kB 00:00:00 (2/5): amzn2extra-docker/2/x86_64/updateinfo | 76 B 00:00:00 (3/5): amzn2extra-docker/2/x86_64/primary_db | 75 kB 00:00:00 (4/5): amzn2-core/2/x86_64/updateinfo | 350 kB 00:00:00 (5/5): amzn2-core/2/x86_64/primary_db | 50 MB 00:00:00 Resolving Dependencies --> Running transaction check ---> Package docker.x86_64 0:19.03.13ce-1.amzn2 will be installed --> Processing Dependency: runc >= 1.0.0 for package: docker-19.03.13ce-1.amzn2.x86_64 --> Processing Dependency: containerd >= 1.3.2 for package: docker-19.03.13ce-1.amzn2.x86_64 --> Processing Dependency: pigz for package: docker-19.03.13ce-1.amzn2.x86_64 --> Processing Dependency: libcgroup for package: docker-19.03.13ce-1.amzn2.x86_64 --> Running transaction check ---> Package containerd.x86_64 0:1.4.1-2.amzn2 will be installed ---> Package libcgroup.x86_64 0:0.41-21.amzn2 will be installed ---> Package pigz.x86_64 0:2.3.4-1.amzn2.0.1 will be installed ---> Package runc.x86_64 0:1.0.0-0.1.20200826.gitff819c7.amzn2 will be installed --> Finished Dependency Resolution Dependencies Resolved ============================================================================================================================================================================ Package Arch Version Repository Size ============================================================================================================================================================================ Installing: docker x86_64 19.03.13ce-1.amzn2 amzn2extra-docker 37 M Installing for dependencies: containerd x86_64 1.4.1-2.amzn2 amzn2extra-docker 24 M libcgroup x86_64 0.41-21.amzn2 amzn2-core 66 k pigz x86_64 2.3.4-1.amzn2.0.1 amzn2-core 81 k runc x86_64 1.0.0-0.1.20200826.gitff819c7.amzn2 amzn2extra-docker 3.7 M Transaction Summary ============================================================================================================================================================================ Install 1 Package (+4 Dependent packages) Total download size: 65 M Installed size: 270 M Downloading packages: (1/5): libcgroup-0.41-21.amzn2.x86_64.rpm | 66 kB 00:00:00 (2/5): pigz-2.3.4-1.amzn2.0.1.x86_64.rpm | 81 kB 00:00:00 (省略)dockerサービス起動
[ec2-user@ip-x-x-x-x ~]$ sudo systemctl start dockerdockerサービス状態確認
[ec2-user@ip-x-x-x-x ~]$ sudo systemctl status docker ● docker.service - Docker Application Container Engine Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled; vendor preset: disabled) Active: active (running) since Sun 2021-03-14 05:59:36 UTC; 25s ago Docs: https://docs.docker.com Process: 3722 ExecStartPre=/usr/libexec/docker/docker-setup-runtimes.sh (code=exited, status=0/SUCCESS) Process: 3709 ExecStartPre=/bin/mkdir -p /run/docker (code=exited, status=0/SUCCESS) Main PID: 3731 (dockerd) Tasks: 8 Memory: 36.6M CGroup: /system.slice/docker.service mq3731 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --default-ulimit nofile=1024:4096 Mar 14 05:59:36 ip-172-31-20-108.us-east-2.compute.internal dockerd[3731]: time="2021-03-14T05:59:36.354394783Z" level=info msg="scheme \"unix\" not registered, f...le=grpc Mar 14 05:59:36 ip-172-31-20-108.us-east-2.compute.internal dockerd[3731]: time="2021-03-14T05:59:36.354629298Z" level=info msg="ccResolverWrapper: sending update...le=grpc Mar 14 05:59:36 ip-172-31-20-108.us-east-2.compute.internal dockerd[3731]: time="2021-03-14T05:59:36.354858217Z" level=info msg="ClientConn switching balancer to ...le=grpc Mar 14 05:59:36 ip-172-31-20-108.us-east-2.compute.internal dockerd[3731]: time="2021-03-14T05:59:36.394039324Z" level=info msg="Loading containers: start." Mar 14 05:59:36 ip-172-31-20-108.us-east-2.compute.internal dockerd[3731]: time="2021-03-14T05:59:36.858998545Z" level=info msg="Default bridge (docker0) is assig...ddress" Mar 14 05:59:36 ip-172-31-20-108.us-east-2.compute.internal dockerd[3731]: time="2021-03-14T05:59:36.915341056Z" level=info msg="Loading containers: done." Mar 14 05:59:36 ip-172-31-20-108.us-east-2.compute.internal dockerd[3731]: time="2021-03-14T05:59:36.942822332Z" level=info msg="Docker daemon" commit=4484c46 gra...3.13-ce Mar 14 05:59:36 ip-172-31-20-108.us-east-2.compute.internal dockerd[3731]: time="2021-03-14T05:59:36.943274164Z" level=info msg="Daemon has completed initialization" Mar 14 05:59:36 ip-172-31-20-108.us-east-2.compute.internal systemd[1]: Started Docker Application Container Engine. Mar 14 05:59:36 ip-172-31-20-108.us-east-2.compute.internal dockerd[3731]: time="2021-03-14T05:59:36.967245548Z" level=info msg="API listen on /var/run/docker.sock" Hint: Some lines were ellipsized, use -l to show in full.dockerをec2-userで実行可能にする
[ec2-user@ip-x-x-x-x ~]$ sudo usermod -a -G docker ec2-user [ec2-user@ip-x-x-x-x ~]$ exit※ここで一度ログアウトして再度ログインすることで権限が反映される
docker-compose
docker-composeインストール
[ec2-user@ip-x-x-x-x ~]$ sudo curl -L "https://github.com/docker/compose/releases/download/1.28.5/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 633 100 633 0 0 9447 0 --:--:-- --:--:-- --:--:-- 9447 100 11.6M 100 11.6M 0 0 22.2M 0 --:--:-- --:--:-- --:--:-- 44.5McurlのURLは↓ここでdocker-composeのバージョンを確認して適宜書き換える。(2021/03/14時点は1.28.5)
https://docs.docker.com/compose/install/#install-compose-on-linux-systemsdocker-compose実行権限設定
[ec2-user@ip-x-x-x-x ~]$ sudo chmod +x /usr/local/bin/docker-composeバージョン確認
[ec2-user@ip-x-x-x-x ~]$ docker-compose --version docker-compose version 1.28.5, build c4eb3a1fwordpress
docker-compose.ymlファイルを用意
[ec2-user@ip-x-x-x-x ~]$ pwd /home/ec2-user [ec2-user@ip-x-x-x-x ~]$ mkdir wordpress [ec2-user@ip-x-x-x-x ~]$ vi ~/wordpress/docker-compose.ymldocker-compose.ymlversion: '3.1' services: wordpress: container_name: wp-trial image: wordpress restart: always ports: - 55555:80 environment: WORDPRESS_DB_HOST: db WORDPRESS_DB_USER: exampleuser WORDPRESS_DB_PASSWORD: examplepass WORDPRESS_DB_NAME: exampledb volumes: - wordpress:/var/www/html db: container_name: wp-db image: mysql:5.7 restart: always environment: MYSQL_DATABASE: exampledb MYSQL_USER: exampleuser MYSQL_PASSWORD: examplepass MYSQL_RANDOM_ROOT_PASSWORD: '1' volumes: - db:/var/lib/mysql volumes: wordpress: db:wordpress用のdocker-compose.ymlファイルは↓を参考に作成。
https://hub.docker.com/_/wordpresswordpressをビルドして起動
docker-compose.ymlが入っているディレクトリに移動して
docker-compose up
する。[ec2-user@ip-x-x-x-x ~]$ cd ~/wordpress/ [ec2-user@ip-x-x-x-x wordpress]$ pwd /home/ec2-user/wordpress [ec2-user@ip-x-x-x-x wordpress]$ ls -la total 4 drwxrwxr-x 2 ec2-user ec2-user 32 Mar 14 06:12 . drwx------ 5 ec2-user ec2-user 142 Mar 14 06:12 .. -rw-rw-r-- 1 ec2-user ec2-user 638 Mar 14 06:12 docker-compose.yml[ec2-user@ip-x-x-x-x wordpress]$ docker-compose up --build -d Creating network "wordpress_default" with the default driver Creating volume "wordpress_wordpress" with default driver Creating volume "wordpress_db" with default driver Pulling wordpress (wordpress:)... latest: Pulling from library/wordpress 6f28985ad184: Pull complete db883aae18bc: Pull complete ffae70ea03a9: Pull complete 1e8027612378: Pull complete 3ec32e53dce5: Pull complete 3bb74037bf77: Pull complete feda0fbd85b1: Pull complete b2244185b327: Pull complete 8852ae668073: Pull complete 985e21deb66e: Pull complete f262da4e7afa: Pull complete 157f3d683e13: Pull complete 990684a56233: Pull complete c80999e49328: Pull complete 02585da80b89: Pull complete d68ab7635a0a: Pull complete 5a577fb48682: Pull complete d27e8a2c96b8: Pull complete f94fa08d2764: Pull complete 6db2ebd4cef9: Pull complete 9c4c1399bbb1: Pull complete Digest: sha256:92fb18e472ce46f289b475457289075c20387374d79bc41724689aa88112eab1 Status: Downloaded newer image for wordpress:latest Pulling db (mysql:5.7)... 5.7: Pulling from library/mysql 6f28985ad184: Already exists e7cd18945cf6: Pull complete ee91068b9313: Pull complete b4efa1a4f93b: Pull complete f220edfa5893: Pull complete 74a27d3460f8: Pull complete 2e11e23b7542: Pull complete 39ac93d44c47: Pull complete dfd9db50d4ea: Pull complete 4e97f54f11a3: Pull complete ebfb95795c5f: Pull complete Digest: sha256:5f649e87093a5b6b863f5c5277b2d2aa797b04d68657494e0f28ffabfa25e781 Status: Downloaded newer image for mysql:5.7 Creating wp-trial ... done Creating wp-db ... done[ec2-user@ip-172-31-20-108 wordpress]$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES d0296aeb5318 mysql:5.7 "docker-entrypoint.s…" About a minute ago Up About a minute 3306/tcp, 33060/tcp wp-db c01446d87997 wordpress "docker-entrypoint.s…" About a minute ago Up About a minute 0.0.0.0:55555->80/tcp wp-trialWordpressにアクセスしてみる
参考
AWS公式 Dockerインストール手順
AWS EC2インスタンスにdockerとdocker-composeをインストールして簡単なWEBサービスを立ち上げる方法
- 投稿日:2021-03-14T11:53:58+09:00
HerokuにConda環境で開発したアプリをデプロイする方法
はじめに
Conda+RDkit等を使って作成したアプリをHerokuにデプロイしたいと思い、色々試行錯誤した結果、Dockerを使って、2日がかりでなんとかデプロイするところまでできたのでメモっておく。
環境
今回は以下の構成で構築したアプリの配布を確認した。
- Windows 10
- python 3.7
- django 3系 (WEBアプリフレームワーク)
- Pytorch 1.7 cpu版 (ディープラーニングフレームワーク)
- RDKit (ケモインフォマティクスライブラリ)
- gunicorn (WEBサーバ)
- herokuアプリケーション名: chemodel今回配布したいアプリ
ソース
今回は、Condaの仮想環境上でのRDKitというライブラリの動作を確認できればよかったので、ある化合物をRDkitで読み取りその原子番号を表示するという、超簡単なDjangoアプリを作成した。
Djangoアプリのviews.pyを以下に示す。chemodel/chemodel_app/vies.pyfrom django.shortcuts import render from django.http import HttpResponse # モジュールの読み込み from rdkit import Chem def hellofunction(request): m = Chem.MolFromSmiles('Cc1ccccc1') data = len(m.GetAtoms()) return HttpResponse('RDkitアプリだよ!!!!! 原子数={0}'.format(data))動作イメージ
動作イメージは、見せるまでもないが、こんな感じとなる。
なぜDockerか
Conda環境を必要とするアプリのHerokuへの配布方法としては、conda--buildpack (https://elements.heroku.com/buildpacks/conda/conda-buildpack) を用いた方法があるが、そもそもローカルとHerokuでは、OSアーキテクチャーが異なるため、Windowsではインストールできたバージョンの組み合わせが、Herokuではインストールできない(Condaのリポジトリにそのアーキテクチャーのバージョンが存在しない)ケースが多発するからである。Dockerであればローカルでビルドした組み合わせをそのまま配布できるため、確実だからである。
手順
ここから実際にデプロイするまでの手順を示す。Heroku CLI はインストールされている前提とする。
Herokuレジストリへのログイン
以下のコマンドによりログインする。
$ heroku container:login
Herokuアプリケーションの作成
Herokuアプリケーションを作成する。
勿論、実際のDjangoアプリは、開発されている前提とする。$ heroku create chemodel
Dockerファイルの作成
以下のようにDockerファイルを作成する。
FROM continuumio/miniconda3 RUN conda create -n chemodel python==3.7 SHELL ["conda", "run", "-n", "chemodel", "/bin/bash", "-c"] RUN conda install django=3.* -c conda-forge --override-channels RUN conda install pytorch==1.7.1 torchvision==0.8.2 torchaudio==0.7.2 cpuonly -c pytorch -c conda-forge --override-channels -c tboyer RUN conda install -c rdkit -c conda-forge rdkit --override-channels RUN conda install -c rdkit -c conda-forge mordred --override-channels RUN conda install django-heroku -c conda-forge --override-channels # pip RUN pip3 install --upgrade pip RUN pip3 install gunicorn # Add our codeg ADD ./chemodel /chemodel/ WORKDIR /chemodel CMD gunicorn --bind 0.0.0.0:$PORT chemodel.wsgiDockerファイルは、Miniconda on Heroku Example Appを参考にしているのだが、少し解説する。
- まず、FROM~
のところで、minocondaのベースイメージを指定する。ここは、Herokuのサンプル (https://github.com/heroku-examples/python-miniconda) では、Pythonがバージョン2のようであり、サンプルアプリがうまく動かなかったので変更している。
- 続いて、RUN conda create -n chemodel python==3.7
で、作成したいPythonのバージョンでConda仮想環境を作成する。
-SHELL~
の行でその仮想環境をActivateする。
- conda, pipで各自インストールしたいものを列挙する。
-ADD~
の行では、自分が配布したいアプリを、コンテナ側の/chemodelというフォルダにコピーする。
-WORKDIR~
で、アプリのフォルダに移動し、CMD~
でアプリを起動している。$PORTというのは、herokuでDockerを配布する際のポート指定の際に必要となる書き方である(参考文献参照)コンテナのプッシュ
Djangoプロジェクトフォルダが直下にあるフォルダに、Dockerfileを配備し、そのフォルダ上で以下コマンドを実行する。-aオプションは、各自のheroku アプリ名に読み替えてほしい。
$ heroku container:push web -a chemdelコンテナのリリース
ビルドが成功したら、以下のコマンドでリリースできる。-aオプションは、各自のheroku アプリ名に読み替えてほしい。
$ heroku container:push web -a chemodelこれで、ブラウザでherokuアプリのURLを叩くと、アプリの画面が確認できるはずだ。
おわりに
RDkitアプリだよ!!!!! 原子数=7
たったこれだけだが、これが表示された瞬間は嬉しかった。今回の方法を使ってどんなアプリをデプロイするか、考えるだけでもワクワクしてくる。
参考文献
- 投稿日:2021-03-14T10:01:14+09:00
miniconda+conda-forgeでの開発環境をDockerでそろえる
はじめに
Anacondaの有償化に伴い、こちらでminiconda+conda-forgeに関する運用の記事を書いたところ、そこそこに反響があったので、今回はDockerで開発環境を揃えるところをご紹介したい。
環境
私がWindows派であり、condaはケモインフォマティクスをやるために利用しているため、今回は以下の構成で説明する。またWebアプリの開発を想定してDjangoも用意することする。
- Windows 10
- python 3.7
- django 3系 (WEBアプリフレームワーク)
- Pytorch 1.7 cpu版 (ディープラーニングフレームワーク)
- RDKit (ケモインフォマティクスライブラリ)
- gunicorn (WEBサーバ)
手順
Dockerのインストール
まずは以下に従ってDockerをインストールしよう。
Dockerfileの作成
続いて以下のようにDockerfileを作成しよう。
FROM continuumio/miniconda3 # conda create RUN conda create -n chemodel python==3.7 # install conda package SHELL ["conda", "run", "-n", "chemodel", "/bin/bash", "-c"] RUN conda install django=3.* -c conda-forge --override-channels RUN conda install pytorch==1.7.1 torchvision==0.8.2 torchaudio==0.7.2 cpuonly -c pytorch -c conda-forge -c tboyer --override-channels RUN conda install -c rdkit -c conda-forge rdkit --override-channels # install pip package RUN pip3 install --upgrade pip RUN pip3 install gunicornDockerfileについて解説する
- まず、
FROM~
のところで、minocondaのベースイメージを指定する。- 続いて、
RUN conda create -n chemodel python==3.7
で、作成したいPythonのバージョンでConda仮想環境を作成する。SHELL~
の行でその仮想環境をActivateする。ここが今回の最大の肝で、この方法を間違えると、それ以降のconda installによるインストールが、作成した仮想環境ではなく、base環境に反映されてしまうのだ。- ここまでくれば、その後は、conda, pipで各自インストールしたいものを列挙すればOKだ。Anaconda有償化の影響をうけ、チャネルやオプションの指定は、前回の記事を参考にしてほしい。
- pytorch1.7は、pytorch, conda-forgeだけからではインストールできなかったっぽかったので、tboyerというマイナーなチャネルを指定したが、危険だと思われる方は別のPyTorchのバージョンを指定してみてほしい。
Dockerイメージのビルド
作成したDockerfileのあるフォルダで以下を実行するとビルドできるはずだ。
docker build -t kimisyo/dev:1.0 -f Dockerfile ./Dockerイメージの確認
docker images
でイメージができたか確認してみよう。$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE kimisyo/dev 1.0 90cbde3916c9 17 hours ago 3.33GB
Dockerコンテナの起動
Djangoアプリを作成し、以下のようにDockerコンテナを起動すると、
http://locahost:8080/
で、作成したDjangoアプリを参照できるはずだ。$docker run -itd -p 8080:8000 --name chemodel --mount type=bind,src=<Djangoのプロジェクトがあるフォルダを絶対パスで指定>, target=/chemodel,readonly kimisyo/dev:1.0 /bin/bash -c "conda run -n chemodel; cd /chemodel/; /opt/conda/envs/chemodel/bin/gunicorn --bind 0.0.0.0:8000 chemodel.wsgi"ちょっと分かりにくいので簡単に説明する。
-p 8080:8000
は、Dockerコンテナ側の8000ポートをローカルの8080ポートで参照できるようにするための指定である。-mountオプション
では、ローカルにあるDjangoプロジェクトのフォルダを、コンテナ側で認識させるために /chemodelというフォルダにマウントしている。- 最後の
/bin/bash -c "conda run -n chemodel; cd /chemodel/; /opt/conda/envs/chemodel/bin/gunicorn --bind 0.0.0.0:8000 chemodel.wsgi"
ではコンテナ起動時に、conda仮想環境をActivateし、コンテナ内のDjangoアプリフォルダに移動し、gunicornによりDjangoアプリを起動している。おわりに
一度開発環境を作ってしまえば、毎回パッケージをインストールする必要もなく、本番環境もDockerで簡単にデプロイしてしまうこともできそうだ。Hava a good miniconda+conda-forge & Docker Life!
参考
- Activating a Conda environment in your Dockerfile 今回の肝となるCondaのActivte方法が記載されている。