2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Dockerを使用して環境構築してみた(初心者)

Posted at

#概要
Dockerを使用してRuby on Railsの開発環境を構築してみました。
Dockerを使用すると、ローカル環境に左右されず開発環境を構築でき、開発環境から本番環境への移行も設定を変更せず移行できるため、多くの開発現場で使用されている。
独学でDockerを勉強した私が作成した最終的な設定になります。

#バージョン
Ruby 2.6.3
Ruby on Rails 5.2.0
Docker 19.03.13
docker compose 1.27.4
MySQL 5.7
Nginx 1.15.8

#前提

  • docker、docker-composeはインストール済みである。

#ディレクトリ構成

ディレクトリ構成
./myapp
├── containers
│   └── nginx
│       ├── Dockerfile
│       └── nginx.conf
├── .env
├── docker-compose.yml
├── Dockerfile
├── Gemfile
└── Gemfile.lock

#各ディレクトリ、ファイルの詳細
Rails用Dockerfile

Dockerfile
FROM ruby:2.6.3

RUN apt-get update\
  && apt-get install -y --no-install-recommends\
  libpq-dev\
  nodejs\
  vim\
  mariadb-client\
  build-essential\
  && apt-get clean\
  && rm -rf /var/lib/apt/list/*

RUN mkdir /myproject
WORKDIR /myproject

COPY Gemfile /myproject/Gemfile
COPY Gemfile.lock /myproject/Gemfile.lock

RUN gem install bundler
RUN bundle install

COPY . /myproject

RUN mkdir -p tmp/sockets
RUN mkdir -p tmp/pids

Gemfile

Gemfile
source 'https://rubygems.org'

gem 'rails', '5.2.0'

Gemfile.lock
中身は空でOK

Nginx用Dockerfile

Dockerfile
FROM nginx:1.15.8

RUN rm -f /etc/nginx/conf.d/*

ADD nginx.conf /etc/nginx/conf.d/myproject.conf

CMD /usr/sbin/nginx -g 'daemon off;' -c /etc/nginx/nginx.conf

Nginx.confファイル

nginx.conf
upstream myproject {
  server unix:///myproject/tmp/sockets/puma.sock;
}

server {
  listen 80;
  server_name IPアドレス [or localhost];

  access_log /var/log/nginx/access.log;
  error_log /var/log/nginx/error.log;
  
  root /myproject/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 @myproject;
  keepalive_timeout 5;

  location @myproject {
    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://myproject;
  }
}

.envファイル

.env
MYSQL_ROOT_PASSWORD=password
MYSQL_USER=username
MYSQL_PASSWORD=password
MYSQL_DATABASE=docker_database

docker-compose.ymlファイル

docker-compose.yml
version: '3'

services:
  db:
    image: mysql:5.7
    command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
    env_file:
      - ./.env
    volumes:
      - mysql-data:/var/lib/mysql
    ports:
      - "4306:3306"

  app:
    build: .
    env_file:
      - ./.env
    command: bundle exec puma -C config/puma.rb
    init: true
    volumes:
      - .:/myproject
      - public-data:/myproject/public
      - tmp-data:/myproject/tmp
      - log-data:/myproject/log
    depends_on:
      - db

  web:
    build:
      context: containers/nginx
    init: true
    volumes:
      - public-data:/myproject/public
      - tmp-data:/myproject/tmp
    ports:
      - 80:80
    depends_on:
      - app

volumes:
  mysql-data:
  public-data:
  tmp-data:
  log-data:

#Railsアプリケーションの設定
まずrails newにてRailsアプリケーションを作成します。

terminal
$ docker-compose run --rm app bundle exec rails new . --force --database=mysql --skip-bundle

続いて、configディレクトリ内のpumaファイルを編集します。

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

database.ymlを編集します。

database.yml
default: &default
  adapter: mysql2
  charset: utf8
  encoding: utf8
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: <%= ENV.fetch("MYSQL_USER") { 'root' } %>
  password: <%= ENV.fetch("MYSQL_PASSWORD") { 'password' } %>
  host: db

development:
  <<: *default
  database: docker_database

test:
  <<: *default
  database: myproject_test

production:
  <<: *default
  database: myproject_production
  username: myproject
  password: <%= ENV['MYPROJECT_DATABASE_PASSWORD'] %>

#コンテナの起動
ここまで準備ができましたら、コンテナを起動します。

terminal
$ docker-compose build
ビルドが完了したら
$ docker-compose up

ここでlocalhostにアクセスしてRailsのページが立ち上がれば完成です。

#既存のRailsアプリをdockerで環境構築する場合
アプリケーションのフォルダの中に以下のディレクトリ、ファイル類を追加します。
(ファイルの設定は一から作る場合と一緒です。)

ディレクトリ構成
./myapp
├── containers
│   └── nginx
│       ├── Dockerfile
│       └── nginx.conf
│
│ その他のファイル
│
├── .env
├── docker-compose.yml
└── Dockerfile

その後、ビルドを行います。アプリケーションはすでにあるので、rails newコマンドをする必要はありません。
データベースは一度migrateする必要があるので、ビルド後にmigrateを行います。

terminal
$ docker-compose build
ビルドが完了したら
$ docker-compose up -d
$ docker-compose exec app rails db:migrate

以上でlocalhostにアクセスすれば既存のアプリケーションにdockerを導入することができると思います。

#補足
私もまだまだ勉強不足でして、途中でエラーになったりとかなり苦戦しました。
その都度、ネットで調べたりして解決できました。

#ハマったエラー

  • rails newでrailsファイルが作成できない。

参考ページでは

$ docker-compose run --rm app rails new . --force --database=mysql --skip-bundle

となっていましたが、

$ docker-compose run --rm app bundle exec rails new . --force --database=mysql --skip-bundle

でRailsファイル群をインストールすることができました。

  • docker-compose buildが通らない。
$ docker-compose build
...
Bundler could not find compatible versions for gem "sprockets":
  In snapshot (Gemfile.lock):
    sprockets (= 4.0.2)

  In Gemfile:
    sass-rails (~> 5.1) x86_64-linux was resolved to 5.1.0, which depends on
      sprockets (>= 2.8, < 4.0)

    rails (~> 5.2.0) x86_64-linux was resolved to 5.2.0, which depends on
sprockets-rails (>= 2.0.0) x86_64-linux was resolved to 3.2.2, which
depends on
        sprockets (>= 3.0.0)

Running `bundle update` will rebuild your snapshot from scratch, using only
the gems in your Gemfile, which may resolve the conflict.
ERROR: Service 'app' failed to build : The command '/bin/sh -c bundle install' returned a non-zero code: 6

bundle updateをするよう言われているので、bundle updateを行います。

$ docker-compose run app bundle update
その後
$ docker-compose build

#まとめ
dockerでの環境構築はなんとかできましたが、まだまだ勉強不足で苦戦しました。
私が初めてdockerを使い始めたときは、既存のアプリケーションをdocker化しました。その後、新規環境構築からdockerを導入する方法を行いましたが、何度もつまずいてしまいました。
細かな設定ももう一度勉強し、ひとつひとつの解説もいつかやっていきたいです。

#参考文献
Docker + Rails + Puma + Nginx + MySQL
#エラー解消 rails newできない Running bundle update will rebuild your snapshot from scratch, using only the gems in your Gemfile, which may resolve the conflict.

2
1
0

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?