Hello. This time too, I summarized the procedure for building a Rails application development environment with Docker. Last time I started two containers for Rails and a database, but this time I also started a container for Nginx as a Web server.
Ruby: 2.5.8 Rails: 5.2.4.4 MySQL: 5.7.31 Nginx: 1.19.2 Docker: 19.03.12 Docker Compose: 1.26.2
The overall configuration is as follows. Now, let's create directories and files as shown in this configuration diagram.
Overall composition
/test-app
├── Dockerfile
├── Dockerfile.nginx
├── docker-compose.yml
├── nginx.conf
├── Gemfile
└── Gemfile.lock
First, create the root directory of your project.
terminal
$ mkdir test-app
And directly under the root directory
DockerfileDockerfile.nginxdocker-compose.ymlnginx.confGemfileGemfile.lockCreate these.
terminal
$ cd test-app
$ touch Dockerfile Dockerfile.nginx docker-compose.yml nginx.conf Gemfile Gemfile.lock 
The contents of each file created above are as follows. (Leave Gemfile.lock empty.)
Dockerfile
FROM ruby:2.5
RUN apt-get update && apt-get install -y \
    build-essential \
    node.js
WORKDIR /test-app
COPY . /test-app
RUN bundle install
Dockerfile.nginx
FROM nginx
RUN rm -f /etc/nginx/conf.d/*
COPY nginx.conf /etc/nginx/conf.d/test-app.conf
CMD /usr/sbin/nginx -g 'daemon off;' -c /etc/nginx/nginx.conf
containers/nginx/nginx.conf
#Specify proxy destination
#Send the request received by Nginx to the backend puma
upstream test-app {
  #I want to communicate with sockets, so puma.Specify sock
  server unix:///test-app/tmp/sockets/puma.sock;
}
server {
  listen 80;
  #Specify domain or IP
  server_name _;
  access_log /var/log/nginx/access.log;
  error_log  /var/log/nginx/error.log;
  #Specifying the document root
  root /test-app/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 @test-app;
  keepalive_timeout 5;
  #Reverse proxy related settings
  location @test-app {
    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://test-app;
  }
  location /favicon {
    empty_gif;
    access_log    off;
    log_not_found off;
  }
}
Gemfile
source 'https://rubygems.org'
gem 'rails', '~>5.2'
docker-compose.yml
version: '3'
services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    command: bundle exec puma -C config/puma.rb
    volumes:
      - .:/test-app
    tty: true
    stdin_open: true
    depends_on:
      - db
  db:
    image: mysql:5.7
    environment:
      - 'MYSQL_ROOT_PASSWORD=password'
    volumes:
      - 'db-data:/var/lib/mysql'
  web:
    build:
      context: .
      dockerfile: Dockerfile.nginx
    volumes:
      - ./public:/test-app/public
      - ./tmp:/test-app/tmp
    ports:
      - 80:80
    depends_on:
      - app
volumes:
  db-data:
terminal
$ docker-compose run --rm app rails new . --force --database=mysql --skip-bundle
First, create a sockets folder inside the tmp folder.
Then, edit the following three of the files created by Rails setup.
config/database.ymlconfig/puma.rbconfig/environments/production.rbconfig/database.yml
default: &default
  adapter: mysql2
  encoding: utf8
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password: password   #docker-compose.yml MYSQL_ROOT_Set the value of PASSWORD
  host: db   #docker-compose.Match with yml service name
development:
  <<: *default
  database: test-app_development
config/puma.rb
threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }
threads threads_count, threads_count
port        ENV.fetch("PORT") { 3000 }
environment ENV.fetch("RAILS_ENV") { "development" }
pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" }
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
config/environments/production.rb
# Do not fallback to assets pipeline if a precompiled asset is missed.
config.assets.compile = true   #The default is false, so change it to true
There is no problem in building the development environment without changing this config / environments / production.rb, but I got an asset precompile error when deploying to the production environment, so I changed it here. It is.
terminal
$ docker-compose up -d --build
$ docker-compose exec app rails db:create
Now when you go to http: // localhost, you should see the Rails home screen.
Recommended Posts