- 投稿日:2021-01-12T23:04:10+09:00
TensorFlowを動かすためのJupyterのDocker環境
環境
MacBookPro
OS:Catalina内容
DockerHubからimageをPull
$ docker pull tensorflow/tensorflow:latest-jupyterimageからコンテナを起動
ホスト側で8888ポートを使用していたので、私は、8889:8888で行った。$ docker run -it -p 8889:8888 --name tf_test tensorflow/tensorflow:latest-jupyter上記実行後、表示されたURLにアクセスしてJupyterのページが表示されていればOK。(8888番ポートを使用していなければ、置き換える)
- 投稿日:2021-01-12T21:17:49+09:00
Docker上でGrafanaとInfluxDBを接続しようとしたらBad Gatewayが出た
「Grafana InfluxDB Docker」とググってみて出てくるチュートリアルをやってみたら上記のようなBad Gatewayに悩まされたお話。
結論としては、URLとAccessの組み合わせを正しく理解していなかったためでした。実施環境
ローカルPCのDocker上にGrafanaとInfluxDBのコンテナを立ち上げ、GrafanaのData SourcesからInflxDBを設定しようとしました。
以下のようなDocker-compose.ymlを書いて、実行します。version: "3" services: influxdb: image: influxdb:latest ports: - "8086:8086" volumes: - ./data/influxdb:/var/lib/influxdb grafana: image: grafana/grafana:latest ports: - "3000:3000" volumes: - ./data/grafana:/var/lib/grafana depends_on: - influxdbvolumesはフィジビリする上では好みですが、今回はdocker-compose.ymlと同階層に「data」フォルダを作成し、その下に「influxdb」フォルダと「grafana」フォルダを作成しておきます。
InfluxDBにdockerコマンドでアクセスして、新規データベース(ここではsample)とメジャーメントを作成しておいてから、Grafanaに
「http://localhost:3000」
でアクセスをして、ConfigurationのData SourcesよりInfluxDBを追加するために情報を入力して、「Save & Test」を実行までしたところ、冒頭のような「InfluxDB Error: Bad Gateway」が発生しました。解決策① AccessをServer→Browserに変更する(非推奨)
こちらは、いろいろ設定を弄っているうちに接続できるようになった、という解決策です。
その後の意味合いを理解すると、この①は非推奨で、後述の②を実施すべきですので、参考程度の記載となります。
URLを「https://localhost:8086」
のまま接続を確立したい場合はAccessを「Server」から「Browser」に変更することで、「Save & Test」後、「Data source is working」となり接続されるようになりました。ところで、このAccessとは何なんでしょうか?
右にある「Help」を選択すると以下のような記載が表示されます。
要約すると、以下のように理解しました。
- ServerはGrafanaのバックエンドを経由してアクセスを試みる(内部通信)
- Browserはブラウザ上から直接アクセスを試みる(外部通信)つまり、今回つまづいた理由はServerのときにURLを「localhost:8086」としてるので、Grafanaコンテナ上の8086ポートにアクセスしようとしたため、Bad Gatewayが発生したということになります。
それが、解決策①では内部通信ではなく、外部通信として、localhost(ローカルPC自身)をアクセスしにいくようになったため、接続できるようになったということになります。
しかし、実際のケースではInfluxDBのようなデータベース層を外部からアクセスできるような状態になっているケースは殆ど無く、DBへは内部通信でアクセスできるようにしたくなります。そのため、今回は以下のような解決策で、アクセスできるようにしました。
解決策② URLを内部通信向けの名前(アドレス)に変更する
今回は、Docker composeよりGrafanaコンテナとInfluxDBコンテナを起動しているため、
docker-compose.yml
の記載やディレクトリ名に依存しますが、今回は一例として以下のような状態となります。$ docker-compose ps Name Command State Ports ------------------------------------------------------------------------------------- influxdb_grafana_grafana_1 /run.sh Up 0.0.0.0:3000->3000/tcp influxdb_grafana_influxdb_1 /entrypoint.sh influxd Up 0.0.0.0:8086->8086/tcp上記の場合、InfluxDBのコンテナ名は「influxdb_grafana_influxdb_1」となります。
docker-composeでは、networkよりデフォルトでお互いのコンテナ名で名前解決ができるため、この「influxdb_grafana_influxdb_1」をURL名とすることでAccessがServerでも接続ができるようになります。
今回の例だと、URLをhttp://influxdb_grafana_influxdb_1:8086
とします。
- 投稿日:2021-01-12T19:19:56+09:00
Nuxt / Laravel(Docker)で作るシンプルなCRUDアプリ
タイトルの通り、フロントはNuxt、バックエンドはLaravelでシンプルなCRUDアプリを制作し、herokuにデプロイしました。それぞれの具体的な解説は別の記事にまとめていきたいと思っています。
NuxtはSSR(ユニバーサル)、API認証にsanctumを使用しています。
機能
バリデーション: コメントを投稿したユーザー(本人)のみ編集と削除ができる
いいね機能: 自分がいいねしたボタンは色が黄色に変化する。2度押すと取り消される。
課題
- エラーハンドリング
- 登録フォームでのエラーメッセージもっと作り込む必要がある。 当初はvee-validate(プラグイン)を導入したが、使い勝手が悪かったため現状はシンプルなメッセージで対応している。
- 前までは動いていたはずなのに、ケアレスミスでいつの間にか動かなくなっている、という状況が発生。 時間のロスなので、テストの重要性を感じた。 それぞれの機能を疎結合にしてテストしやすくしたい。
- Nuxt
- 非同期の理解を深め有効に活用したい。
- 監視プロパティーを活用し、よりインタラクティブな処理を書きたい。
- AWSにデプロイしたい。
参考
- 投稿日:2021-01-12T18:50:50+09:00
【Docker】ローカル(Win, Mac)にサクッとWordpress環境を構築する
Docker DesktopをローカルPCにインストール
https://www.docker.com/products/docker-desktop
お使いの環境(win, mac)に合わせたダウンロードを実行してください。無事インストールされているか下記コマンドで確認
docker -vこれでローカルマシンにDocker Engineが搭載されました。
で、起動しなければ意味がないのでDockerを起動しておいてください。
おそらくクジラのアイコンがどこかにいれば起動していると思います。
※下記はwindowsのタスクトレイの例
Dockerでの作業は、あくまでもDocker Engineという仮想環境の中での出来事であるということは、常に念頭に置いてください。
「環境はローカルホスト(PC)に構築されているんじゃない、Dockerホスト(Engine)に構築されているんだ」
Pythonをインストールする
え?python?何か間違ってませんか?って思った方も多いでしょう。
気持ちは分かります。ただその思いはいったん胸にしまいましょう。
一応、簡単に説明しておくと、
この後、Docker操作を補佐するツールもインストールすることになりますが、
それがPython製のツールなのです。
その名も「Docker Comopose」
そいつを簡単にインストールするにはPythonが話が早いってわけですね。
「python3」「python3-pip」をそれぞれインストールします。
https://www.python.org/
※pythonをインストールして使える状態に持っていく方法はここでは割愛しますが、
winの方はmacより若干複雑かもしれない。健闘を祈る。無事インストールされているか下記コマンドで確認
python3 -VDocker Composeをインストールする
というわけで、Docker操作の補佐ツールを導入しましょう。
pip3 install docker-compose※pipはpythonパッケージ管理ツール。nodeでいうところのnpmだと思ってください
無事インストールされているか下記コマンドで確認
docker-compose --version作業用ディレクトリを作成する
ローカルPCの任意の場所に作成し、そのディレクトリへ移動してください。
今回は「wp_test」とします。
コマンドでも、GUIで手動でも何でもいいです。mkdir ~/wp_test cd ~/wp_test※いやちょっと待てよ、さっきローカルホスト(PC)で作業するわけじゃない、みたいなこと言ってたけど
作業用ディレクトリをこんな形で作るって何だか矛盾してないかい?って思った方、その指摘は鋭いです。
これはあくまで、「ある作業」用という意味で、これから作る予定のWordpressを利用したプロジェクトの本体の場所を意味しません。
後ほど全貌が明らかになるでしょう。今は静観なさい。docker-compose.ymlを作成する
これは何?って感じでしょうね。
名前からしてあれですが、Docker composeの設定ファイルをYAML形式で書いたものです。
ひとまずエディタで下記内容で作成保存して、先ほど作成した該当ディレクトリに置いてください。
※YAML形式とは、空白インデントで構造ブロックを表現する記述方法ですdocker-compose.ymlversion: "3" services: wordpress-db: image: mysql:5.7 networks: - wordpressnet volumes: - wordpress_db_volume:/var/lib/mysql restart: always environment: MYSQL_ROOT_PASSWORD: myrootpassword MYSQL_DATABASE: wordpressdb MYSQL_USER: wordpressuser MYSQL_PASSWORD: wordpresspass wordpress-app: depends_on: - wordpress-db image: wordpress networks: - wordpressnet ports: - 8080:80 restart: always environment: WORDPRESS_DB_HOST: wordpress-db WORDPRESS_DB_NAME: wordpressdb WORDPRESS_DB_USER: wordpressuser WORDPRESS_DB_PASSWORD: wordpresspass networks: wordpressnet: volumes: wordpress_db_volume:※書いてある内容についてはいったん考えずに
Docker Composeでコンテナを起動する
ひとまずこの設定でコンテナを起動させちゃいましょう。
必ずdocker-compose.ymlを置いたディレクトリで実行してください。cd ~/wp_test docker-compose up -d※ここでコンテナが起動しなかった場合、
一つにはDockerEngineそのものが起動しているか再度確認してください。
クジラアイコンがタスクトレイにいればOKです。起動を確認する
Wordpressの初期インストール画面が表示されるはずです。
コマンドでコンテナの起動確認
docker-compose ps起動しているコンテナが表示されているはずです。
※今回は二つ
コンテナを停止、破棄する
docker-compose down最後に
「おいおい、こんな駆け足でいって、伏線の回収もなしかよ!」って声が聞こえてきそうですね。
時間も時間なので、今回はここまでだよ。
ひとまずこの状態でWordpressを設定してみて、いろいろいじってみてほしい。
そうすると様々な問題が出てくるだろう。
そしたらまた会おう。
- 投稿日:2021-01-12T18:18:07+09:00
docker-composeで指定するcommandはDockerfileよりも優先される
優先度
docker-composeでは
build
においてdockerfile
を指定することで、Dockerfileからイメージを生成してコンテナを作成できます。このとき、このDockerfileでデフォルトで実行されるCMDがあります。
DockerfileCMD ["uvicorn", "code.main:app", "--reload", "--host", "0.0.0.0", "--port", "8000"]このDockerfileがある状態で、docker-compose.ymlの
command
に別のコマンドを書き込んでみます。docker-compose.ymlversion: "3.0" services: fastapi: image: "image" container_name: "container" # ビルド build: dockerfile: ./docker/fastapi/Dockerfile context: . restart: always tty: true ports: - "8000:8000" volumes: - .:/app command: /bin/bash -c "sleep 10 && uvicorn code.main:app --reload --reload-dir code --host 0.0.0.0 --port 8000"このとき、docker-compose.ymlのcommandが優先して実行されます。
そのため、10秒スリープしてからuvicornが実行されます。Dockerfileはすでにあって、ymlで簡単に動作を変更できることを考えると、自然な動作かなと思いました。
- 投稿日:2021-01-12T18:09:15+09:00
MacOS の Ansible で 開発用WebサーバのDocker コンテナを作成する
概要
- ansible を使って開発環境用の docker コンテナを作成しようとしたが、ansible-bender を使う方法は、podman と buildah が必要らしく(参考:Ansibleを使ってdockerコンテナを立ち上げる)、MacOS 用の buildah が配布されていないようなので、別の方法を調べてみた。
- ansible の community.docker に含まれるモジュールは、ansible が結局、ssh 接続を前提としているので、パッケージのインストールなど、やりたいことができない。(image や container を外側から触ることはできるが、中身の操作は不可)
- よって、ansible 側から docker のイメージやコンテナを操作するのではなく、Dockefile で docker イメージを構築する際に、イメージ内に ansible をインストールし、そのイメージ内で ansible をローカル実行して、自分自身に必要なパッケージのインストールや設定を行うようにする。(ansible のエージェントレスという利点は失われてしまうことになるが)
環境
- macOS Catalina (10.15.1)
- Docker version 20.10.0, build 7287ab3
- ansible 2.10.3
やったこと
- ansible の実行に必要なディレクトリやファイル、rpm パッケージを全て docker コンテナ側へコピーする。コンテナ内で ansible をローカル実行させるため。
- python, pip のインストール。
- ansible-galaxy から必要なロールのインストール。(community.general, community.crypto)
- いくつかのサービス(chrony, http, mackerel, sshd)起動の設定を外す。docker には1コンテナ1サービスの概念があり、コンテナ内のサービスを制御するのではなく、コンテナ自体の起動、停止によるコントロールが前提となっており、サービスの起動・停止などのコントロールはできないため。
Dockerfile 内で必要なポートを開け(EXPOSE 80 443)、docker run でコンテナ起動時に、それを指定する。
- Dockerfile
FROM centos:centos8 RUN dnf clean all && rm -r /var/cache/dnf && dnf upgrade -y && dnf update -y RUN dnf install -y sudo RUN dnf install -y python3-pip RUN pip3 install ansible RUN ansible-galaxy collection install community.crypto RUN ansible-galaxy collection install community.general ## ansible の実行に必要な設定ファイルをディレクトリごとコピーし、 ## それらを全て dev.yml ファイルから読み込む COPY ./ ./. RUN ansible-playbook dev.yml EXPOSE 80 443 CMD ["/bin/bash"]
- イメージ作成とコンテナ起動時の実行例
## イメージの構築 $ cd (Dockerfile のあるディレクトリ) $ docker build -t web/dev:1.0 . ## コンテナ起動 $ docker run -itd -p 80:80 -p 443:443 --name test web/dev:1.0参考
以上。
- 投稿日:2021-01-12T17:27:46+09:00
Windows環境でAuteMuteUsのDocker利用セルフホスティング
はじめに
AutoMuteUsはAmong usをDiscordのボイスチャットを併用して遊ぶ際に、自動ミュートしてくれるツールです。
最近は勝率とか色々機能が増えてきているようですが、最新機能を利用するにはDockerでセルフホストする必要があります。
Windowsのexeで実行できるものは2.4.3で開発が止まっており、動作も不安定気味です。Dockerでセルフホストに成功したのでやり方を記録しておきます。
AutoMuteUs
https://github.com/denverquane/automuteus環境
Docker Desktop 3.0.4
Docker Compose 1.28.0-rc2
automuteus 6.10.1
galactus 2.4.1AutoMuteUsホスティング手順
githubのDocker Composeに記載されている通りですが、以下に手順を示します。
①下記リンクの [3. Discord の bot を作成する] を参考にbotを作成・招待しTokenを取得する。
Among Us 用超便利 Discord bot “AutoMuteUs” をセルフホストした (公式推奨簡単版)②Docker DesktopとDocker Composeをインストールする。
③下記リンクからymlファイルをダウンロード
https://github.com/denverquane/automuteus/blob/master/docker-compose.yml④下記リンクからsampl.envをダウンロード
https://github.com/denverquane/automuteus/blob/master/sample.env⑤ダウンロードしたsampl.envを.envに名前変更し、下記の項目を記載する。
AUTOMUTEUS_TAG:ここから最新のバージョン番号を記載
GALACTUS_TAG:ここから最新バージョンの番号を記載
DISCORD_BOT_TOKEN:①で取得したトークンを記載
GALACTUS_HOST:automuteusのコンテナがアクセスするgalactusのホストを記載。
今回はローカルで完結するのでhttp://localhost
と記載
GALACTUS_EXTERNAL_PORT:ホストへのアクセス時のポート番号を記載。今回は80
。変更する場合はGALACTUS_HOSTにもポートを記載する。⑥作成した
.env
とdocker-compose.yml
を同じフォルダ内に配置し、そこをカレントディレクトリにしてコマンドラインを起動。⑦コマンド実行
docker-compose pull
⑧コマンド実行
docker-compose up -d
以上でホスト完了。Docker Desktopで稼働状況を確認し、正常に動作していればOK。
利用
下記リンクから最新のAmongUsCaptureをダウンロードし、起動して [Setting] - [Discord] - [Discord token] に取得したトークンを入れる。
https://github.com/denverquane/amonguscaptureゲームを起動し、botを招待したDiscordのチャンネルで
.au new
と入力すればbotからDMがくるので、リンクをクリックしてAmongUsCaptureとリンクすれば利用できる。
その他のコマンドは公式Githubページを参照。補足
環境構築時に発生したトラブルについて
galactusで下記のエラーが発生し、redisに接続できない。
websocket: close 4004: Authentication failed.
No REDIS_USER specified.
No REDIS_PASS specified.上記エラーが発生するのはDiscordと通信が取れないことが原因らしい。
同じポート番号が他のコンテナで既に使われていないか、
Discordのトークンが合っているかなどを確認するとよい。
- 投稿日:2021-01-12T15:38:37+09:00
【入門】はじめての Docker Desktop の CentOS コンテナでの GridDB Community Edition のセットアップ
【入門】はじめての Docker Desktop の CentOS コンテナでの GridDB Community Edition のセットアップ
Docker Desktop 上の CentOS コンテナ (仮想環境)で、オープンソースのGridDB Community Editionをセットアップの方法について、はじめからていねいにまとめて紹介します。また、途中で Dockerコマンドなどについても詳しく説明していくので、 Docker初心者で、DockerのCentOS コンテナに GridDB Community Edition をセットアップしたいという方には、参考になると思います。
具体的には、ホストOSかmacOS に Docker for Mac がインストールされ CentOS のDockerコンテナがビルドされた1台の MacBook に GridDB Community Edition をインストール・環境設定し、GridDBサーバの起動/停止やサンプルプログラムを実行し動作確認をします。
なお、Docker Desktop for Windows の環境の場合でも手順などはほとんど同じです。
流れ
- 事前準備
- GridDB インストール
- 環境設定
- GridDB サーバの起動
- サンプルプログラムの実行
- GridDB サーバの停止
- セットアップ済みのコンテナの保存
事前準備
CentOS のDockerコンテナを用意
今回は、すでにDocker Desktop の環境が構築され、その上に動作確認済の CentOS のDockerイメージが用意されていることを前提としています。これから用意する場合は、次の2つの記事を参照して頂ければと思います。
「【入門】はじめての Docker Desktop for Mac のインストールと CentOS の仮想環境構築のセットアップ - Qiita」
「【入門】はじめての Docker Desktop for Windows のインストールと CentOS の仮想環境構築のセットアップ - Qiita」なお、今回の動作確認済みのCentOSは、CentOS 7.9.2009 imagesを用いています。
以降、ここでは、動作確認済の CentOS のイメージの名前は centos:gahoh とします。
ターミナル を起動して、docker images コマンドを用いて、ローカルに保存した Docker イメージの一覧を表示します。
次のようなCentOS のDocker イメージが用意されているものとします。$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE centos gahoh 8beaf0d882f9 53 minutes ago 663MB centos centos7 8652b9f0cb4c 6 weeks ago 204MBCentOS のDockerイメージ centos:gahoh からコンテナをビルドして起動します。
CentOS コンテナ の作成・起動
CentOS のイメージからCentOS コンテナをビルドして起動するには docker run コマンドを用います。
次のように docker run コマンドを実行して、コンテナをビルド・起動します。$ docker run -it --name="centos" centos:gahoh /bin/bash #ここでは、CentOS のDockerイメージ centos:gahoh から コンテナをビルドし、同時にコンテナも起動し、そのタイミングで自動的にログインし、そのまま bash シェルに接続します。
ここでは新しく作成するコンテナに "centos" という名前を付けています。GridDB のインストール
GridDB Community Editionのパッケージのインストールは次の通りです。
(CentOS) $ sudo rpm -ivh griddb-X.X.X-(X.)linux.x86_64.rpm (Ubuntu) $ sudo dpkg -i griddb_X.X.X_amd64.deb (openSUSE) $ sudo rpm -ivh griddb-X.X.X-opensuse.x86_64.rpm ※ X.X.X-(X.) または X.X.X はバージョンを意味します。今回、Docker Desktop for Mac の CentOS上で、GitHubのサイトの Release の Assets のRPMパッケージを用いて直接インストールします。RPMパッケージのURLは、次の通りです。
https://github.com/griddb/griddb/releases/download/vX.X.X/griddb-X.X.X(-X)-linux.x86_64.rpm
X.X.X または X.X.X-(X) はバージョンを意味します。
今回、ここでインストールするバージョンは、v4.5.2とします。よって、インストールに用いるRPMパッケージのURLは、次のようになります。
https://github.com/griddb/griddb/releases/download/v4.5.2/griddb-4.5.2-linux.x86_64.rpm
では、インストールします。
RPMパッケージをインストールする/アンインストールする rpm コマンドを用います。rpm コマンド でインストールします。
# rpm -ivh https://github.com/griddb/griddb/releases/download/v4.5.2/griddb-4.5.2-linux.x86_64.rpmインストールが開始されます。
# rpm -ivh https://github.com/griddb/griddb/releases/download/v4.5.2/griddb-4.5.2-linux.x86_64.rpm Retrieving https://github.com/griddb/griddb/releases/download/v4.5.2/griddb-4.5.2-linux.x86_64.rpm Preparing... ################################# [100%] ------------------------------------------------------------ Information: User gsadm and group gridstore have been registered. GridDB uses new user and group. ------------------------------------------------------------ Updating / installing... 1:griddb-4.5.2-linux ################################# [100%] #これで、インストールは完了です。
インストール後のユーザとグループ
このRPMパッケージをインストールすると、CentOSのユーザ gsadm とグループ gridstore が自動的に作成されます。ユーザ gsadmは、GridDBを運用するための 管理ユーザとして使用します。
ユーザ gsadm でログインすると環境変数 GS_HOMEとGS_LOGが自動的に設定されます。また、運用コマンドの場所が環境変数 PATHに設定されます。インストール後のディレクトリ構成
インストールされたGridDBノードのディレクトリ構成を確認します。
ノードの定義ファイルやデータベースファイルなどを配置するGridDBホームディレクトリと、インストールしたファイルを配置するインストールディレクトリが作成されます。環境設定
管理ユーザ gsadm の設定
管理ユーザは、運用コマンドの実行や、管理者権限のみ許可されている操作を実行する際に用います
管理ユーザ gsadm にはパスワードが設定されていないので、パスワードを設定してください。# passwd gsadm Changing password for user gsadm. New password: (パスワードを入力します) Retype new password: (パスワードを入力します) passwd: all authentication tokens updated successfully. # gpasswd -a gsadm wheel Adding user gsadm to group wheelここでは、CentOSのパスワードポリシーに準じたパスワードを設定してください。
管理ユーザ gsadm のパスワード設定
管理ユーザ gsadm のパスワードが設定されていない場合、サーバは起動できないため必ずパスワードを設定してください。
ユーザ gsadm でログインし、gs_passwd コマンドを使用して、管理ユーザのパスワードの設定します。# su - gsadm $ gs_passwd admin Password: (パスワードを入力します) Retype password: (パスワードを入力します) $ここでは、パスワードを とりあえず admin と入力して雪庭してください。
クラスタ名の設定
インストール後に GridDB を動作させるためには、アドレスやクラスタ名などのノードのパラメータの初期設定が必要です。ここでは、必須項目の クラスタ名 のみ設定を行い、それ以外はデフォルト値を用います。
クラスタの クラスタ名 をクラスタ定義ファイルに記述します。クラスタ定義ファイルは、/var/lib/gridstore/conf/gs_cluster.json です。
"clusterName":"" の部分にクラスタ名を記載します。ここでは、myCluster という名前を用います。$ vi conf/gs_cluster.json { "dataStore":{ "partitionNum":128, "storeBlockSize":"64KB" }, "cluster":{ "clusterName":"", "replicationNum":2, "notificationAddress":"239.0.0.1", "notificationPort":20000, "notificationInterval":"5s", "heartbeatInterval":"5s", "loadbalanceCheckInterval":"180s" }, "sync":{ "timeoutInterval":"30s" }, "transaction":{ "notificationAddress":"239.0.0.1", "notificationPort":31999, "notificationInterval":"5s", "replicationMode":0, "replicationTimeoutInterval":"10s" }, "sql":{ "notificationAddress":"239.0.0.1", "notificationPort":41999, "notificationInterval":"5s" } }”clusterName”:””の部分にクラスタ名 myCluster を挿入して保存します。
$ vi conf/gs_cluster.json { "dataStore":{ "partitionNum":128, "storeBlockSize":"64KB" }, "cluster":{ "clusterName":"myCluster", "replicationNum":2, "notificationAddress":"239.0.0.1", "notificationPort":20000, "notificationInterval":"5s", "heartbeatInterval":"5s", "loadbalanceCheckInterval":"180s" }, "sync":{ "timeoutInterval":"30s" }, "transaction":{ "notificationAddress":"239.0.0.1", "notificationPort":31999, "notificationInterval":"5s", "replicationMode":0, "replicationTimeoutInterval":"10s" }, "sql":{ "notificationAddress":"239.0.0.1", "notificationPort":41999, "notificationInterval":"5s" } }サーバの起動
GridDBノードの起動/停止、クラスタの開始/停止の操作をやってみましょう。起動や停止の操作方法はいくつかあるようですが、ここでは、運用コマンドを使ってみます。なお、運用コマンドは gsadm ユーザで実行で実行します。
サーバを起動する
ノードを起動する
ノードを起動するは、運用コマンドの gs_startnode コマンドを用います。
ユーザ認証オプション -u には管理ユーザ のユーザ名: admin とパスワード (ここでは、admin) を指定し、ノードの起動を待ち合せる -w オプションを指定します。$ gs_startnode -u admin/admin -w . Started node.クラスタを開始する
クラスタの開始するには、運用コマンドの gs_joincluster コマンドを用います。 ユーザ認証オプション-uには管理ユーザのユーザ名 admin とパスワード(ここでは、admin) を指定し、クラスタの開始を待ち合せる -w オプションを指定します。クラスタ名を -c オプションで指定します.
$ gs_joincluster -u admin/admin –w -c myCluster .. Joined nodeクラスタが開始されているかなどのクラスタの状態を確認するのは、運用コマンドの gs_stat コマンドを用います。
ユーザ認証オプション -u には管理ユーザ admin のユーザ名とパスワードを指定します。また、クラスタのステータスを確認するために、"Status"の表記の行のみを grep で抽出した方がよいでしょう。$ gs_stat -u admin/admin | egrep Status "clusterStatus": "MASTER", "nodeStatus": "ACTIVE", "partitionStatus": "NORMAL","clusterStatus"、"nodeStatus"、"partitionStatus"が上のように表示されていれば、正常に起動している状態で、アプリケーションからクラスタにアクセスが可能になります。
サンプルプログラムの実行
$ cd $ export CLASSPATH=${CLASSPATH}:/usr/share/java/gridstore.jar:. $ mkdir gsSample $ cp /usr/griddb-4.5.2/docs/sample/program/Sample1.java gsSample/. $ javac gsSample/Sample1.java $ java gsSample/Sample1 239.0.0.1 31999 myCluster admin admin Person: name=name02 status=false count=2 lob=[65, 66, 67, 68, 69, 70, 71, 72, 73, 74]JDKがインストールされていない場合、 CentOS の標準の yum リポジトリに java-1.8.0-openjdk という名前があります。のOpenJDKの Java 8 (JDK) 開発環境のパッケージです。
# sudo yum -y install java-1.8.0-openjdk-develサーバの停止
サーバを停止する
起動の流れとは逆に、クラスタを安全に停止してから、各ノードを停止します。クラスタを停止した段階で、アプリケーションからはクラスタにアクセスできなくなります。
クラスタを停止する
運用コマンドの gs_stopcluster コマンドを実行します。クラスタ停止コマンドを実行した時点で、アプリケーションからはクラスタにアクセスできなくなります。
ユーザ認証オプション -u には管理ユーザ admin のユーザ名とパスワードを指定し、クラスタの停止を待ち合せる -w オプションを指定します。$ gs_stopcluster -u admin/admin -w . Stopped clusterノードを停止する
運用コマンドの gs_stopnodeコマンドを実行し、ノードを停止(シャットダウン)します。必ず、クラスタを停止してからノードを停止します。
ユーザ認証オプション -u には管理ユーザ admin のユーザ名とパスワードを指定し、クラスタの停止を待ち合せる -w オプションを指定します。$ gs_stopnode -u admin/admin -w Stopping node . Stopped nodeセットアップ済みの環境の保存
セットアップした動作環境を新たな Docker イメージとして保存
コンテナで変更した作業の内容を新たなイメージとして保存するコマンドとして docker commit というコマンドが用意されています。これを使って GridDB をインストール・環境設定するために変更を加えたコンテナをイメージとして保存しておきます。
いったん、コンテナから抜けて、docker commit コマンドで"centos"というコンテナを"centos:gahoh"という名前のイメージに上書き保存します。今後、これで、GridDBの動作環境を楽に使えるようにします。
保存するコンテナを停止する
コンテナから抜けます。
$ exit logout # exit exit $これで、コンテナ centos は停止しました。
docker ps コマンドで、 -a オプションをつけて、停止中のコンテナを含めたすべてのコンテナを表示します。$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES cd115c8ce57b centos:gahoh "/bin/bash" 37 minutes ago Exited (0) 2 minutes ago centos $停止したコンテナをイメージに保存する
その前に、docker images コマンドで、現在取得したイメージを確認します。
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE centos gahoh 8beaf0d882f9 2 hours ago 663MB centos centos7 8652b9f0cb4c 6 weeks ago 204MBセットアップした動作環境のCentOS コンテナの"centos"を docker commit コマンドで、イメージ "centos:gahoh" という名前のイメージに上書き保存します。
$ docker commit centos centos:gahoh sha256:9d94ca66706c330a7b2c7ee49c8c29ccc528e3ae54cd757085e0e17b21e27ddd $一応、docker imagesコマンドにて、イメージ "centos:gahoh" が更新されたことを確認しておきましょう。
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE centos gahoh 9d94ca66706c 9 seconds ago 709MB centos centos7 8652b9f0cb4c 6 weeks ago 204MB $これで、GridDB のインストール・環境設定をおこなったコンテナが イメージ centos:gahoh に上書き保存されたことが確認できます。
さいごに
Docker Desktop for Mac 上の CentOS コンテナ (仮想環境)で、GridDB Community Editionを構築・動作確認をしながら、一連の手順を詳細に記述したつもりです。 もし、記述について誤りがあったり、気になることがあれば、編集リクエストやコメントでフィードバックしていただけると助かります。
- 投稿日:2021-01-12T12:24:46+09:00
https-portal productionで証明書が取得できない時 (Response Code: 403)
stagingではlet's encryptからテスト用の証明書を発行できるが
productionに変更しコンテナを立ち上げると以下の様なエラーが発生するエラー内容
https-portalコンテナのログResponse Code: 403 Response: {u'status': 403, u'type': u'urn:ietf:params:acme:error:unauthorized', u'detail': u'An account with the provided public key exists but is deactivated'} ================================================================================ Failed to sign ドメイン名 Make sure you DNS is configured correctly and is propagated to this host machine. Sometimes that takes a while. ================================================================================ Failed to obtain certs for ドメイン名レート制限かかっているかも?
https://crt.sh/
にてドメインでggっても証明書を発行した履歴が見つからない、、これ証明書発行できてないんじゃないか?ポート DNSの設定を確認
一通りポート、DNSの設定を確認するも特にこれといったエラー項目は確認できず
解決方法
https-portalのリポジトリのREADME.mdの説明を全て読んでみる
Automatic Container Discovery
WARNING: WE STRONGLY RECOMMEND AGAINST USING THIS FEATURE UNLESS ABSOLUTELY NECESSARY as exposing Docker socket to a container (even with :ro) essentially gives the container root access to your host OS. If you insist, verify the source code carefully. Read more
HTTPS-PORTAL is capable of discovering other Docker containers running on the same host, as long as the Docker API socket is accessible within the container.あれ、、もしかしてコンテナ検出できてない?
以下記載通りにvolumeの記述を変更してみる
services: https-portal: # ... volumes: - /var/run/docker.sock:/var/run/docker.sock:ro # DANGEROUS, see the warning aboveコンテナを再度立ち上げログを確認しつつ数分待ってみる
証明書が取得できました!!!!
- 投稿日:2021-01-12T10:56:52+09:00
GitHub Actions/Cache : Dockerコンテナ上でbundle installしたgemをキャッシュする
GitHub AcitonsでRailsプロジェクトのrspec/rubocopを実行するような場合に、
bundle install
したgemのキャッシュを行いたいのだが、Permission denied
エラーが出てうまくキャッシュが作れず、キャッシュキーが汚染1されることがあった。error例Post job cleanup. /bin/tar --posix --use-compress-program zstd -T0 -cf cache.tzst -P -C /home/runner/work/project/project --files-from manifest.txt /bin/tar: ../../../../../tmp/cache/bundle/gems/puma-5.1.1/ext/puma_http11/.gem.20201227-1-wtkvl5: Cannot open: Permission denied /bin/tar: ../../../../../tmp/cache/bundle/gems/mini_racer-0.3.1/ext/mini_racer_extension/.gem. [中略] /bin/tar: ../../../../../tmp/cache/bundle/gems/sassc-2.4.0/ext/.gem.20201227-1-1ompol5: Cannot open: Permission denied /bin/tar: Exiting with failure status due to previous errors Warning: Tar failed with error: The process '/bin/tar' failed with exit code 2上記のエラーはローカルの
/var/cache/bundle
ディレクトリを、コンテナの/bundle
にマウントした状態でBUNDLE_PATH=/bundle bundle install
を実行し、/var/cache/bundle
をActions/Cache
でキャッシュさせる場合に発生したdocker-compose と workflow のyamlは下記のような感じ
docker-compose.yamlversion: '3.7' services: app: ... volumes: - ./:/app:cached - /var/cache/bundle:/bundle.github/workflows/ci.ymljobs: ... rspec: ... env: GEMS_CACHE_DIR: /tmp/cache/bundle steps: ... - name: Cache bundle gems id: cache-bundle-gems uses: actions/cache@v2 with: path: ${{env.GEMS_CACHE_DIR}} key: ${{ runner.os }}-${{ matrix.ruby }}-${{ env.GEM_CACHE_TAG }}-${{ hashFiles('Gemfile.lock') }} restore-keys: | ${{ runner.os }}-${{ matrix.ruby }}-${{ env.GEM_CACHE_TAG }}-解決策 1 アクセス権限を書き換える
アクセス権限の問題なので、雑にアクセス権限を書き換えてしまう方法。
cache作成時のtarコマンドでsudoがつけられたらいいのだが、そういうオプションはないので、下記のようなアクション
steps
の最後に差し込む.github/workflows/ci.yml- name: Fix permissions of bundle id: fix-permissions-of-bundle run: sudo chmod -R a+rwx ${{env.GEMS_CACHE_DIR}}この方法で多分大丈夫。
ですが、アクセス権限書き換えることになるので、その辺りの動作確認は取れません(そこが問題になることなんてほぼないと思いますが…
解決策 2 コンテナ上でtarを作成してcacheさせる
アクセス権限の問題が発生するのは、コンテナ上で
bundler install
しているのにローカルでtarを作成しているため。コンテナ上で
/bundle
のtarを作成し、そのtarをActions/Cache
でキャッシュして貰えば問題ありません。下記の設定では必要最低限の軽量コンテナのみを立ち上げて(今回は
standalone
という名前のコンテナを使用している)、tarを作っています。.github/workflows/ci.ymlenv: GEMS_ARCHIVE_DIR: /tmp/cache/bundle-gem-archive ... # $GEMS_ARCHIVE_DIR ディレクトリをキャッシュ - name: Cache bundle gems id: cache-bundle-gems uses: actions/cache@v2 with: path: ${{ env.GEMS_ARCHIVE_DIR }} key: ${{ runner.os }}-${{ matrix.ruby }}-${{ env.GEM_CACHE_TAG }}-${{ hashFiles('Gemfile.lock') }} restore-keys: | ${{ runner.os }}-${{ matrix.ruby }}-${{ env.GEM_CACHE_TAG }}- # $GEMS_ARCHIVE_DIR をマウントした軽量コンテナ上で /archive/bundle.tar からファイルを抽出 - name: Unarchive bundle gems cache id: unarchive-bundle-gems-cache run: test -f ${{env.GEMS_ARCHIVE_DIR}}/bundle.tar && docker-compose run --rm -v ${{ env.GEMS_ARCHIVE_DIR }}:/archive:cached standalone tar -xf /archive/bundle.tar -C / || echo "bundle gem cache does not exist." ... # 軽量コンテナ上で $GEM_HOME の内容をtarで固め、/archive/bundle.tar の名前で保存 - name: Create bundle gems archive id: create-bundle-gems-archive if: steps.cache-bundle-gems.outputs.cache-hit != 'true' run: docker-compose run --rm -v ${{ env.GEMS_ARCHIVE_DIR }}:/archive:cached standalone tar -cf /archive/bundle.tar -C / bundleこの方法の場合、コンテナ上でtarを実行するので多少遅くなるようだが自分の環境の場合はほぼ誤差(数秒程度)しか変わらなかった(gemの量などにもよると思う)。
- 投稿日:2021-01-12T09:38:02+09:00
Docker-Volumeのバックアップとリストア
Docker-Volumeのバックアップとリストア
何故か標準でバックアップ方法が存在しない
DockerはImageやConteinerは簡単にバックアップがとれるのに、何故かVolumeに関しては標準的なバックアップ方法が存在しません。ということでできる限り簡単な方法を考えてみました。
ネットで検索すると出てくる方法
VolumeをマウントするConteinerを作って、バックアップを作成する方法が多数ヒットします。ただ、残念なのはその出力先です。何故かバックアップファイルをConteiner内、もしくはDockerホスト上のディレクトリに作成していました。
それをやられると、リモートでコマンドを使った場合に、手元にバックアップが残りません。作成したバックアップを何らかの手段でさらに引き寄せる必要があります。非常に面倒です。
標準入出力を使おう
dockerコマンドは標準入出力でConteinerとデータをやりとりすることが出来ます。つまりバックアップファイルを標準出力に出すだけで、コマンドを実行した環境にバックアップ結果を吐き出すことが出来ます。
バックアップコマンドを作ってみる
以下のようなコマンドを実行すると、期待通りに動いてくれます。
>
によるリダイレクトはConteiner上ではなく、dockerコマンドを実行したローカル環境で働くからです。
- バックアップコマンド
docker run --rm -v [Dockerボリューム]:/backup busybox tar cvz -C /backup . > [バックアップファイル名.tar.gz]
- リモートのDockerホストに対してボリュームのバックアップ
docker -H [ホスト名] run --rm -v [Dockerボリューム]:/backup busybox tar cvz -C /backup . > [バックアップファイル名.tar.gz]リモートのバックアップした場合も、もちろんローカル環境にバックアップをとることが出来ます。
リストアコマンドを作ってみる
- リストアコマンド
dockerコマンドで-iを使い、標準入力を使えるようにします。
docker run --rm -i -v [Dockerボリューム]:/backup busybox tar xvz -C /backup < [バックアップファイル名.tar.gz]
- リモートのDockerホストに対してボリュームのリストア
docker -H [ホスト名] run --rm -i -v [Dockerボリューム]:/backup busybox tar xvz -C /backup < [バックアップファイル名.tar.gz]高速化したい
バックアップやリストアは出来るようになりましたが、もっと高速に処理したくなります。tarでzオプションを使うとgzipが使われますが、これをpigzのような並列処理対応のコマンドで置き換えれば、ホスト側のCPUのコア数に応じて高速化が見込めます。しかしざっと探したところ、pigzが入っている軽量Imageが見つかりません。もしかしたらどこかにあるかもしれませんが、探すより作った方が早いので作ることにしました。
バックアップ用Imageを作成する
pigz付きalpineのImageを作成します。
コマンドを書かなくても良いように、CMDも設定しておきます。
- バックアップ
FROM alpine RUN apk --no-cache add pigz CMD sh -c "tar cv -C /backup . | pigz"
- リストア
FROM alpine RUN apk --no-cache add pigz CMD sh -c "pigz -d | tar xv -C /backup"Docker Hubに登録
- 置き場所
- 使い方
- バックアップ
docker --rm -v [DOCKER-VOLUME]:/backup dktools/backup > backup.tar.gz
- リストア
docker --rm -i -v [DOCKER-VOLUME]:/backup dktools/restore < backup.tar.gz
今のところパラメータ指定などはありませんが、気が向いたらそのうち機能を追加します。
まとめ
私の場合Dockerはtls接続でリモート管理しているので、バックアップをローカルに呼び寄せないと面倒なので、今回のようなものを作成しました。ちなみにsshのポートフォワードをしている場合も、リモートバックアップは可能です。ただtlsで直接接続している場合とポートフォワードでは、ポートフォワードの転送速度が数倍遅いので、出来ることならtls設定を入れた方が効率は上がります。
tls設定に関してはこちらに記事を書いています。
UbuntuにDockerをインストールし、tlsを使ったリモート接続の設定を行う
- 投稿日:2021-01-12T00:12:17+09:00
【Rails AWS Docker】既存Ruby on Rails + MySQLアプリをDockerで構築し、AWSにデプロイする(6)
ポートフォリをとして作ったRuby on RailsアプリをDockerコンテナ化し本番環境をAWSで構築するまでの道のりです。
ポートフォリオ自体はこちらとなります。
【ポートフォリオ】転職活動時に作成したポートフォリオの概要(テッ◯キャンプ)かなり苦しめられたので、どなたかのお役に立てれば。
タイトル 1 ローカル環境のRailsアプリをDockerコンテナ化 2 AWSにVPCを作成する。パブリックサブネットを作成する 3 プライベートサブネットを作成する 4 EC2インスタンスを作成する 5 RDSを作成する 6 DockerコンテナをAWSにアップロードする DockerコンテナをAWSにアップロードします。
この項目では、かなり苦しめられました。ngixやpuma、RDSなど接続しなくてはいけないものが多々あり、また、AWS内にコンテナを構築することにより今、自分がどこにいるのか、よくわからなくなる状態に陥ることがありました。
この記事通りに、行ってもうまくいかないかもしれませんが、少しでもどなたかのお力になれればと思います。
自分はできれば、再びあのような思いをしたく無いので忘れないうちに記事として残しておきました。作成したAWSインスタンスにローカルdockerコンテナをアップロードしていきます。
コンテナ内での環境変数を設定します。
現状、database.ymlを確認すると
database.ymlusername: root password: password host: dbこのように、セキュアな情報がハードコーディングされています。
このままではgithubのコードから漏洩する危険があるので、本番環境のコンテナ内で環境変数を用いてセキュアな情報を設定します。環境変数については、参考までに下記をご覧下さい。
環境変数について環境変数を利用するために、dotenv-railsというgemをインストールします。
Gemfileに以下を追記します。Gemfile.gem 'dotenv-rails'dotenv-railsをインストールすることにより、「.env」ファイルに記載された環境変数をdockerコンテナ内で、下記のような記述で取り出せる様になります。
ENV['DATABASE_PASSWORD']また、.envファイルをgithubに上げてしまうと元も子も無いので、gitignoreに追記します。
.env.envを下記の様に記載してアプリ直下に配置します。
DB_USERNAME=root DB_PASSWORD=gakjadfmoaeur DB_HOST=fito2-db-instance.〇〇〇〇〇〇.ap-northeast-1.rds.amazonaws.com DB_DATABASE=fitO2_dbDB_HOSTはRDSのエンドポイントです。
AWSのRDSダッシュボードのデーターベースをクリックし、一覧から該当のRDSを選択すると確認できます。database.ymlの修正
database.ymlに下記を追加して、本番環境は環境変数から値を読み込むようにします。
database.ymlproduction: <<: *default database: <%= ENV['DB_DATABASE'] %> adapter: mysql2 encoding: utf8mb4 charset: utf8mb4 collation: utf8mb4_general_ci host: <%= ENV['DB_HOST'] %> username: <%= ENV['DB_USERNAME'] %> password: <%= ENV['DB_PASSWORD'] %>nginx.confの修正
以下の部分を本番用に修正します。
nginx.confserver { listen 80; # =========ローカルと本番切り替え=========== server_name 固定IP; # server_name localhost; # ======================================docker-compose.ymlの修正
docker-compose.ymlversion: '3' services: app: build: context: . # =========ローカルと本番切り替え=========== command: bundle exec puma -C config/puma.rb -e production # command: bundle exec puma -C config/puma.rb # ====================================== volumes: - .:/fitO2 - public-data:/fitO2/public - tmp-data:/fitO2/tmp - log-data:/fitO2/log networks: - fitO2-network # =========ローカルと本番切り替え=========== # depends_on: # - db # db: # image: mysql:5.7 # environment: # MYSQL_ROOT_PASSWORD: password # MYSQL_USER: user # MYSQL_PASSWORD: password # MYSQL_DATABASE: fitO2_development # volumes: # - db-data:/var/lib/mysql # networks: # - fitO2-network # ====================================== web: build: context: ./nginx_docker volumes: - public-data:/fitO2/public - tmp-data:/fitO2/tmp ports: - 80:80 depends_on: - app networks: - fitO2-network volumes: public-data: tmp-data: log-data: db-data: networks: fitO2-network: external: true変更点
・dbコンテナは本番環境ではRDSを使用するので不要のため、コメントアウト
(appコンテナのdepend onもまとめてコメントアウトします)
・command のrails s に -e production を追記して、本番環境でサーバー立ち上げるようにした。AWSインスタンス上にdockerコンテナを構築する。
今一度、AWSインスタンス上にdockerコンテナを構築するまでの流れを整理します。
今、現状ローカルでは、下記のようにfitO2というファイルを元に、下記の様なdockerコンテナをbuildできる状態でした。
そして、fitO2というファイルを書き換えて、以下の様なコンテナが作成されるように修正しました。(DBコンテナ削除)
その、fitO2をgithubにpushします。そして、AWS側からclone(2回目以降はpull)します。
cloneしたfitO2を元に、AWS内でbuildしてコンテナを構築し、AWS内に作成しているRDSと接続します。
通信の流れはオレンジの矢印となります。
githubへプッシュ
まずは、修正したファイルをコミットしてgithubへpushします。
AWSにdockerをインストール
ssh接続でAWSにログインし、dockerをインストールします。
sudo yum install -y docker //インストール sudo service docker start //docker起動 sudo usermod -G docker ec2-user //ec2-userに権限付与 exit //ログアウト //再度sshでログイン docker info下記の様な表示がされたらオッケーです。
Client: Debug Mode: false Server: Containers: 0 Running: 0 Paused: 0 Stopped: 0 Images: 0 Server Version: 19.03.13-cesudo chkconfig docker on //EC2起動時にDockerを自動で立ち上げるdocker-composeをインストールします。
sudo curl -L "https://github.com/docker/compose/releases/download/1.24.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose docker-compose -v docker-compose version 1.24.0, build 0aa59064 //上記の様にバージョンが表示されたら成功gitをインストールします。
sudo yum install -y git秘密鍵を作成します。(質問は全てエンター)
ssh-keygen -t rsa -b 4096作成した秘密鍵を表示し、コピーします。
cat ~/.ssh/id_rsa.pubhttps://github.com/settings/keys
こちらにアクセスします。titleを適宜入力し、keyのところに先ほどコピーした文字列を貼り付けます。
(ssh-rsa~から含めます)ssh -T git@github.com上記を打ち込んで、途中yesと入力し、下記の様に表示されればAWSとgithubの認証が成立しました。
Hi yourname! You've successfully authenticated, but GitHub does not provide shell access.以後、AWSインスタンス側から自身のgithubに対し、pull等ができる様になります。
githubからcloneします。(URLはリポジトリを表示したときのURL)
cd / //ルート直下に移動します。homeディレクトリでコンテナを展開すると、pumaとnginxの連携でエラーが出る場合がありますl。puma.sockの読み取りエラーsudo git clone https://github.com/〇〇〇〇〇〇/〇〇〇〇〇〇ls //lsと打って、ディレクトリがあるか確認する。今、gitignoreに記載したファイル(.env master.key)は含まれていません。そこで、ssh通信を用いてローカルからAWSに直接ファイルを転送します。
exit //一旦ログアウトして、ローカルのfitO2ファイルに移動 sudo scp -i ~/.ssh/fitO2_key.pem .env ec2-user@固定IP:/home/ec2-user/ sudo scp -i ~/.ssh/fitO2_key.pem config/master.key ec2user@固定IP:/home/ec2-user //scpコマンドを用いて、AWSに.envを転送します。 .env のように転送したファイルが表示されたらオッケー。 //権限の関係で一旦、ホームディレクトリに転送します。再度、ログイン。
cd ls -aホームディレクトリに移動して.envとmaster.keyが存在していたら問題ない。
.envとmaster.keyを移動させる。sudo mv .env /fitO2 sudo mv master.key /fitO2/config念のため移動してるか確認
ls -a /fitO2/ ls -a /fitO2/configコンテナの起動
cd /fitO2 docker-compose build //コンテナを作成します。 (Permition deniedになった場合は、sudo chmod 777 /usr/local/bin/docker-compose を実行します。) docker network create fitO2-network //ネットワークを作成します。 docker-compose run app rails assets:precompile RAILS_ENV=production //プリコンパイルを実施 docker-compose up //コンテナを起動します。下記のように表示されていれば問題なく起動しています。
Creating fito2_app_1 ... done Creating fito2_web_1 ... done Attaching to fito2_app_1, fito2_web_1 app_1 | Puma starting in single mode... app_1 | * Version 3.12.6 (ruby 2.5.1-p57), codename: Llamas in Pajamas app_1 | * Min threads: 5, max threads: 5 app_1 | * Environment: production app_1 | * Listening on tcp://0.0.0.0:3000 app_1 | * Listening on unix:///fitO2/tmp/sockets/puma.sock app_1 | Use Ctrl-C to stop別タブを開いて、AWSにログインします。
データベースの作成
docker-compose exec app rails db:create db:migrate RAILS_ENV=production docker-compose exec app rails db:seed RAILS_ENV=production //(必要に応じて)以上で、http://固定IPにアクセスした場合、正しく表示されるはずです。
RDSのデーターベース確認方法
dockerコンテナにログインし、mysqlを起動させます。
docker ps //コンテナIDを調べます。NAMESがfito2_app_1の方のCONTAINER IDをコピーします。
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c5ec64f0ea76 fito2_web "/bin/sh -c '/usr/sb…" 5 minutes ago Up 5 minutes 0.0.0.0:80->80/tcp fito2_web_1 442b9ddb3a20 fito2_app "bundle exec puma -C…" 5 minutes ago Up 5 minutes fito2_app_1コンテナにログインします
docker exec -it 442b9ddb3a20 bashmysqlを起動させます。
service mysql startmysql -u root -h RDSのエンドポイント -p //パスワードを入力してログインセキュリティーグループで制限んしているので、作成したEC2コンテナからしかアクセスできません。
ローカルから試してみてください。
以上となります。
参考
EC2上でRailsアプリケーションにDockerを導入する(Rails、Nginx、RDS)
開発環境において既存のRailsアプリにDockerを導入する方法(Rails、nginx、mysql)
無料!かつ最短?で Ruby on Rails on Docker on AWS のアプリを公開するぞ。
【画像付きで丁寧に解説】AWS(EC2)にRailsアプリをイチから上げる方法【その1〜ネットワーク,RDS環境設定編〜】
Nginx + Rails (Puma) on Docker のいくつかの実用パターン
Docker + Rails + Puma + Nginx + MySQL
- 投稿日:2021-01-12T00:12:17+09:00
【Rails AWS Docker 】既存Ruby on Rails + MySQLアプリをDockerで構築し、AWSにデプロイする(6)
ポートフォリをとして作ったRuby on RailsアプリをDockerコンテナ化し本番環境をAWSで構築するまでの道のりです。
ポートフォリオ自体はこちらとなります。
【ポートフォリオ】転職活動時に作成したポートフォリオの概要(テッ◯キャンプ)かなり苦しめられたので、どなたかのお役に立てれば。
タイトル 1 ローカル環境のRailsアプリをDockerコンテナ化 2 AWSにVPCを作成する。パブリックサブネットを作成する 3 プライベートサブネットを作成する 4 EC2インスタンスを作成する 5 RDSを作成する 6 DockerコンテナをAWSにアップロードする DockerコンテナをAWSにアップロードします。
この項目では、かなり苦しめられました。ngixやpuma、RDSなど接続しなくてはいけないものが多々あり、また、AWS内にコンテナを構築することにより今、自分がどこにいるのか、よくわからなくなる状態に陥ることがありました。
この記事通りに、行ってもうまくいかないかもしれませんが、少しでもどなたかのお力になれればと思います。
自分はできれば、再びあのような思いをしたく無いので忘れないうちに記事として残しておきました。作成したAWSインスタンスにローカルdockerコンテナをアップロードしていきます。
コンテナ内での環境変数を設定します。
現状、database.ymlを確認すると
database.ymlusername: root password: password host: dbこのように、セキュアな情報がハードコーディングされています。
このままではgithubのコードから漏洩する危険があるので、本番環境のコンテナ内で環境変数を用いてセキュアな情報を設定します。環境変数については、参考までに下記をご覧下さい。
環境変数について環境変数を利用するために、dotenv-railsというgemをインストールします。
Gemfileに以下を追記します。Gemfile.gem 'dotenv-rails'dotenv-railsをインストールすることにより、「.env」ファイルに記載された環境変数をdockerコンテナ内で、下記のような記述で取り出せる様になります。
ENV['DATABASE_PASSWORD']また、.envファイルをgithubに上げてしまうと元も子も無いので、gitignoreに追記します。
.env.envを下記の様に記載してアプリ直下に配置します。
DB_USERNAME=root DB_PASSWORD=gakjadfmoaeur DB_HOST=fito2-db-instance.〇〇〇〇〇〇.ap-northeast-1.rds.amazonaws.com DB_DATABASE=fitO2_dbDB_HOSTはRDSのエンドポイントです。
AWSのRDSダッシュボードのデーターベースをクリックし、一覧から該当のRDSを選択すると確認できます。database.ymlの修正
database.ymlに下記を追加して、本番環境は環境変数から値を読み込むようにします。
database.ymlproduction: <<: *default database: <%= ENV['DB_DATABASE'] %> adapter: mysql2 encoding: utf8mb4 charset: utf8mb4 collation: utf8mb4_general_ci host: <%= ENV['DB_HOST'] %> username: <%= ENV['DB_USERNAME'] %> password: <%= ENV['DB_PASSWORD'] %>nginx.confの修正
以下の部分を本番用に修正します。
nginx.confserver { listen 80; # =========ローカルと本番切り替え=========== server_name 固定IP; # server_name localhost; # ======================================docker-compose.ymlの修正
docker-compose.ymlversion: '3' services: app: build: context: . # =========ローカルと本番切り替え=========== command: bundle exec puma -C config/puma.rb -e production # command: bundle exec puma -C config/puma.rb # ====================================== volumes: - .:/fitO2 - public-data:/fitO2/public - tmp-data:/fitO2/tmp - log-data:/fitO2/log networks: - fitO2-network # =========ローカルと本番切り替え=========== # depends_on: # - db # db: # image: mysql:5.7 # environment: # MYSQL_ROOT_PASSWORD: password # MYSQL_USER: user # MYSQL_PASSWORD: password # MYSQL_DATABASE: fitO2_development # volumes: # - db-data:/var/lib/mysql # networks: # - fitO2-network # ====================================== web: build: context: ./nginx_docker volumes: - public-data:/fitO2/public - tmp-data:/fitO2/tmp ports: - 80:80 depends_on: - app networks: - fitO2-network volumes: public-data: tmp-data: log-data: db-data: networks: fitO2-network: external: true変更点
・dbコンテナは本番環境ではRDSを使用するので不要のため、コメントアウト
(appコンテナのdepend onもまとめてコメントアウトします)
・command のrails s に -e production を追記して、本番環境でサーバー立ち上げるようにした。AWSインスタンス上にdockerコンテナを構築する。
今一度、AWSインスタンス上にdockerコンテナを構築するまでの流れを整理します。
今、現状ローカルでは、下記のようにfitO2というファイルを元に、下記の様なdockerコンテナをbuildできる状態でした。
そして、fitO2というファイルを書き換えて、以下の様なコンテナが作成されるように修正しました。(DBコンテナ削除)
その、fitO2をgithubにpushします。そして、AWS側からclone(2回目以降はpull)します。
cloneしたfitO2を元に、AWS内でbuildしてコンテナを構築し、AWS内に作成しているRDSと接続します。
通信の流れはオレンジの矢印となります。
githubへプッシュ
まずは、修正したファイルをコミットしてgithubへpushします。
AWSにdockerをインストール
ssh接続でAWSにログインし、dockerをインストールします。
sudo yum install -y docker //インストール sudo service docker start //docker起動 sudo usermod -G docker ec2-user //ec2-userに権限付与 exit //ログアウト //再度sshでログイン docker info下記の様な表示がされたらオッケーです。
Client: Debug Mode: false Server: Containers: 0 Running: 0 Paused: 0 Stopped: 0 Images: 0 Server Version: 19.03.13-cesudo chkconfig docker on //EC2起動時にDockerを自動で立ち上げるdocker-composeをインストールします。
sudo curl -L "https://github.com/docker/compose/releases/download/1.24.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose docker-compose -v docker-compose version 1.24.0, build 0aa59064 //上記の様にバージョンが表示されたら成功gitをインストールします。
sudo yum install -y git秘密鍵を作成します。(質問は全てエンター)
ssh-keygen -t rsa -b 4096作成した秘密鍵を表示し、コピーします。
cat ~/.ssh/id_rsa.pubhttps://github.com/settings/keys
こちらにアクセスします。titleを適宜入力し、keyのところに先ほどコピーした文字列を貼り付けます。
(ssh-rsa~から含めます)ssh -T git@github.com上記を打ち込んで、途中yesと入力し、下記の様に表示されればAWSとgithubの認証が成立しました。
Hi yourname! You've successfully authenticated, but GitHub does not provide shell access.以後、AWSインスタンス側から自身のgithubに対し、pull等ができる様になります。
githubからcloneします。(URLはリポジトリを表示したときのURL)
cd / //ルート直下に移動します。homeディレクトリでコンテナを展開すると、pumaとnginxの連携でエラーが出る場合がありますl。puma.sockの読み取りエラーsudo git clone https://github.com/〇〇〇〇〇〇/〇〇〇〇〇〇ls //lsと打って、ディレクトリがあるか確認する。今、gitignoreに記載したファイル(.env master.key)は含まれていません。そこで、ssh通信を用いてローカルからAWSに直接ファイルを転送します。
exit //一旦ログアウトして、ローカルのfitO2ファイルに移動 sudo scp -i ~/.ssh/fitO2_key.pem .env ec2-user@固定IP:/home/ec2-user/ sudo scp -i ~/.ssh/fitO2_key.pem config/master.key ec2user@固定IP:/home/ec2-user //scpコマンドを用いて、AWSに.envを転送します。 .env のように転送したファイルが表示されたらオッケー。 //権限の関係で一旦、ホームディレクトリに転送します。再度、ログイン。
cd ls -aホームディレクトリに移動して.envとmaster.keyが存在していたら問題ない。
.envとmaster.keyを移動させる。sudo mv .env /fitO2 sudo mv master.key /fitO2/config念のため移動してるか確認
ls -a /fitO2/ ls -a /fitO2/configコンテナの起動
cd /fitO2 docker-compose build //コンテナを作成します。 (Permition deniedになった場合は、sudo chmod 777 /usr/local/bin/docker-compose を実行します。) docker network create fitO2-network //ネットワークを作成します。 docker-compose run app rails assets:precompile RAILS_ENV=production //プリコンパイルを実施 docker-compose up //コンテナを起動します。下記のように表示されていれば問題なく起動しています。
Creating fito2_app_1 ... done Creating fito2_web_1 ... done Attaching to fito2_app_1, fito2_web_1 app_1 | Puma starting in single mode... app_1 | * Version 3.12.6 (ruby 2.5.1-p57), codename: Llamas in Pajamas app_1 | * Min threads: 5, max threads: 5 app_1 | * Environment: production app_1 | * Listening on tcp://0.0.0.0:3000 app_1 | * Listening on unix:///fitO2/tmp/sockets/puma.sock app_1 | Use Ctrl-C to stop別タブを開いて、AWSにログインします。
データベースの作成
docker-compose exec app rails db:create db:migrate RAILS_ENV=production docker-compose exec app rails db:seed RAILS_ENV=production //(必要に応じて)以上で、http://固定IPにアクセスした場合、正しく表示されるはずです。
RDSのデーターベース確認方法
dockerコンテナにログインし、mysqlを起動させます。
docker ps //コンテナIDを調べます。NAMESがfito2_app_1の方のCONTAINER IDをコピーします。
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c5ec64f0ea76 fito2_web "/bin/sh -c '/usr/sb…" 5 minutes ago Up 5 minutes 0.0.0.0:80->80/tcp fito2_web_1 442b9ddb3a20 fito2_app "bundle exec puma -C…" 5 minutes ago Up 5 minutes fito2_app_1コンテナにログインします
docker exec -it 442b9ddb3a20 bashmysqlを起動させます。
service mysql startmysql -u root -h RDSのエンドポイント -p //パスワードを入力してログインセキュリティーグループで制限んしているので、作成したEC2コンテナからしかアクセスできません。
ローカルから試してみてください。
以上となります。
参考
EC2上でRailsアプリケーションにDockerを導入する(Rails、Nginx、RDS)
開発環境において既存のRailsアプリにDockerを導入する方法(Rails、nginx、mysql)
無料!かつ最短?で Ruby on Rails on Docker on AWS のアプリを公開するぞ。
【画像付きで丁寧に解説】AWS(EC2)にRailsアプリをイチから上げる方法【その1〜ネットワーク,RDS環境設定編〜】
Nginx + Rails (Puma) on Docker のいくつかの実用パターン
Docker + Rails + Puma + Nginx + MySQL
- 投稿日:2021-01-12T00:11:46+09:00
【Rails AWS Docker】既存Ruby on Rails + MySQLアプリをDockerで構築し、AWSにデプロイする(5)
ポートフォリをとして作ったRuby on RailsアプリをDockerコンテナ化し本番環境をAWSで構築するまでの道のりです。
ポートフォリオ自体はこちらとなります。
【ポートフォリオ】転職活動時に作成したポートフォリオの概要(テッ◯キャンプ)かなり苦しめられたので、どなたかのお役に立てれば。
タイトル 1 ローカル環境のRailsアプリをDockerコンテナ化 2 AWSにVPCを作成する。パブリックサブネットを作成する 3 プライベートサブネットを作成する 4 EC2インスタンスを作成する 5 RDSを作成する 6 DockerコンテナをAWSにアップロードする RDSを作成します。
既存Ruby on Rails + MySQLアプリをDockerで構築し、AWSにデプロイする(1)においてデーターベースコンテナを作成しました。
実はプライベートサブネット内にEC2インスタンスを配置して、その中にデーターベースコンテナを配置してもいいのですが、AWSにはRDSというサービスがあります。
ざっくりいうと、RDSとはデーターベース用のインスタンスで、自動的に可用性や耐障害性を高めた構成にしてくれます。また、異なるアベイラビリティーゾーンにバックアップ用のデーターベースを配置することにより、災害等により一箇所のデーターベースで障害が生じた際にも、問題なく稼働できる様になっています。プライベートサブネットを二つ作った理由はこれです。
今回は、このRDSを用いてデーターベースインスタンスを作成します。
サブネットグループの作成
まずは、プライベートサブネット2つをまとめた、サブネットグループを作成します。
RDSダッシュボードに入り、サブネットグループを選択し、「DBサブネットグループを作成」をクリックします。
サブネットに先ほど、作成した二つのプライベートサブネットを追加します。
今、下記のような異なるアベイラビリティーゾーンを持つサブネットグループが作成されました。
パラメーターグループの設定
RDSでは直接データベースの設定を触れないので、パラメーターグループで設定します。
パラメーターグループファミリーは、開発環境のバージョンに合わせます。
オプショングループの設定
RDSダッシュボードに入り、オブショングループを選択し、「グループを作成」をクリックします。
開発環境に合わせてエンジンとメジャーエンジンバージョンを設定します。
RDSを作成する。
RDSダッシュボードに入り、データベースを選択し、「データーベースの作成」をクリックします。
下記は設定例です。ご自身の運用に合わせて設定してください。「データーベースの作成」クリック
少し分かりずらいですが、下記の様にRDSがサブネットグループとdb用セキュリティーグループと結びつけることにより、
結果として下記の構成となります。
これでRDSインスタンスが作成できました。
次回(6)へ続く
DockerコンテナをAWSにアップロードする
- 投稿日:2021-01-12T00:11:46+09:00
【Rails】既存Ruby on Rails + MySQLアプリをDockerで構築し、AWSにデプロイする(5)
ポートフォリをとして作ったRuby on RailsアプリをDockerコンテナ化し本番環境をAWSで構築するまでの道のりです。
ポートフォリオ自体はこちらとなります。
【ポートフォリオ】転職活動時に作成したポートフォリオの概要(テッ◯キャンプ)かなり苦しめられたので、どなたかのお役に立てれば。
タイトル 1 ローカル環境のRailsアプリをDockerコンテナ化 2 AWSにVPCを作成する。パブリックサブネットを作成する 3 プライベートサブネットを作成する 4 EC2インスタンスを作成する 5 RDSを作成する 6 DockerコンテナをAWSにアップロードする RDSを作成します。
既存Ruby on Rails + MySQLアプリをDockerで構築し、AWSにデプロイする(1)においてデーターベースコンテナを作成しました。
実はプライベートサブネット内にEC2インスタンスを配置して、その中にデーターベースコンテナを配置してもいいのですが、AWSにはRDSというサービスがあります。
ざっくりいうと、RDSとはデーターベース用のインスタンスで、自動的に可用性や耐障害性を高めた構成にしてくれます。また、異なるアベイラビリティーゾーンにバックアップ用のデーターベースを配置することにより、災害等により一箇所のデーターベースで障害が生じた際にも、問題なく稼働できる様になっています。プライベートサブネットを二つ作った理由はこれです。
今回は、このRDSを用いてデーターベースインスタンスを作成します。
サブネットグループの作成
まずは、プライベートサブネット2つをまとめた、サブネットグループを作成します。
RDSダッシュボードに入り、サブネットグループを選択し、「DBサブネットグループを作成」をクリックします。
サブネットに先ほど、作成した二つのプライベートサブネットを追加します。
今、下記のような異なるアベイラビリティーゾーンを持つサブネットグループが作成されました。
パラメーターグループの設定
RDSでは直接データベースの設定を触れないので、パラメーターグループで設定します。
パラメーターグループファミリーは、開発環境のバージョンに合わせます。
オプショングループの設定
RDSダッシュボードに入り、オブショングループを選択し、「グループを作成」をクリックします。
開発環境に合わせてエンジンとメジャーエンジンバージョンを設定します。
RDSを作成する。
RDSダッシュボードに入り、データベースを選択し、「データーベースの作成」をクリックします。
下記は設定例です。ご自身の運用に合わせて設定してください。「データーベースの作成」クリック
少し分かりずらいですが、下記の様にRDSがサブネットグループとdb用セキュリティーグループと結びつけることにより、
結果として下記の構成となります。
これでRDSインスタンスが作成できました。
次回(6)へ続く
DockerコンテナをAWSにアップロードする
- 投稿日:2021-01-12T00:11:19+09:00
【Rails AWS Docker】既存Ruby on Rails + MySQLアプリをDockerで構築し、AWSにデプロイする(4)
ポートフォリをとして作ったRuby on RailsアプリをDockerコンテナ化し本番環境をAWSで構築するまでの道のりです。
ポートフォリオ自体はこちらとなります。
【ポートフォリオ】転職活動時に作成したポートフォリオの概要(テッ◯キャンプ)かなり苦しめられたので、どなたかのお役に立てれば。
タイトル 1 ローカル環境のRailsアプリをDockerコンテナ化 2 AWSにVPCを作成する。パブリックサブネットを作成する 3 プライベートサブネットを作成する 4 EC2インスタンスを作成する 5 RDSを作成する 6 DockerコンテナをAWSにアップロードする EC2インスタンスを作成する
EC2とは
Elastic Compute Cloudと呼ばれるもので、ざっくりというと仮想的なパソコンです。
それを、AWS上に置くことによって、クラウド上にシステムを構築します。作成したEC2インスタンスは、パブリックサブネットに配置して、アプリ本体を置きます。
EC2インスタンスの作成
今回はインスタンスタイプにクイックスタートの「AMAZON Linux2」を利用します。
(ざっくり)どのタイプのコンピューターにするかということです。今回はOSがlinuxのものを選択します。タイプは無料利用枠のt2.microを選択します。
(ざっくり)どの程度のスペックにするかとうことです。→「次のステッップ:インスタンスの詳細設定」をクリックします。
項目 内容 説明(ざっくり) インスタンス数 1 起動するインスタンスの数 購入のオプション チェックなし スポットインスタンスを選択すると安価に利用できる(常時起動しない場合) ネットワーク fitO2_vpc 先ほど作成したVPCに配置する。 サブネット fitO2_public_subnet_1a 先ほど作成したパブリックサブネットに配置する。 自動割り当てパブリック IP サブネット設定を使用(無効) 後ほど固定IPを割り振るため 配置グループ チェックなし 複数のインスタンス間の通信を高速化する設定 キャパシティーの予約 なし リソースの上限を超えた時にインスタンスが起動できなくなることを回避(有料) IAM ロール なし AWSのリソースに紐付けることができる権限設定を行うサービス CPU オプション なし CPUの性能に対するオプション シャットダウン動作 停止 シャットダウン時の動作 停止 - 休止動作 なし 停止動作に休止動作を追加する 終了保護の有効化 なし 誤った終了を防止します モニタリング なし 5分間隔の監視を1分感覚にする。 テナンシー 共有 ハードディスクを占有するか否か Elastic Inference なし 機械学習に効率化 クレジット仕様 なし 規定量の通信量が来た際に制限がなくなる ネットワークインターフェイス
プライマリIP 10.0.10.10 サブネットにプライベートIPアドレスを設定する。 「次のステップ:ストレージの追加」をクリック
項目 内容 説明(ざっくり) サイズ 8 ボリュームタイプ 汎用SSD 合わせて削除 チェック 暗号化 暗号化なし 「タグの追加」をクリック
項目 内容 説明(ざっくり) name fitO2_web ボリュームタイプ 汎用SSD インスタンス チェック ボリューム チェック 「セキュリティーグループの設定」をクリック
既存のセキュリティーグループを選択する。
先ほど作成した(fitO2_SG)を適用する。「確認と作成」をクリック
「起動」をクリック
キーペアの作成
新しいキーペアの作成(すでにキーペアを作っている場合は既存のものを作っても良い)
キーペア名を設定し、ダウンロード。
(ざっくり)キーペアとは、ssh接続する際に、使用する鍵。ssh接続する際にダウンロードしたキーペアを用いて接続し、AWS側にで生成した鍵と合致した場合接続が許可される。
「インスタンスの作成」
作成されたら、分かりやすいようにインスタンスに名前を設定しておきます。
nameのところをクリックしたら名前が編集できます。ダウンロードしたキーペアを適当な位置に移動させます。(今回は ~/.ssh)
Elastic IP(固定)アドレスを作成する。
現状インスタンスを停止したら、IPアドレスが変わってしまうので、固定IPを割り割り振ります。
EC2ダッシュボードから、Elastic IPを選択します。
「新しいアドレスの割り当て」をクリックします。
ネットワークボーダーグループ : ap-northease-1
パブリック IPv4 アドレスプール : Amazon の IPv4 アドレスプール「割り当て」をクリック。
作成したElastic IPアドレスに分かりやすい様に名前を付けておく。
Elastic IP(固定)アドレスをインスタンスに紐づける。
作成したIPアドレスにチェックを入れてアクションから「アドレスの関連付け」を選択する。
リソース : インスタンス
インスタンス : 作成したインスタンスを選択
プライベートIPアドレス : 10.0.10.10「関連付け」をクリック
ssh接続を試みて確認する。
インスタンスの状態が、runningになっていることを確認後
sudo ssh -i ~/.ssh/fitO2_key.pem ec2-user@固定IPアドレス~/.ssh/fitO2_key.pemは秘密鍵の保管している場所/秘密鍵の名前
固定IPは、インスタンス一覧から選択して、説明タグをクリックし、Elastic IPと表示されているものです。Are you sure you want to continue connecting (yes/no/[fingerprint])? yesと打ってenter__| __|_ ) _| ( / Amazon Linux 2 AMI ___|\___|___| https://aws.amazon.com/amazon-linux-2/上記のように表示されれば接続成功。
図にすると下記の様なイメージで接続しました。
EC2には先ほど作成したセキュリティーグループ(fitO2_SG)が適用されています。
インバウンド(入ってくる方の通信)に対し、ssh接続の場合、22番ポートを使用し、全てのアクセス元(0.0.0.0/0)を許可しているので、ssh接続することが可能だったわけです。
EC2インスタンスを作成し、ssh接続を行うことができました。
80番ポートもhttp通信に対し、開放されているので、今作成したインスタンスは下記のような通信を許可する状態となっています。
これでパブリックサブネットEC2インスタンスに対し、上記のようなセキュリティーグループが設定されました。
次回(5)へ続く
RDSを作成する
- 投稿日:2021-01-12T00:10:53+09:00
【Rails AWS Docker】既存Ruby on Rails + MySQLアプリをDockerで構築し、AWSにデプロイする(3)
ポートフォリをとして作ったRuby on RailsアプリをDockerコンテナ化し本番環境をAWSで構築するまでの道のりです。
ポートフォリオ自体はこちらとなります。
【ポートフォリオ】転職活動時に作成したポートフォリオの概要(テッ◯キャンプ)かなり苦しめられたので、どなたかのお役に立てれば。
タイトル 1 ローカル環境のRailsアプリをDockerコンテナ化 2 AWSにVPCを作成する。パブリックサブネットを作成する 3 プライベートサブネットを作成する 4 EC2インスタンスを作成する 5 RDSを作成する 6 DockerコンテナをAWSにアップロードする プライベートサブネットを作成します。
実は後ほど、理由は説明するのですがプライベートサブネットは異なるアベイラビリティーゾーンで2つ作る必要がありあります。
アベイラビリティーゾーンとは、ざっくりいうとクラウドが保管されているサーバーが実際に置かれている地域です。よって下記のような構成を作ります。
一つ目のプライベートサブネット作成します。
AWSコンソールからVPCダッシュボードに入り、サブネットを選択してサブネットを作成する。
VPC IDに先ほど作成したVPCを選択する。
アベイラビリティーゾーン:今回はap-northease-1a
名前 : fitO2_private_subnet_1a
IPv4 CIDR ブロック : 10.0.20.0/24
「サブネットを作成」をクリック
二つ目のプライベートサブネット作成します。
AWSコンソールからVPCダッシュボードに入り、サブネットを選択してサブネットを作成する。
VPC IDに先ほど作成したVPCを選択する。
アベイラビリティーゾーン:今回はap-northease-1c
名前 : fitO2_private_subnet_1c
IPv4 CIDR ブロック : 10.0.21.0/24
「サブネットを作成」をクリック
プライベートサブネット用のセキュリティーグループを作成する。
EC2ダッシュボードのセキュリティーグループをクリックして、「セキュリティーグループの作成」をクリックする。
「ルールの追加」をクリックします。
セキュリティーグループ名 : fitO2_db_SG
VPC : 先ほど作成したVPC
インバウンド :
タイプ : MYSQL/Aurora
ポート : 3306
ソース :
カスタム
パブリックサブネットに置かれたEC2インスタンスに適用する予定の(先ほど作った)セキュリティーグループを指定。(名前を打ち込んだら出てくる。出てこなければグループIDをコピペ)これで、プライベートサブネット2つと、それに適用させる予定の下記の様なセキュリティーグループの作成が完了しました。
次回(4)へ続く
EC2インスタンスを作成する |
- 投稿日:2021-01-12T00:10:14+09:00
【Rails AWS Docker】既存Ruby on Rails + MySQLアプリをDockerで構築し、AWSにデプロイする(2)
ポートフォリをとして作ったRuby on RailsアプリをDockerコンテナ化し本番環境をAWSで構築するまでの道のりです。
ポートフォリオ自体はこちらとなります。
【ポートフォリオ】転職活動時に作成したポートフォリオの概要(テッ◯キャンプ)かなり苦しめられたので、どなたかのお役に立てれば。
タイトル 1 ローカル環境のRailsアプリをDockerコンテナ化 2 [AWSにVPCを作成する。パブリックサブネットを作成する] 3 プライベートサブネットを作成する 4 EC2インスタンスを作成する 5 RDSを作成する 6 DockerコンテナをAWSにアップロードする AWSにVPCを作成する。
VPCとは(ざっくり)
Virtual Private Cloud と呼ばれるものでAWS内に作成する仮想的なネットワーク網のことです。
まずは下記の様な構成のVPCとサブベットを作成します。
サブネットとは、VPC内でさらに区分されたネットワークのことです。
パブリックサブネットにアプリ本体。プライベートサブネットにデーターベースを置きます。
パブリックサブネットは、外部からのアクセスを許可する設定します。
プライベートサブネットは、外部からのアクセスを許可せず、パブリックサブネットからのアクセスのみを許可します。(データーベースは外部からアクセスする必要はないのでセキュリティー向上のため)なお、「パブリックサブネット」「プライベートサブネット」という設定自体はなく、後ほど設定するセキュリティーグループにおいて、上記のようなネットワークのアクセス制限を設定していきます。
vpcのプライベートIPアドレスは、サイダー表記が16ビットなので、先頭から16ビット分つまり、10.0が、ネットワーク部となります。
パブリックサブネット、プライベートサブネット共にプライベートアドレスは10.0.から始まっているので、VPC内のネットワークにあります。
また、パブリックサブネットのサイダー表記は/24なので24ビット分、つまり10.0.10.までがネットワーク部。
プライベートサブネットのサイダー表記も/24なので24ビット分、つまり10.0.20.までがネットワーク部であり、
パブリックサブネットとプライベートサブネットは異なるネットワーク空間となります。VPCの作成
AWSにログインして、VPCダッシュボードに入り、VPCを作成する。
名前 : VPCの名前任意
IPv4 CIDR ブロック : VPC用のプライベートIPアドレス(今回は10.0.0.0/16)
「VPCを作成」をクリック
パブリックサブネット作成
AWSコンソールからVPCにVPCに入り、サブネットを選択してサブネットを作成する。
VPC IDに先ほど作成したVPCを選択する。
アベイラビリティーゾーン:今回はap-northease-1a
名前:fitO2_public_subnet_1a
IPv4 CIDR ブロック : 10.0.10.0/24
「サブネットを作成」をクリック
パブリックサブネットのルーティングの作成
インターネットゲートウェイ(IGW)を作成し、VPCにアタッチします。
IGWとは、ざっくりいうとVPCとインタネットを繋ぐ窓口のようなものです。IGWを通じて、インターネットとVPC通信を行います。アタッチとは、作成したIGWをVPCと紐づける作業となります。
VPCコンソールから、「インタネットゲートウェイ」を選択、「インターネットゲートウェイの作成」をクリック。
名前を決めて、作成。一覧から作成したIGWを選択して、右上のアクションからVPCに「アタッチをクリック」
先ほど作成したVPCを選択して、「インターネットゲートウェイのアタッチ」をクリック
ルートテーブルを作成して、パブリックサブネットに紐付け
パブリックサブネット用のルーティングテーブルを作成します。
パブリックサブネットに来たアクセスのうち
10.0.0.0/16 が宛先のものはVPCに送ります。
10.0.10.0/24 が宛先のものはパブリックサブネット(自分自身)に送ります。
0.0.0.0/0 (上記以外全ての宛先)は、IGWに送ります。VPCコンソールから、「ルートテーブル」を選択し、「ルートテーブルの作成」をクリックして、名前を決めてVPCに先ほど作成したVPCを選択します。
一覧から作成した、ルーティングを選択し、下部の「ルート」タブを確認すると、
送信先「10.0.0.0/16」のものが宛先(ターゲット)がVPC(local)となっていることが確認できます。
ルートテーブルは、必ず所属するVPCが必須であるためため、先ほど選択したVPCが紐付けられます。「サブネットの関連付け」タブをクリックし、「サブネットの関連付け編集」をクリックします。
パブリックサブネットを選択し、保存をクリックします。
IGWへのルートを作成する。
「ルートの追加」を選択して、「0.0.0.0/0」を選択する。
先ほど作成したIGWを選択する。「ルートの保存」をクリックする。
これで、パブリックサブネットに紐づくルーティングテーブルが作成されました。
作り方をまとめると、下記の様になります。
それぞれ作り方が異なるのでややこしいですが、やっていることは、宛先IPアドレスに対して、どこに通信を振り分けるかということです。
パブリックサブネット用のセキュリティーグループを作成する。
EC2ダッシュボードのセキュリティーグループをクリックして、「セキュリティーグループの作成」をクリックする。
「ルールの追加」をクリックします。
セキュリティーグループ名 : fitO2_SG
VPC: 先ほど作成したVPC
インバウンド:
上記図の様に作成これで、全てのアクセス元に対して、SSH通信(22番ポート)とhttp通信(80番ポート)を開放するセキュリティーグループが作成できました。後ほど、作るEC2インスタンスに、このセキュリティーグループを適用させる予定です。
(セキュリティーグループは後ほど、もうちょっと詳しく説明します。)次回(3)へ続く
プライベートサブネットを作成する
- 投稿日:2021-01-12T00:09:41+09:00
【Rails AWS Docker】既存Ruby on Rails + MySQLアプリをDockerで構築し、AWSにデプロイする(1)
ポートフォリをとして作ったRuby on RailsアプリをDockerコンテナ化し本番環境をAWSで構築するまでの道のりです。
ポートフォリオ自体はこちらとなります。
【ポートフォリオ】転職活動時に作成したポートフォリオの概要(テッ◯キャンプ)かなり苦しめられたので、どなたかのお役に立てれば。
タイトル 1 ローカル環境のRailsアプリをDockerコンテナ化 参考にさせていただいた記事は、(6)の末尾い記載しています。
ローカル環境のRailsアプリをDockerコンテナ化
Dockerコンテナ環境構成(ローカル版)
構成は上記です。
webサーバーとしてnginxを配置します。
appサーバーはpumaを設置します。まず既存のRailsアプリをコンテナ化します。
前提
AWSにアカウント作成済
docker hubにアカウント作成済
docker インストール済
ローカル環境で動作するRailsアプリ構築
※fitO2の部分は、ご自身のアプリ名に変更してください。
現状のアプリのフォルダ構成に、下記のファイルを追加します。
docker-compose.yml Dockerfile nginx_docker ├── Dockerfile └── nginx.conf config └── puma.rbdocker-compose.ymlversion: '3' services: app: build: context: . command: bundle exec puma -C config/puma.rb volumes: - .:/fitO2 - public-data:/fitO2/public - tmp-data:/fitO2/tmp - log-data:/fitO2/log networks: - fitO2-network depends_on: - db db: image: mysql:5.7 environment: MYSQL_ROOT_PASSWORD: password MYSQL_USER: user MYSQL_PASSWORD: password MYSQL_DATABASE: fitO2_development volumes: - db-data:/var/lib/mysql networks: - fitO2-network web: build: context: ./nginx_docker volumes: - public-data:/fitO2/public - tmp-data:/fitO2/tmp ports: - 80:80 depends_on: - app networks: - fitO2-network volumes: public-data: tmp-data: log-data: db-data: networks: fitO2-network: external: true簡単な説明
dbコンテナ
image でdockerhubからmysql:5.7をプルします。
ports でホスト側の3306とコンテナ側の3306ポートを接続します。
networks でappコンテナ側と共通のネットワークfitO2-networkを利用します。appコンテナ
build でDockerfileのディレクトリ(コンテキスト)を指定して、Dockerfileからコンテナを作成します。
volumes で、ホスト側のdocker-compose.ymlが存在しているディレクトリと、コンテナ側の/fitO2をマウント(共通化)しています。
command で設定ファイルを指定してpuma(アプリケーションサーバー)を立ち上げています。
ports でホスト側の3000とコンテナ側の3000ポートを接続します。
depends_on でappコンテナが生成されてから、実行されるように指定しています。
networks でdbコンテナ側と共通のネットワークfitO2-networkを利用します。webコンテナ
build で./nginx_dockerがあるディレクトリ(コンテキスト)を指定して、Dockerfileからコンテナを作成します。
depends_on でappコンテナが生成されてから、実行されるように指定しています。networks でfitO2-networkを設定しています。
fitO2/Dockerfile.FROM ruby:2.5.1 RUN apt-get update -qq && \ apt-get install -y build-essential \ nodejs\ mysql-server\ mysql-client WORKDIR /fitO2 COPY Gemfile /fitO2/Gemfile COPY Gemfile.lock /fitO2/Gemfile.lock RUN gem install bundler RUN bundle install RUN mkdir -p tmp/sockets簡単な説明
FROM でruby:2.5.1 イメージをdocker hubからインストールします。
1回目のRUN で、必要なパッケージをインストールしています。
WORKDIR で作業ディレクトリを/fitO2に設定しています。
COPYで ホスト側のgemfileとgemfile.lockをコンテナの/fitOディレクトリにコピーしています。
2回目のRUN でbundlerをインストールします。
3回目のRUN でgemfileからパッケージをインストールします。
4回目のRUN ソケットファイルを作成しています。fitO2/nginx_docker/Dockerfile.FROM nginx:1.15.8 RUN rm -f /etc/nginx/conf.d/* ADD nginx.conf /etc/nginx/conf.d/fitO2.conf # ビルド完了後にNginxを起動 CMD /usr/sbin/nginx -g 'daemon off;' -c /etc/nginx/nginx.conf簡単な説明
FROM でnginx:1.15.8 イメージをdocker hubからインストールします。
RUN でインクルード用のディレクトリ内を削除してます。
ADD でNginxの設定ファイルをコンテナにコピーしてます。
CMD でビルド完了後にNginxを起動するようにしてます。fitO2/nginx_docker/nginx.confupstream fitO2 { server unix:///fitO2/tmp/sockets/puma.sock; } server { listen 80; # =========ローカルと本番切り替え=========== # server_name ◯◯◯.◯◯◯.◯◯◯.◯◯◯; server_name localhost; # ====================================== access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; root /fitO2/public; client_max_body_size 100m; error_page 404 /404.html; error_page 505 502 503 504 /500.html; try_files $uri/index.html $uri @fitO2; keepalive_timeout 5; location @fitO2 { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_pass http://fitO2; } }nginxの設定ファイルです。
ローカル環境の場合は、server_name をlocalhostにします。config/puma.rbthreads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }.to_i threads threads_count, threads_count port ENV.fetch("PORT") { 3000 } environment ENV.fetch("RAILS_ENV") { "development" } plugin :tmp_restart app_root = File.expand_path("../..", __FILE__) bind "unix://#{app_root}/tmp/sockets/puma.sock" stdout_redirect "#{app_root}/log/puma.stdout.log", "#{app_root}/log/puma.stderr.log", truepumaの設定ファイルです。
bind "unix://#{app_root}/tmp/sockets/puma.sock"の部分は、nginx.confのserverと一致するようにしなければなりません。参考
config/database.ymldefault: &default adapter: mysql2 encoding: utf8 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> # PasswordとUsernameはdocker-compose.ymlと合わせます username: root password: password host: db development: <<: *default database: fitO2_development test: <<: *default database: fitO2_testコンテナ作成、起動
アプリのディレクトリに移動します。
コンテナを作成します。
docker-compose buildネットワークを作成します。
docker network create fitO2-networkコンテナを起動します。
docker-compose up初回はデーターベースの初期化を行います。
ターミナルを別タブで開き、アプリ直下に移動して下記コマンドをうちます。docker-compose exec app rails db:create docker-compose exec app rails db:migrate docker-compose exec app rails db:seed (シーダーがなければ不要)うまくいかなかった場合、試行錯誤した場合は中途半端にシーダーが入ってしまって、バリデーションの関係で弾かれる場合があるので、一度下記の様にデーターベースを削除してから再度上記コマンドを実行してください。
docker-compose exec app rails db:dropにアクセスすると、サイトにアクセスすることができます。
エラーがー生じた際は、docker-compose upターミナルにログが出ていますので、確認してください。
とりあえず既存のアプリをDockerコンテナ化できました。
次回(2)へ続く
[AWSにVPCを作成する。パブリックサブネットを作成する。]
- 投稿日:2021-01-12T00:09:41+09:00
【Rails AWS Docker】既存Ruby on Rails + MySQLアプリをDockerで構築し、AWSにデプロイする(1)
ポートフォリをとして作ったRuby on RailsアプリをDockerコンテナ化し本番環境をAWSで構築するまでの道のりです。
ポートフォリオ自体はこちらとなります。
【ポートフォリオ】転職活動時に作成したポートフォリオの概要(テッ◯キャンプ)かなり苦しめられたので、どなたかのお役に立てれば。
タイトル 1 ローカル環境のRailsアプリをDockerコンテナ化 2 AWSにVPCを作成する。パブリックサブネットを作成する 3 プライベートサブネットを作成する 4 EC2インスタンスを作成する 5 RDSを作成する 6 DockerコンテナをAWSにアップロードする 参考にさせていただいた記事は、(6)の末尾に記載しています。
ローカル環境のRailsアプリをDockerコンテナ化
Dockerコンテナ環境構成(ローカル版)
構成は上記です。
webサーバーとしてnginxを配置します。
appサーバーはpumaを設置します。まず既存のRailsアプリをコンテナ化します。
前提
AWSにアカウント作成済
docker hubにアカウント作成済
docker インストール済
ローカル環境で動作するRailsアプリ構築
※fitO2の部分は、ご自身のアプリ名に変更してください。
現状のアプリのフォルダ構成に、下記のファイルを追加します。
docker-compose.yml Dockerfile nginx_docker ├── Dockerfile └── nginx.conf config └── puma.rbdocker-compose.ymlversion: '3' services: app: build: context: . command: bundle exec puma -C config/puma.rb volumes: - .:/fitO2 - public-data:/fitO2/public - tmp-data:/fitO2/tmp - log-data:/fitO2/log networks: - fitO2-network depends_on: - db db: image: mysql:5.7 environment: MYSQL_ROOT_PASSWORD: password MYSQL_USER: user MYSQL_PASSWORD: password MYSQL_DATABASE: fitO2_development volumes: - db-data:/var/lib/mysql networks: - fitO2-network web: build: context: ./nginx_docker volumes: - public-data:/fitO2/public - tmp-data:/fitO2/tmp ports: - 80:80 depends_on: - app networks: - fitO2-network volumes: public-data: tmp-data: log-data: db-data: networks: fitO2-network: external: true簡単な説明
dbコンテナ
image でdockerhubからmysql:5.7をプルします。
ports でホスト側の3306とコンテナ側の3306ポートを接続します。
networks でappコンテナ側と共通のネットワークfitO2-networkを利用します。appコンテナ
build でDockerfileのディレクトリ(コンテキスト)を指定して、Dockerfileからコンテナを作成します。
volumes で、ホスト側のdocker-compose.ymlが存在しているディレクトリと、コンテナ側の/fitO2をマウント(共通化)しています。
command で設定ファイルを指定してpuma(アプリケーションサーバー)を立ち上げています。
ports でホスト側の3000とコンテナ側の3000ポートを接続します。
depends_on でappコンテナが生成されてから、実行されるように指定しています。
networks でdbコンテナ側と共通のネットワークfitO2-networkを利用します。webコンテナ
build で./nginx_dockerがあるディレクトリ(コンテキスト)を指定して、Dockerfileからコンテナを作成します。
depends_on でappコンテナが生成されてから、実行されるように指定しています。networks でfitO2-networkを設定しています。
fitO2/Dockerfile.FROM ruby:2.5.1 RUN apt-get update -qq && \ apt-get install -y build-essential \ nodejs\ mysql-server\ mysql-client WORKDIR /fitO2 COPY Gemfile /fitO2/Gemfile COPY Gemfile.lock /fitO2/Gemfile.lock RUN gem install bundler RUN bundle install RUN mkdir -p tmp/sockets簡単な説明
FROM でruby:2.5.1 イメージをdocker hubからインストールします。
1回目のRUN で、必要なパッケージをインストールしています。
WORKDIR で作業ディレクトリを/fitO2に設定しています。
COPYで ホスト側のgemfileとgemfile.lockをコンテナの/fitOディレクトリにコピーしています。
2回目のRUN でbundlerをインストールします。
3回目のRUN でgemfileからパッケージをインストールします。
4回目のRUN ソケットファイルを作成しています。fitO2/nginx_docker/Dockerfile.FROM nginx:1.15.8 RUN rm -f /etc/nginx/conf.d/* ADD nginx.conf /etc/nginx/conf.d/fitO2.conf # ビルド完了後にNginxを起動 CMD /usr/sbin/nginx -g 'daemon off;' -c /etc/nginx/nginx.conf簡単な説明
FROM でnginx:1.15.8 イメージをdocker hubからインストールします。
RUN でインクルード用のディレクトリ内を削除してます。
ADD でNginxの設定ファイルをコンテナにコピーしてます。
CMD でビルド完了後にNginxを起動するようにしてます。fitO2/nginx_docker/nginx.confupstream fitO2 { server unix:///fitO2/tmp/sockets/puma.sock; } server { listen 80; # =========ローカルと本番切り替え=========== # server_name ◯◯◯.◯◯◯.◯◯◯.◯◯◯; server_name localhost; # ====================================== access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; root /fitO2/public; client_max_body_size 100m; error_page 404 /404.html; error_page 505 502 503 504 /500.html; try_files $uri/index.html $uri @fitO2; keepalive_timeout 5; location @fitO2 { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_pass http://fitO2; } }nginxの設定ファイルです。
ローカル環境の場合は、server_name をlocalhostにします。config/puma.rbthreads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }.to_i threads threads_count, threads_count port ENV.fetch("PORT") { 3000 } environment ENV.fetch("RAILS_ENV") { "development" } plugin :tmp_restart app_root = File.expand_path("../..", __FILE__) bind "unix://#{app_root}/tmp/sockets/puma.sock" stdout_redirect "#{app_root}/log/puma.stdout.log", "#{app_root}/log/puma.stderr.log", truepumaの設定ファイルです。
bind "unix://#{app_root}/tmp/sockets/puma.sock"の部分は、nginx.confのserverと一致するようにしなければなりません。参考
config/database.ymldefault: &default adapter: mysql2 encoding: utf8 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> # PasswordとUsernameはdocker-compose.ymlと合わせます username: root password: password host: db development: <<: *default database: fitO2_development test: <<: *default database: fitO2_testコンテナ作成、起動
アプリのディレクトリに移動します。
コンテナを作成します。
docker-compose buildネットワークを作成します。
docker network create fitO2-networkコンテナを起動します。
docker-compose up初回はデーターベースの初期化を行います。
ターミナルを別タブで開き、アプリ直下に移動して下記コマンドをうちます。docker-compose exec app rails db:create docker-compose exec app rails db:migrate docker-compose exec app rails db:seed (シーダーがなければ不要)うまくいかなかった場合、試行錯誤した場合は中途半端にシーダーが入ってしまって、バリデーションの関係で弾かれる場合があるので、一度下記の様にデーターベースを削除してから再度上記コマンドを実行してください。
docker-compose exec app rails db:dropにアクセスすると、サイトにアクセスすることができます。
エラーがー生じた際は、docker-compose upターミナルにログが出ていますので、確認してください。
とりあえず既存のアプリをDockerコンテナ化できました。
次回(2)へ続く
AWSにVPCを作成する。パブリックサブネットを作成する。