20210112のdockerに関する記事は20件です。

TensorFlowを動かすためのJupyterのDocker環境

環境

MacBookPro
OS:Catalina

内容

DockerHubからimageをPull

$ docker pull tensorflow/tensorflow:latest-jupyter

imageからコンテナを起動
ホスト側で8888ポートを使用していたので、私は、8889:8888で行った。

$ docker run -it -p 8889:8888 --name tf_test tensorflow/tensorflow:latest-jupyter

上記実行後、表示されたURLにアクセスしてJupyterのページが表示されていればOK。(8888番ポートを使用していなければ、置き換える)

参考サイト
https://www.tensorflow.org/install/docker?hl=ja

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

Docker上でGrafanaとInfluxDBを接続しようとしたらBad Gatewayが出た

screencapture-localhost-3000-datasources-edit-6-2021-01-12-20_21_50.png

「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:
      - influxdb

volumesはフィジビリする上では好みですが、今回は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に変更する(非推奨)

こちらは、いろいろ設定を弄っているうちに接続できるようになった、という解決策です。
その後の意味合いを理解すると、この①は非推奨で、後述の②を実施すべきですので、参考程度の記載となります。
スクリーンショット 2021-01-12 20.54.22.png
URLを「https://localhost:8086」のまま接続を確立したい場合はAccessを「Server」から「Browser」に変更することで、「Save & Test」後、「Data source is working」となり接続されるようになりました。

ところで、このAccessとは何なんでしょうか?
右にある「Help」を選択すると以下のような記載が表示されます。
スクリーンショット 2021-01-12 20.58.44.png
要約すると、以下のように理解しました。
- 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とします。

screencapture-localhost-3000-datasources-edit-6-2021-01-12-21_13_50.png

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

Nuxt / Laravel(Docker)で作るシンプルなCRUDアプリ

タイトルの通り、フロントはNuxt、バックエンドはLaravelでシンプルなCRUDアプリを制作し、herokuにデプロイしました。それぞれの具体的な解説は別の記事にまとめていきたいと思っています。

制作したアプリケーション

スクリーンショット 2021-01-12 16.19.35.png

NuxtはSSR(ユニバーサル)、API認証にsanctumを使用しています。

機能
バリデーション: コメントを投稿したユーザー(本人)のみ編集と削除ができる
いいね機能: 自分がいいねしたボタンは色が黄色に変化する。2度押すと取り消される。

課題

  • エラーハンドリング
    • 登録フォームでのエラーメッセージもっと作り込む必要がある。 当初はvee-validate(プラグイン)を導入したが、使い勝手が悪かったため現状はシンプルなメッセージで対応している。
    • 前までは動いていたはずなのに、ケアレスミスでいつの間にか動かなくなっている、という状況が発生。 時間のロスなので、テストの重要性を感じた。 それぞれの機能を疎結合にしてテストしやすくしたい。
  • Nuxt
    • 非同期の理解を深め有効に活用したい。
    • 監視プロパティーを活用し、よりインタラクティブな処理を書きたい。
  • AWSにデプロイしたい。

参考

Dockerデプロイ
- git pushでDocker環境をHerokuにデプロイする
- docker + Laravelアプリをherokuにデプロイする
- 【超入門】20分でLaravel開発環境を爆速構築するDockerハンズオン

Nuxt
- Nuxtを使ってPromise, async/awaitのコードを書く
- JavaScriptで一定時間待ってから処理を開始する方法
- Vue + Vue Router + Vuex + Laravelで写真共有アプリを作ろう (16) エラーハンドリング Part.2

Laravel
- Laravel 粘着質なcacheを削除しよう!

Auth
- Nuxt.jsでAuth Moduleを使ってログイン機能を実装する
- 【Laravel + Vue】 Laravel Sanctum を使ってAPI認証を構築してみる
- nuxt.js + auth使用時のFATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory解消法
- 【Nuxt.js】ログイン前後のリダイレクト処理をミドルウェアで実装する








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

【Docker】ローカル(Win, Mac)にサクッとWordpress環境を構築する

Docker DesktopをローカルPCにインストール

https://www.docker.com/products/docker-desktop
お使いの環境(win, mac)に合わせたダウンロードを実行してください。

無事インストールされているか下記コマンドで確認

docker -v

これでローカルマシンにDocker Engineが搭載されました。

で、起動しなければ意味がないのでDockerを起動しておいてください。
おそらくクジラのアイコンがどこかにいれば起動していると思います。
※下記はwindowsのタスクトレイの例
名称未設定-1.png

Dockerでの作業は、あくまでもDocker Engineという仮想環境の中での出来事であるということは、常に念頭に置いてください。

「環境はローカルホスト(PC)に構築されているんじゃない、Dockerホスト(Engine)に構築されているんだ」

Pythonをインストールする

え?python?何か間違ってませんか?って思った方も多いでしょう。
気持ちは分かります。ただその思いはいったん胸にしまいましょう。
一応、簡単に説明しておくと、
この後、Docker操作を補佐するツールもインストールすることになりますが、
それがPython製のツールなのです。
その名も「Docker Comopose」
そいつを簡単にインストールするにはPythonが話が早いってわけですね。
「python3」「python3-pip」をそれぞれインストールします。
https://www.python.org/
※pythonをインストールして使える状態に持っていく方法はここでは割愛しますが、
winの方はmacより若干複雑かもしれない。健闘を祈る。

無事インストールされているか下記コマンドで確認

python3 -V

Docker 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.yml
version: "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です。

起動を確認する

http://localhost:8080/

Wordpressの初期インストール画面が表示されるはずです。
screenshot-localhost_8080-2021.01.12-17_07_57.png

コマンドでコンテナの起動確認

docker-compose ps

起動しているコンテナが表示されているはずです。
※今回は二つ
dd.png

コンテナを停止、破棄する

docker-compose down

最後に

「おいおい、こんな駆け足でいって、伏線の回収もなしかよ!」って声が聞こえてきそうですね。
時間も時間なので、今回はここまでだよ。
ひとまずこの状態でWordpressを設定してみて、いろいろいじってみてほしい。
そうすると様々な問題が出てくるだろう。
そしたらまた会おう。

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

docker-composeで指定するcommandはDockerfileよりも優先される

優先度

docker-composeでは
buildにおいてdockerfileを指定することで、Dockerfileからイメージを生成してコンテナを作成できます。

このとき、このDockerfileでデフォルトで実行されるCMDがあります。

Dockerfile
CMD ["uvicorn", "code.main:app", "--reload", "--host", "0.0.0.0", "--port", "8000"]

このDockerfileがある状態で、docker-compose.ymlのcommandに別のコマンドを書き込んでみます。

docker-compose.yml
version: "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で簡単に動作を変更できることを考えると、自然な動作かなと思いました。

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

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
    

参考

以上。

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

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

AutoMuteUsホスティング手順

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にもポートを記載する。

⑥作成した.envdocker-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のトークンが合っているかなどを確認するとよい。

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

【入門】はじめての 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      204MB

CentOS の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を構築・動作確認をしながら、一連の手順を詳細に記述したつもりです。 もし、記述について誤りがあったり、気になることがあれば、編集リクエストやコメントでフィードバックしていただけると助かります。

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

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

コンテナを再度立ち上げログを確認しつつ数分待ってみる

証明書が取得できました!!!!

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

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/bundleActions/Cache でキャッシュさせる場合に発生した

docker-compose と workflow のyamlは下記のような感じ

docker-compose.yaml
version: '3.7'

services:
  app:
    ...

    volumes:
      - ./:/app:cached
      - /var/cache/bundle:/bundle
.github/workflows/ci.yml
jobs:
  ...
  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.yml
  env:
    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の量などにもよると思う)。

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

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はtls接続でリモート管理しているので、バックアップをローカルに呼び寄せないと面倒なので、今回のようなものを作成しました。ちなみにsshのポートフォワードをしている場合も、リモートバックアップは可能です。ただtlsで直接接続している場合とポートフォワードでは、ポートフォワードの転送速度が数倍遅いので、出来ることならtls設定を入れた方が効率は上がります。

 tls設定に関してはこちらに記事を書いています。
 UbuntuにDockerをインストールし、tlsを使ったリモート接続の設定を行う

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

【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.yml
  username: 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_db

DB_HOSTはRDSのエンドポイントです。
AWSのRDSダッシュボードのデーターベースをクリックし、一覧から該当のRDSを選択すると確認できます。

database.ymlの修正

database.ymlに下記を追加して、本番環境は環境変数から値を読み込むようにします。

database.yml
production:
  <<: *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.conf
server {
  listen 80;
# =========ローカルと本番切り替え===========
  server_name 固定IP;
  # server_name localhost;
# ======================================

docker-compose.ymlの修正

docker-compose.yml
version: '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できる状態でした。
IMG_E6E1E78616D4-1.jpeg

そして、fitO2というファイルを書き換えて、以下の様なコンテナが作成されるように修正しました。(DBコンテナ削除)
IMG_8878B35F0D0C-1.jpeg

その、fitO2をgithubにpushします。そして、AWS側からclone(2回目以降はpull)します。
IMG_5390174B203B-1.jpeg
cloneしたfitO2を元に、AWS内でbuildしてコンテナを構築し、AWS内に作成しているRDSと接続します。
IMG_025BB67DF9F9-1.jpeg

通信の流れはオレンジの矢印となります。

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-ce
sudo 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.pub

https://github.com/settings/keys
こちらにアクセスします。

右上の「new SSH key」をクリックします。
image.png

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 bash

mysqlを起動させます。

service mysql start
mysql -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

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

【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.yml
  username: 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_db

DB_HOSTはRDSのエンドポイントです。
AWSのRDSダッシュボードのデーターベースをクリックし、一覧から該当のRDSを選択すると確認できます。

database.ymlの修正

database.ymlに下記を追加して、本番環境は環境変数から値を読み込むようにします。

database.yml
production:
  <<: *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.conf
server {
  listen 80;
# =========ローカルと本番切り替え===========
  server_name 固定IP;
  # server_name localhost;
# ======================================

docker-compose.ymlの修正

docker-compose.yml
version: '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できる状態でした。
IMG_E6E1E78616D4-1.jpeg

そして、fitO2というファイルを書き換えて、以下の様なコンテナが作成されるように修正しました。(DBコンテナ削除)
IMG_8878B35F0D0C-1.jpeg

その、fitO2をgithubにpushします。そして、AWS側からclone(2回目以降はpull)します。
IMG_5390174B203B-1.jpeg
cloneしたfitO2を元に、AWS内でbuildしてコンテナを構築し、AWS内に作成しているRDSと接続します。
IMG_025BB67DF9F9-1.jpeg

通信の流れはオレンジの矢印となります。

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-ce
sudo 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.pub

https://github.com/settings/keys
こちらにアクセスします。

右上の「new SSH key」をクリックします。
image.png

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 bash

mysqlを起動させます。

service mysql start
mysql -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

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

【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サブネットグループを作成」をクリックします。

image.png

サブネットに先ほど、作成した二つのプライベートサブネットを追加します。

今、下記のような異なるアベイラビリティーゾーンを持つサブネットグループが作成されました。

IMG_5121AE56F9A4-1.jpeg

パラメーターグループの設定

RDSでは直接データベースの設定を触れないので、パラメーターグループで設定します。

image.png

パラメーターグループファミリーは、開発環境のバージョンに合わせます。

オプショングループの設定

RDSダッシュボードに入り、オブショングループを選択し、「グループを作成」をクリックします。

image.png

開発環境に合わせてエンジンとメジャーエンジンバージョンを設定します。

RDSを作成する。

RDSダッシュボードに入り、データベースを選択し、「データーベースの作成」をクリックします。
下記は設定例です。ご自身の運用に合わせて設定してください。

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

「データーベースの作成」クリック

少し分かりずらいですが、下記の様にRDSがサブネットグループとdb用セキュリティーグループと結びつけることにより、
IMG_5255B692BA7F-1.jpeg

結果として下記の構成となります。

IMG_9352B52CF97B-1.jpeg

これでRDSインスタンスが作成できました。

次回(6)へ続く
DockerコンテナをAWSにアップロードする

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

【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サブネットグループを作成」をクリックします。

image.png

サブネットに先ほど、作成した二つのプライベートサブネットを追加します。

今、下記のような異なるアベイラビリティーゾーンを持つサブネットグループが作成されました。

IMG_5121AE56F9A4-1.jpeg

パラメーターグループの設定

RDSでは直接データベースの設定を触れないので、パラメーターグループで設定します。

image.png

パラメーターグループファミリーは、開発環境のバージョンに合わせます。

オプショングループの設定

RDSダッシュボードに入り、オブショングループを選択し、「グループを作成」をクリックします。

image.png

開発環境に合わせてエンジンとメジャーエンジンバージョンを設定します。

RDSを作成する。

RDSダッシュボードに入り、データベースを選択し、「データーベースの作成」をクリックします。
下記は設定例です。ご自身の運用に合わせて設定してください。

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

「データーベースの作成」クリック

少し分かりずらいですが、下記の様にRDSがサブネットグループとdb用セキュリティーグループと結びつけることにより、
IMG_5255B692BA7F-1.jpeg

結果として下記の構成となります。

IMG_9352B52CF97B-1.jpeg

これでRDSインスタンスが作成できました。

次回(6)へ続く
DockerコンテナをAWSにアップロードする

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

【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上に置くことによって、クラウド上にシステムを構築します。

IMG_718A6999530D-1.jpeg

作成したEC2インスタンスは、パブリックサブネットに配置して、アプリ本体を置きます。

EC2インスタンスの作成

検索ウィンドウからEC2を検索し、コンソールに入ります。
image.png

インスタンスを起動をクリックします。
image.png

今回はインスタンスタイプにクイックスタートの「AMAZON Linux2」を利用します。
(ざっくり)どのタイプのコンピューターにするかということです。今回はOSがlinuxのものを選択します。

image.png

タイプは無料利用枠のt2.microを選択します。
(ざっくり)どの程度のスペックにするかとうことです。

image.png

→「次のステッップ:インスタンスの詳細設定」をクリックします。

項目 内容 説明(ざっくり)
インスタンス数 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側にで生成した鍵と合致した場合接続が許可される。

「インスタンスの作成」

image.png

作成されたら、分かりやすいようにインスタンスに名前を設定しておきます。
nameのところをクリックしたら名前が編集できます。

image.png

ダウンロードしたキーペアを適当な位置に移動させます。(今回は ~/.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/

上記のように表示されれば接続成功。

図にすると下記の様なイメージで接続しました。

IMG_D7961C5FA634-1.jpeg

EC2には先ほど作成したセキュリティーグループ(fitO2_SG)が適用されています。

image.png

インバウンド(入ってくる方の通信)に対し、ssh接続の場合、22番ポートを使用し、全てのアクセス元(0.0.0.0/0)を許可しているので、ssh接続することが可能だったわけです。

EC2インスタンスを作成し、ssh接続を行うことができました。

80番ポートもhttp通信に対し、開放されているので、今作成したインスタンスは下記のような通信を許可する状態となっています。

IMG_378691F05F41-1.jpeg

これでパブリックサブネットEC2インスタンスに対し、上記のようなセキュリティーグループが設定されました。

次回(5)へ続く
RDSを作成する

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

【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つ作る必要がありあります。
アベイラビリティーゾーンとは、ざっくりいうとクラウドが保管されているサーバーが実際に置かれている地域です。

よって下記のような構成を作ります。

IMG_633C134D7C4A-1.jpeg

一つ目のプライベートサブネット作成します。

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ダッシュボードのセキュリティーグループをクリックして、「セキュリティーグループの作成」をクリックする。

image.png

「ルールの追加」をクリックします。

セキュリティーグループ名 : fitO2_db_SG
VPC : 先ほど作成したVPC
インバウンド :
 タイプ : MYSQL/Aurora
ポート : 3306
ソース :
カスタム
   パブリックサブネットに置かれたEC2インスタンスに適用する予定の(先ほど作った)セキュリティーグループを指定。(名前を打ち込んだら出てくる。出てこなければグループIDをコピペ)

これで、プライベートサブネット2つと、それに適用させる予定の下記の様なセキュリティーグループの作成が完了しました。

IMG_237B88A63A89-1.jpeg

次回(4)へ続く
EC2インスタンスを作成する |

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

【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内でさらに区分されたネットワークのことです。
パブリックサブネットにアプリ本体。プライベートサブネットにデーターベースを置きます。
パブリックサブネットは、外部からのアクセスを許可する設定します。
プライベートサブネットは、外部からのアクセスを許可せず、パブリックサブネットからのアクセスのみを許可します。(データーベースは外部からアクセスする必要はないのでセキュリティー向上のため)

なお、「パブリックサブネット」「プライベートサブネット」という設定自体はなく、後ほど設定するセキュリティーグループにおいて、上記のようなネットワークのアクセス制限を設定していきます。

IMG_A66BC051DFB8-1.jpeg

 vpcのプライベートIPアドレスは、サイダー表記が16ビットなので、先頭から16ビット分つまり、10.0が、ネットワーク部となります。

 パブリックサブネット、プライベートサブネット共にプライベートアドレスは10.0.から始まっているので、VPC内のネットワークにあります。

 また、パブリックサブネットのサイダー表記は/24なので24ビット分、つまり10.0.10.までがネットワーク部。
プライベートサブネットのサイダー表記も/24なので24ビット分、つまり10.0.20.までがネットワーク部であり、
パブリックサブネットとプライベートサブネットは異なるネットワーク空間となります。

IMG_BD8661923AD3-1.jpeg

VPCの作成

image.png

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にアタッチします。

IMG_174B7A21241B-1.jpeg

IGWとは、ざっくりいうとVPCとインタネットを繋ぐ窓口のようなものです。IGWを通じて、インターネットとVPC通信を行います。アタッチとは、作成したIGWをVPCと紐づける作業となります。

VPCコンソールから、「インタネットゲートウェイ」を選択、「インターネットゲートウェイの作成」をクリック。
名前を決めて、作成。

一覧から作成したIGWを選択して、右上のアクションからVPCに「アタッチをクリック」

image.png

先ほど作成したVPCを選択して、「インターネットゲートウェイのアタッチ」をクリック

image.png

ルートテーブルを作成して、パブリックサブネットに紐付け

パブリックサブネット用のルーティングテーブルを作成します。

IMG_92E66ED01F79-1.jpeg

パブリックサブネットに来たアクセスのうち

10.0.0.0/16 が宛先のものはVPCに送ります。
10.0.10.0/24 が宛先のものはパブリックサブネット(自分自身)に送ります。
0.0.0.0/0 (上記以外全ての宛先)は、IGWに送ります。

VPCコンソールから、「ルートテーブル」を選択し、「ルートテーブルの作成」をクリックして、名前を決めてVPCに先ほど作成したVPCを選択します。

image.png

一覧から作成した、ルーティングを選択し、下部の「ルート」タブを確認すると、
送信先「10.0.0.0/16」のものが宛先(ターゲット)がVPC(local)となっていることが確認できます。
ルートテーブルは、必ず所属するVPCが必須であるためため、先ほど選択したVPCが紐付けられます。

「サブネットの関連付け」タブをクリックし、「サブネットの関連付け編集」をクリックします。

image.png

パブリックサブネットを選択し、保存をクリックします。

image.png

IGWへのルートを作成する。

「ルートタブ」を選択し、「ルートの編集」をクリックする。
image.png

「ルートの追加」を選択して、「0.0.0.0/0」を選択する。
先ほど作成したIGWを選択する。

「ルートの保存」をクリックする。

image.png

これで、パブリックサブネットに紐づくルーティングテーブルが作成されました。

作り方をまとめると、下記の様になります。

IMG_AE0A928B8E61-1.jpeg

それぞれ作り方が異なるのでややこしいですが、やっていることは、宛先IPアドレスに対して、どこに通信を振り分けるかということです。

パブリックサブネット用のセキュリティーグループを作成する。

EC2ダッシュボードのセキュリティーグループをクリックして、「セキュリティーグループの作成」をクリックする。

「ルールの追加」をクリックします。

image.png

セキュリティーグループ名 : fitO2_SG
VPC: 先ほど作成したVPC
インバウンド:
 上記図の様に作成

これで、全てのアクセス元に対して、SSH通信(22番ポート)とhttp通信(80番ポート)を開放するセキュリティーグループが作成できました。後ほど、作るEC2インスタンスに、このセキュリティーグループを適用させる予定です。
(セキュリティーグループは後ほど、もうちょっと詳しく説明します。)

次回(3)へ続く
プライベートサブネットを作成する

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

【Rails AWS Docker】既存Ruby on Rails + MySQLアプリをDockerで構築し、AWSにデプロイする(1)

ポートフォリをとして作ったRuby on RailsアプリをDockerコンテナ化し本番環境をAWSで構築するまでの道のりです。
ポートフォリオ自体はこちらとなります。
【ポートフォリオ】転職活動時に作成したポートフォリオの概要(テッ◯キャンプ)

かなり苦しめられたので、どなたかのお役に立てれば。

タイトル
1 ローカル環境のRailsアプリをDockerコンテナ化

参考にさせていただいた記事は、(6)の末尾い記載しています。

ローカル環境のRailsアプリをDockerコンテナ化

Dockerコンテナ環境構成(ローカル版)

IMG_CE2774B27B97-1.jpeg

構成は上記です。
webサーバーとしてnginxを配置します。
appサーバーはpumaを設置します。

まず既存のRailsアプリをコンテナ化します。

前提

AWSにアカウント作成済
docker hubにアカウント作成済
docker インストール済
ローカル環境で動作するRailsアプリ

構築

※fitO2の部分は、ご自身のアプリ名に変更してください。

現状のアプリのフォルダ構成に、下記のファイルを追加します。

docker-compose.yml

Dockerfile

nginx_docker
  ├── Dockerfile
  └── nginx.conf

config
  └── puma.rb

docker-compose.yml
version: '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.conf
upstream 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.rb
threads_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", true

pumaの設定ファイルです。
bind "unix://#{app_root}/tmp/sockets/puma.sock"の部分は、nginx.confのserverと一致するようにしなければなりません。

参考

config/database.yml
default: &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

http://localhost

にアクセスすると、サイトにアクセスすることができます。

エラーがー生じた際は、docker-compose upターミナルにログが出ていますので、確認してください。

とりあえず既存のアプリをDockerコンテナ化できました。

次回(2)へ続く
[AWSにVPCを作成する。パブリックサブネットを作成する。]

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

【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コンテナ環境構成(ローカル版)

IMG_CE2774B27B97-1.jpeg

構成は上記です。
webサーバーとしてnginxを配置します。
appサーバーはpumaを設置します。

まず既存のRailsアプリをコンテナ化します。

前提

AWSにアカウント作成済
docker hubにアカウント作成済
docker インストール済
ローカル環境で動作するRailsアプリ

構築

※fitO2の部分は、ご自身のアプリ名に変更してください。

現状のアプリのフォルダ構成に、下記のファイルを追加します。

docker-compose.yml

Dockerfile

nginx_docker
  ├── Dockerfile
  └── nginx.conf

config
  └── puma.rb

docker-compose.yml
version: '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.conf
upstream 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.rb
threads_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", true

pumaの設定ファイルです。
bind "unix://#{app_root}/tmp/sockets/puma.sock"の部分は、nginx.confのserverと一致するようにしなければなりません。

参考

config/database.yml
default: &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

http://localhost

にアクセスすると、サイトにアクセスすることができます。

エラーがー生じた際は、docker-compose upターミナルにログが出ていますので、確認してください。

とりあえず既存のアプリをDockerコンテナ化できました。

次回(2)へ続く
AWSにVPCを作成する。パブリックサブネットを作成する。

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