LoginSignup
37
38

More than 3 years have passed since last update.

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

Last updated at Posted at 2021-01-11

ポートフォリをとして作った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

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

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

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

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

37
38
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
37
38