[RUBY] Build a local development environment for Rails tutorials with Docker (Rails 6 + PostgreSQL + Webpack)

Introduction

The latest Rails tutorial (as of 2020.8.5) uses Rails 6 and I would like to build a development environment corresponding to this with Docker.

When building a development environment for personally developed apps I introduced Rails 6 because I like new things ...

However ... with the introduction of Webpack in the JavaScript module bundler from Rails 6 Not only will the introduction and management of tools such as Bootstrap and Fontawesome change, but In the first place, when building the environment, steps that are not necessary in Rails 5 are necessary, We're hitting the rails 6 and Webpack walls in a big way ...

Since it is a great deal, I would like to organize and establish my knowledge and experience through this trial.

Also, I would like to re-run while actually derailing the Rails tutorial and deepen my learning.

Personally developed app mdClip

Previously, an article about building a Rails 5 environment with Docker Building Rails development environment with Docker for the first time [NGINX + Rails 5 (puma) + PostgreSQL] --Qiita

environment

Configuration file

Prepare the following 5 files in the workspace Dockerfile, docker-compose.yml, Gemfile, Gemfile.lock, entrypoint.sh

https://github.com/naokit1030/sample_app_on_docker.git

git clone -b create-docker-files https://github.com/dev-naokit/sample_app_on_docker.git

Dockerfile

--Use "alpine" to reduce the weight of the image

--nodejs, yarn are required for Webpack introduction

--You can't just use postgresql, you also need postgresql-dev

--bundle install's -j4 option speeds up bundle install

--After bundle install, deleting unnecessary files contributes to reducing image size

FROM ruby:2.6.3-alpine

ENV LANG=ja_JP.UTF-8
ENV TZ=Asia/Tokyo
ENV ROOT=/myapp \
    GEM_HOME=/bundle \
    BUNDLE_PATH=$GEM_HOME
ENV BUNDLE_BIN=$BUNDLE_PATH/bin
ENV PATH /app/bin:$BUNDLE_BIN:$PATH


WORKDIR $ROOT

RUN apk update && \
    apk upgrade && \
    apk add --no-cache \
        gcc \
        g++ \
        libc-dev \
        libxml2-dev \
        linux-headers \
        make \
        nodejs \
        postgresql \
        postgresql-dev \
        tzdata \
        yarn && \
    apk add --virtual build-packs --no-cache \
        build-base \
        curl-dev

COPY Gemfile $ROOT
COPY Gemfile.lock $ROOT

RUN bundle install -j4
#Delete unnecessary files
RUN rm -rf /usr/local/bundle/cache/* /usr/local/share/.cache/* /var/cache/* /tmp/* && \
apk del build-packs

COPY . $ROOT

# Add a script to be executed every time the container starts.
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["sh", "/usr/bin/entrypoint.sh"]
EXPOSE 3000

docker-compose.yml

--Added : cahed option to volume to address slow storage access on mac --Webpack-dev-server is started in another container to support hot reload. (If there is a change in the file structure, it will reload the browser and compile around javascript if necessary) --db host, user, password will be reused later

version: '3'

services:
  db:
    image: postgres:11.0-alpine
    volumes:
      - postgres:/var/lib/postgresql/data:cached
    environment:
      - TZ=Asia/Tokyo
    ports:
      - '5432:5432'
    environment:
      PGDATA: /var/lib/postgresql/data/pgdata
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: password
      POSTGRES_INITDB_ARGS: '--encoding=UTF-8 --locale=ja_JP.UTF-8'
      TZ: Asia/Tokyo
  app:
    build: .
    command: ash -c "rm -f tmp/pids/server.pid && ./bin/rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/myapp:cached
      - rails_cache:/myapp/tmp/cache
      - bundle:/bundle:cached
    tmpfs:
      - /tmp
    tty: true
    stdin_open: true
    ports:
      - "3000:3000"
    environment:
      RAILS_ENV: development
      NODE_ENV: development
      DATABASE_HOST: db
      DATABASE_PORT: 5432
      DATABASE_USER: postgres
      DATABASE_PASSWORD: password
      WEBPACKER_DEV_SERVER_HOST: webpacker
    depends_on:
      - db
      - webpacker
    links:
      - db
      - webpacker
  webpacker:
    build: .
    command: ./bin/webpack-dev-server
    volumes:
      - .:/myapp:cached
    environment:
      RAILS_ENV: development
      NODE_ENV: development
      WEBPACKER_DEV_SERVER_HOST: 0.0.0.0
    tty: false
    stdin_open: false
    ports:
      - '3035:3035'

volumes:
  rails_cache:
  postgres:
  bundle:

Gemfile

source 'https://rubygems.org'
gem 'rails',      '6.0.3'

Gemfile.lock Only the touch command is fine as an empty file

touch Gemfile.lock

entrypoint.sh

#!/bin/bash
set -e

# Remove a potentially pre-existing server.pid for Rails.
rm -f /myapp/tmp/pids/server.pid

# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"

procedure

Install Rails 6.0.3.

docker-compose run app rails new . --force --no-deps --database=postgresql --skip-bundle

Gemfile Changed as follows according to Rails tutorial (It has been changed to use PostgreSQL even in the Development and test environments.)

source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

gem 'rails',      '6.0.3'
gem 'puma',       '4.3.4'
gem 'pg',         '1.1.4'
gem 'sass-rails', '5.1.0'
gem 'webpacker',  '4.0.7'
gem 'turbolinks', '5.2.0'
gem 'jbuilder',   '2.9.1'
gem 'bootsnap',   '1.4.5', require: false

group :development, :test do
  gem 'byebug',  '11.0.1', platforms: [:mri, :mingw, :x64_mingw]
end

group :development do
  gem 'web-console',           '4.0.1'
  gem 'listen',                '3.1.5'
  gem 'spring',                '2.1.0'
  gem 'spring-watcher-listen', '2.0.1'
end

group :test do
  gem 'capybara',                 '3.28.0'
  gem 'selenium-webdriver',       '3.142.4'
  gem 'webdrivers',               '4.1.2'
  gem 'rails-controller-testing', '1.0.4'
  gem 'minitest',                 '5.11.3'
  gem 'minitest-reporters',       '1.3.8'
  gem 'guard',                    '2.16.2'
  gem 'guard-minitest',           '2.4.6'
end

group :production do
end

#On Windows tzinfo for timezone information-Must include data gem
#gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

Updated Gemfile.lock (may not be needed)

docker-compose run app bundle update

Install webpacker

Rails 6 requires a webpacker, It is not installed as it is, so install it

docker-compose run app rails webpacker:install

Database settings

config/database.yml Match host, username, password with docker-compose.yml

default: &default
  adapter: postgresql
  encoding: unicode
  host: db
  username: postgres
  password: password
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  
#abridgement...

docker-compose build 'Build' is required every time you change a Dockerfile or Gemfile It will take some time because bundle install is also executed.

docker-compose build

Finally start the container

docker-compose up

Database creation

It is said that there is no DB as it is, so create a DB for development environment

docker-compose run app rake db:create

Operation check

Check the container running with docker ps Three containers, DB, Rails and webpack-dev-server are running.

$ docker ps
CONTAINER ID        IMAGE                            COMMAND                  ...              PORTS                              NAMES
1fb4f53d5652        sample_app_on_docker_app         "sh /usr/bin/entrypo…"   ...    0.0.0.0:3000->3000/tcp             sample_app_on_docker_app_1
ccd40c018d53        sample_app_on_docker_webpacker   "sh /usr/bin/entrypo…"   ...    3000/tcp, 0.0.0.0:3035->3035/tcp   sample_app_on_docker_webpacker_1
74392532098a        postgres:11.0-alpine             "docker-entrypoint.s…"   ...    0.0.0.0:5432->5432/tcp             sample_app_on_docker_db_1

When you access localhost: 3000 with a browser

Thank you for your hard work "Yay! You ’re on Rails!"

Trouble shoot

check_yarn_integrity related

Error when starting a container with docker-compose up

app_1        | ========================================
app_1        |   Your Yarn packages are out of date!
app_1        |   Please run `yarn install --check-files` to update.
app_1        | ========================================
app_1        | 
app_1        | 
app_1        | To disable this check, please change `check_yarn_integrity`
app_1        | to `false` in your webpacker config file (config/webpacker.yml).
app_1        | 
app_1        | 
app_1        | yarn check v1.16.0
app_1        | info Visit https://yarnpkg.com/en/docs/cli/check for documentation about this command.
app_1        | 
app_1        | 
app_1        | Exiting
sample_app_on_docker_app_1 exited with code 1

config/webpacker.yml Change as follows

#...abridgement

development:
  <<: *default
  compile: false # true ->Change to false

  # Verifies that correct packages and versions are installed by inspecting package.json, yarn.lock, and node_modules
  check_yarn_integrity: true
  
#abridgement...

"webpack-dev-server" not found

Similarly, the error that occurs when starting the container with docker-compose up

webpacker_1  | yarn run v1.16.0
webpacker_1  | error Command "webpack-dev-server" not found.
webpacker_1  | info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
sample_app_on_docker_webpacker_1 exited with code 1

Because webpack-dev-server should not be described in package.json Install webpack-dev-server

docker-compose run app yarn add webpack-dev-server

bonus

Image size 477MB I intend to borrow a lot of the wisdom of my ancestors to reduce the weight. When I started learning Docker, the image I made was about 1.5GB ...

$docker images
REPOSITORY                       TAG                 IMAGE ID            CREATED             SIZE
sample_app_on_docker_app         latest              84aed607a3d2        31 minutes ago      477MB
sample_app_on_docker_webpacker   latest              84aed607a3d2        31 minutes ago      477MB

Recommended Posts

Build a local development environment for Rails tutorials with Docker (Rails 6 + PostgreSQL + Webpack)
Build a development environment for Docker + Rails6 + Postgresql
Build a local development environment for Rails tutorials with Docker-Introduce Bootstrap and Font Awesome with Webpack-
Build debug environment on container --Build local development environment for Rails tutorial with Docker-
I made a development environment with rails6 + docker + postgreSQL + Materialize.
Build a PureScript development environment with Docker
Build a Wordpress development environment with Docker
Build a local development environment for Open Distro for Elasticsearch with multiple nodes using Docker
Procedure for building a Rails application development environment with Docker [Rails, MySQL, Docker]
Build a development environment for Django + MySQL + nginx with Docker Compose
Build a WordPress development environment quickly with Docker
Build a development environment for Docker, java, vscode
How to build a Ruby on Rails development environment with Docker (Rails 5.x)
Template: Build a Ruby / Rails development environment with a Docker container (Ubuntu version)
Template: Build a Ruby / Rails development environment with a Docker container (Mac version)
Build Couchbase local environment with Docker
Build environment with vue.js + rails + docker
Build Rails environment with Docker Compose
How to build Rails, Postgres, ElasticSearch development environment with Docker
[Rails] [Docker] Copy and paste is OK! How to build a Rails development environment with Docker
How to quit Docker for Mac and build a Docker development environment with Ubuntu + Vagrant
How to build Rails 6 environment with Docker
Build a simple Docker + Django development environment
Steps to build a Ruby on Rails development environment with Vagrant
One file of Docker x Laravel threat! Build a local development environment with the minimum configuration
Build a Laravel / Docker environment with VSCode devcontainer
Creating a java web application development environment with docker for mac part1
I tried to build a Firebase application development environment with Docker in 2020
[Copy and paste] Build a Laravel development environment with Docker Compose Part 2
Build a simple Docker Compose + Django development environment
[Copy and paste] Build a Laravel development environment with Docker Compose Participation
[Win10] Build a JSF development environment with NetBeans
[Rails] How to build an environment with Docker
[First team development ②] Build an environment with Docker
Create a java web application development environment with docker for mac part2
Wordpress local environment construction & development procedure with Docker
Create a Spring Boot development environment with docker
Build a Java development environment with VS Code
Build a development environment to create Ruby on Jets + React apps with Docker
Build a Ruby on Rails development environment on AWS Cloud9
How to build docker environment with Gradle for intelliJ
Stable development environment construction manual for "Rails6" with "Docker-compose"
Easily build a Vue.js environment with Docker + Vue CLI
[Note] Build a Python3 environment with Docker in EC2
Build Java development environment with WSL2 Docker VS Code
Build Rails (API) x MySQL x Nuxt.js environment with Docker
[Environment construction] Build a Java development environment with VS Code!
Build WordPress environment with Docker (Local) and AWS (Production)
Try to build a Java development environment using Docker
[2021] Build a Docker + Vagrant environment for using React / TypeScript
[Docker] Rails 5.2 environment construction with docker
Build docker environment with WSL
Build DynamoDB local with Docker
Until you build a Nuxt.js development environment with Docker and touch it with VS Code
Build a "Spring Thorough Introduction" development environment with IntelliJ IDEA
Rails application development environment construction with Docker [Docker, Rails, Puma, Nginx, MySQL]
Build a Node-RED environment with Docker to move and understand
Create Rails5 and postgresql environment with Docker and make pgadmin available
I tried to create a padrino development environment with Docker
Rails + MySQL environment construction with Docker
Create a Vue3 environment with Docker!