20210314のdockerに関する記事は11件です。

ポータブルなGlusterFSコンテナを作成する(レプリカ数2の場合)

1. はじめに

 複数のサーバでコンテナを運用する際、コンテナ内で動作するアプリケーションが保存するファイルをどのように保持するかを考える必要があります。Kubernetesでは、CephやGlusterFSなどの分散ストレージが利用できます。この記事では、十数台程度の小規模なオンプレミスのdocker実行環境で、GlusterFSによるデータ保持機構を構築するときに検討した内容をまとめたものです(下図のように、コンテナの参照先をファイルサーバにすることで、どのサーバでコンテナが稼働しても同じデータを参照できます。)。

arch1.png

記事にまとめるにあたり、「オンプレミスな環境で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を用いて本番環境を模擬する。(ネットワークアドレスは仮のものです)

deploy-pattern.png

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を組み込み、その中で実施する。

directory4.png

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

3.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: host

3.4 プロジェクトの全体構成

上記の情報をまとめると、以下のような構成となった。setupが開発環境で構築する内容で、deployが本番環境の設定をまとめるところ、としている。
directory3.png

4. まとめ

 自分がこの構成を検討するとき、なかなかGlusterの設定内容をコンテナイメージ内に組み込んでデプロイする事例が見つからなかったため、備忘録として記事にまとめてみました。コンテナ内でglusterを起動するときに、事前にコンフィグを移動したり、強制起動し直す、といったハマるポイントがあったので注意が必要です。
 また、検証の側面が強かったので、IPアドレスとかの設定が直書きです。そのあたりを環境変数にするなど、実際にデプロイするものに仕上げるにはもう少し改良が必要です。

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

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

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

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のバージョンを合わせれて良かったと思います。

誰かの参考になれば幸いです。
ありがとうございました。

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

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を使った例のようにコマンドを&&で繋げてレイヤを節約するのが推奨されてるようです。

いずれにせよ調理鍋を固定してから卵を割るか鍋をとったらすかさず卵を割ることで、卵を無駄にしないようにしましょう。

終わりに

 気を抜くと冷凍チャーハン製造工場の動画をみていました。目的を見失わないように引き続き精進していきたいです。


  1. 本題から逸れるので省きましたが、実際にはこの前にここに記載のある依存ライブラリ(とgccとmake)のインストール処理が必要です。 

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

【実験】Dockerを使用してGitLabを構築してみる part1

今回は仮想化技術である「コンテナ化」の代表的なプラットフォームであるDockerを使用してGitLabを構築してみます。
恐らく長くなりそうなので、複数回に分けて投稿予定です。
加えて今回は実施しませんが次回以降に以前使用していたGitLabとデータの共有を出来るように設定したいと思います。

事前準備

まずはサーバーにDockerをインストールします。
以下のコマンドでインストールを行います。

sudo yum -y install docker

インストール完了後、起動と自動起動の有効化を行います。

sudo systemctl start docker
sudo systemctl enable docker
sudo systemctl status docker

Dockerを起動後、テスト用イメージである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 + cdocker logs -f gitlabを中断し、続けて以下のコマンドでreconfigureを手動実行します。

docker exec -it gitlab gitlab-ctl reconfigure
※「gitlab Reconfigured!」と表示された次の行でプロンプトに戻れば成功

GitLabインストール実行時にそのままreconfigureを実行する流れのようですが、どういう訳かそれだとうまく行かないようです。

GitLabのweb画面にアクセス

インストール完了後、ブラウザにてhttp://<サーバーのIPアドレス>へアクセスします。
rootパスワードの設定画面が表示されれば無事成功です。
git01.png
rootパスワードを設定し、ログイン画面に移行します。
git02.png
ログインができて以下の画面が表示されていればGitLabインストールの一連の流れは完了です。
git03.png

今回はここまでです。
次回へ続きます。

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

生のPHPとLaravelの、二通りの類似ポートフォリオを作った話

はじめに

こんにちは、おーもとと申します。エンジニアに転職をするため学習している初学者です。
私は車が好きで、「近年の若者の車離れ」という問題にフォーカスしたアプリを制作しようと思いました。

制作背景

若者が車を持たない理由には様々な理由があると思いますが、
「欲しいと思えるほど魅力を感じる車に出会っていないからなのでは?」
と思い、
・かわいいやかっこいいというスタイル
・大きさ
・国産か外車か
・アウトドアや街乗りという用途
これらの項目に当てはまる車を、結果として表示するアプリを制作することにしました。
(これらの特徴は全て私が定めているため、投票などにより特徴を決める機能をつけたいです)

11月 PHPでアプリ開発

10月からPHPの学習を始めていたので、そのアプリはPHPで制作しました。
カーセンサーAPIを使用して、車の情報を取得します。
解説動画:https://www.youtube.com/watch?v=ZXbgUtjxKM8
スクリーンショット 2020-12-12 12.34.26.png

機能

ユーザー登録関連
⚪︎ ログイン
⚪︎ ログアウト
⚪︎ 新規登録
⚪︎ ユーザー件数を表示

車の検索機能
⚪︎ 車の見た目→「かわいい」「かっこいい」「シンプル」「おしゃれ」「レトロ」
⚪︎ 車のサイズ→「ふつう」「すごくおおきい」「おおきい」「ちいさい」
⚪︎ 車の製造国→「国産車」「外車」
⚪︎ 車の用途 →「街乗り」「アウトドア」「スポーツ」

カーセンサー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
(スマホサイズにも対応しています)
スクリーンショット 2021-03-14 16.03.00.png

使用技術

使用言語

⚪︎ 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)

インフラ構成図

スクリーンショット 2021-02-28 20 11 32

機能一覧

機能 概要
ユーザー管理機能 新規登録・ログイン・ログアウトができます
簡単ログイン機能 ログイン画面のゲストログインをクリックすることで、ゲストユーザーとしてログインできます
おすすめ車種検索機能 条件を選択すると、それにあった車種一覧を表示します
検索履歴機能 直近の検索履歴・結果を表示します
画像提供機能 ユーザーの所有している車の画像を提供できます
提供した画像の削除機能 提供した画像を削除できます
提供画像一覧表示機能 自身が提供した画像一覧を表示します。
ユーザー情報編集機能 ご登録いただいたユーザー名・メールアドレスを変更できます
Twitterシェア機能 車の検索結果をツイートすることができます
レスポンシブ機能 スマホサイズ(320~540px)にも対応しています

DB設計

スクリーンショット 2021-02-20 19 05 58

各テーブルについて

テーブル名 説明
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へデプロイしました。
まだ課題も多いですが、ブラッシュアップしていきたく思っています。
長くなりましたが、ここまで読んでくださりありがとうございました!!

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

【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 bash 

mysqlのコマンドでデータベースにアクセスする。

パスワードは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のコマンド自体はまだまだあるので下記の参考にさせていただいた記事を参照してみてください。

参考

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

AWS EC-2 docker + wordpress インストール

AWSにEC2作る

image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png

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 update

docker準備

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 docker

dockerサービス状態確認

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

curlの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 c4eb3a1f

wordpress

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.yml
docker-compose.yml
version: '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-trial

Wordpressにアクセスしてみる

image.png


参考

AWS公式 Dockerインストール手順
AWS EC2インスタンスにdockerとdocker-composeをインストールして簡単なWEBサービスを立ち上げる方法

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

AWS EC2 docker + wordpress インストール

AWSにEC2作る

AMIの選択

image.png

インスタンスタイプの選択

image.png

インスタンスの詳細の設定

自動割り当てパブリックIPを「有効」にした以外はデフォルト設定。

image.png

ストレージの追加

image.png

タグの追加

タグはなにも設定していない。

image.png

セキュリティグループの設定

セキュリティグループは事前に作成してあったものを利用した。

  • 22番ポート: SSH接続
  • 55555番ポート: WordPress接続

image.png

インスタンス作成の確認

内容に問題なければ「起動」。

image.png

キーペアの確認

事前に作ったあったキーペアを使った。

image.png

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 update

docker準備

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 docker

dockerサービス状態確認

[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

curlのURLは↓ここでdocker-composeのバージョンを確認して適宜書き換える。(2021/03/14時点は1.28.5)
https://docs.docker.com/compose/install/#install-compose-on-linux-systems

docker-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 c4eb3a1f

wordpress

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.yml
docker-compose.yml
version: '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/_/wordpress

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

Wordpressにアクセスしてみる

image.png


参考

AWS公式 Dockerインストール手順
AWS EC2インスタンスにdockerとdocker-composeをインストールして簡単なWEBサービスを立ち上げる方法

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

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.py
from 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))

動作イメージ

動作イメージは、見せるまでもないが、こんな感じとなる。

image.png

なぜ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.wsgi

Dockerファイルは、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

たったこれだけだが、これが表示された瞬間は嬉しかった。今回の方法を使ってどんなアプリをデプロイするか、考えるだけでもワクワクしてくる。

参考文献

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

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 gunicorn

Dockerfileについて解説する

  • まず、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!

参考

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