docker-composeでrails環境を構築する

環境

OS

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 18.04.4 LTS
Release:        18.04
Codename:       bionic

Docker

$ docker -v
Docker version 19.03.6, build 369ce74a3c

docker-compose

$ docker-compose -v
docker-compose version 1.25.4, build 8d51620a

今回作成する構成

Web Server

nginx

Ruby Web Server

puma (rails server)

構築手順

[1] 基礎となるdockerを用意する

> 手順6 以降はdocker hubに公開する手順です。後悔したくない場合はプライベートレポジトリ作成の手順をネットで探して参照してください。

  1. 作業用ディレクトリを作成

    $ mkdir rails_base
    $ pushd rails_base
  2. baseのimageを指定

    $ cat << EOS > Dockerfile
    # define ubuntu version, you can use --build-arg
    ARG ubuntu_version="19.10"
    FROM ubuntu:\${ubuntu_version}
    EOS
  3. rvmをインストールするためにbashを利用する

    $ cat << EOS >> Dockerfile
    # Dockerfile on bash
    SHELL ["/bin/bash", "-c"]
    EOS
  4. バージョンを簡単に変更しやすいように変数を設定

    $ cat << EOS >> Dockerfile
    # Default nvm version, you can use --build-arg
    ARG nvm_version="0.35.2"
    # Default node version, you can use --build-arg
    ARG node_version="v13.9.0"
    # Default ruby version, you can use --build-arg
    ARG ruby_version="2.7.0"
    # Default ffi version, you can use --build-arg
    ARG ffi_version="1.12.2"
    # Default sassc version, you can use --build-arg
    ARG sassc_version="2.2.1"
    EOS
  5. railsに必要なパッケージをインストール
    ここではnewsdict.jpに必要なパッケージを使ってます。自由に書き換えてください

    $ cat << EOS >> Dockerfile
    # Install packages
    RUN apt update \
    && apt install --no-install-recommends  -y \
    gnupg2 \
    gnupg1 \
    gnupg \
    libmagickwand-dev \
    libmecab-dev \
    libxslt-dev \
    mecab-ipadic \
    mecab-ipadic-utf8 \
    mecab-utils \
    openjdk-8-jdk \
    graphicsmagick \
    graphviz \
    nginx \
    python2 \
    git \
    curl
    EOS
  6. yarnのインストール

    $ cat << EOS >> Dockerfile
    RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \
    && echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list \
    && apt update \
    && apt install --no-install-recommends -y yarn
    EOS
  7. nodeのインストール

    $ cat << EOS >> Dockerfile
    # Installv nvm
    RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v\${nvm_version}/install.sh | bash
    ENV NVM_DIR "/root/.nvm"
    RUN . \${NVM_DIR}/nvm.sh \
    && nvm install \${node_version} \
    && nvm alias default ${node_version}
    EOS
  8. rubyのインストール

    $ cat << EOS >> Dockerfile
    # Install rvm and ruby
    RUN curl -sSL https://rvm.io/mpapis.asc | gpg --import - \
    && curl -sSL https://rvm.io/pkuczynski.asc | gpg --import - \
    && curl -sSL https://get.rvm.io | bash -s stable \
    && . /etc/profile.d/rvm.sh \
    && rvm install \${ruby_version} \
    && gem install bundler
    EOS
  9. (任意) ビルド時間短縮のためgemをインストール

    $ cat << EOS >> Dockerfile
    # Install sassc. For fast install of gem.
    RUN echo "gem: --no-rdoc --no-ri" > ~/.gemrc
    RUN . /etc/profile.d/rvm.sh && \
    gem install "sassc:\${sassc_version}" "ffi:\${ffi_version}"
    EOS
  10. ビルドする

    $ docker build -t rails_base .
  11. docker hubに登録する

    1. 以下のURLよりdocker hubに登録する(無料です)
      https://hub.docker.com/

    2. (任意) docker hubに公開する

      $ docker login
      Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
      Username: [docker hubのユーザ名を入力]
      Password: [docker hubのパスワードを入力]
      WARNING! Your password will be stored unencrypted in /home/ubuntu/.docker/config.json.
      Configure a credential helper to remove this warning. See
      https://docs.docker.com/engine/reference/commandline/login/#credentials-store
       
      Login Succeeded
    3. docker hubにpushする

      $ docker tag rails_base [docker hub ユーザ名]/base_docker_image_for_rails
      $ docker push [docker hub ユーザ名]/base_docker_image_for_rails
  12. このセクションで作成したdocker image

[2] 今回のrails6に必要なdockerを作成する

[1] で作成したdockerと分けているのは、ビルド実行速度を大幅に下げるためです。ビルド速度が問題にならない場合は [1] と同じDockerfileに記述して問題ありません。

  1. railsを用意する

    $ rails new docker_image_for_rails
    $ pushd docker_image_for_rails
  2. rvm の rubyバージョンを設定する(railsのインストール環境とdockerのrubyバージョンが違う場合に必要です)

    $ echo 'ruby-2.7.0' > .ruby-version
    $ sed -i "s/ruby '2.6.3'/ruby '2.7.0'/" Gemfile
    $ sed -i "s/gem 'tzinfo-data', platforms: \[:mingw, :mswin, :x64_mingw, :jruby\]/gem 'tzinfo-data'/" Gemfile
    $ rm Gemfile.lock
  3. config/environments/development.rbにpumaから待ち受けれるように記述する

    # To allow requests to puma, add the following to your environment configuration
    config.hosts << "puma"
  4. socketで待ち受けできるように変更する

    $ sed -i 's@^port\s.*$@bind "unix://#{Rails.root}/tmp/sockets/puma.sock"@' config/puma.rb
  5. [1] で作成したDockerfileを使う(ビルド速度が問題にならない場合は[1]のファイルに追記してください)

    base_imageを任意のimageにすることでimageを変更可能です

    $ cat << EOS > Dockerfile
    # Define base image, you can use --build-arg
    ARG base_image="newsdict/base_docker_image_for_rails"
    FROM \$base_image
    EOS
  6. docker用のentrypointシェルを作成する

    1. nvmの読み込み
      $ cat << EOS > entrypoint.sh
      # Initialize nvm
      export NVM_DIR="\$HOME/.nvm"
      [ -s "\$NVM_DIR/nvm.sh" ] && \. "\$NVM_DIR/nvm.sh"  # This loads nvm
      [ -s "\$NVM_DIR/bash_completion" ] && \. "\$NVM_DIR/bash_completion"  # This loads nvm bash_completion
      EOS
    2. rvmの読み込み
      $ cat << EOS >> entrypoint.sh
      # Initialize rvm
      . /etc/profile.d/rvm.sh
      EOS
    3. yarn install
      $ cat << EOS >> entrypoint.sh
      # yarn install
      yarn install --check-files
      EOS
    4. bundle install
      $ cat << EOS >> entrypoint.sh
      bundle config --global --delete without
      bundle config --global --delete frozen
      rm Gemfile.lock # Run only when docker-compose build
      bundle install
      EOS
    5. binstubsを作る
      $ cat << EOS >> entrypoint.sh
      rm -rf /var/www/docker/bin
      bundle exec rake app:update:bin
      bundle exec rails webpacker:binstubs
      bundle exec spring binstub --all
      EOS
    6. webpackerを起動
      $ cat << EOS >> entrypoint.sh
      # Start webpack-dev-server
      bin/webpack-dev-server &
      EOS
    7. nginxとrails serverを起動する
      $ cat << EOS >> entrypoint.sh
      /usr/sbin/nginx -c /etc/nginx/nginx.conf
      cd /var/www/docker
      bundle exec bin/rails log:clear
      EDITOR="mate --wait" bundle exec bin/rails credentials:edit
      bundle exec bin/rails webpacker:compile
      bundle exec bin/rails assets:precompile
      bundle exec bin/rails db:seed
      RAILS_LOG_TO_STDOUT=true bundle exec bin/rails server
      EOS

      1.nginxの設定ファイルを作る

      $ mkdir -p src/provisioning/nginx/sites-available/
      $ cat << EOS > src/provisioning/nginx/sites-available/default
      upstream puma {
      server unix:///var/www/docker/tmp/sockets/puma.sock;
      }
      server {
      listen 80 default_server;
      server_name _;
      root /var/www/docker/public;
      index index.html;
      # For compiled css
      location /assets {
      root /var/www/docker/public;
      }
      # For webpacker's js
      location /packs {
      root /var/www/docker/public;
      }
      # For rails
      location / {
      proxy_pass http://puma/;
      proxy_http_version 1.1;
      proxy_set_header Upgrade \$http_upgrade;
      proxy_set_header Connection "Upgrade";
      proxy_set_header Host \$http_host;
      proxy_read_timeout 180s;
      proxy_set_header X-Real-IP \$remote_addr;
      proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
      }
      }
      EOS

      1.Dockerfileを完成させる

      $ cat << EOS >> Dockerfile
      # Set correct environment variables.
      RUN mkdir -p /var/www/docker
      WORKDIR /var/www/docker
      # Set up application
      COPY . .
      RUN cp src/provisioning/nginx/sites-available/default /etc/nginx/sites-available/default
      # Init gems
      RUN . /etc/profile.d/rvm.sh && \
      bundle config --global without 'development test' && \
      bundle config --global system true && \
      bundle install --quiet && \
      bundle config --global frozen true
      # If you are running the development environment, the pid file will remain, so delete the pid file
      RUN if [ -f /var/www/docker/tmp/pids/server.pid ]; then \
      rm /var/www/docker/tmp/pids/server.pid; \
      fi
      CMD ["bash", "/var/www/dockder/entrypoint.sh"]
      # Port 80: Application (nginx + puma)
      # Port 3035: webpack-dev-server
      EXPOSE 80 3035
      EOS

[3] docker-compose.ymlを用意する

$ cat << EOS >> docker-compose.yml
version: "3"
networks:
  app-tier:
    driver: bridge
services:
  web:
    tty: true
    stdin_open: true
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - ./:/var/www/docker
    working_dir: /var/www/docker
    command: "bash entrypoint.sh"
    ports:
      - 3000:80
      - 3035:3035
    networks:
      - app-tier
EOS

[4] 起動する

$ [ -f tmp/sockets/puma.sock ] && rm -f tmp/sockets/puma.sock
$ docker-compose up --build [-d]

githubにアップしてます

https://github.com/newsdict/docker_image_for_rails

コメントを残す

メールアドレスが公開されることはありません。