[Rails AWS Docker] Build an existing Ruby on Rails + MySQL application with Docker and deploy it on AWS (1)

This is the way to build a production environment on AWS by turning a Ruby on Rails application created as a portfolio into a Docker container. The portfolio itself is here. [[Portfolio] Overview of the portfolio created during job change activities (Tec camp)] (https://qiita.com/sho_U/items/058e590325ee6833abb0)

I was suffering a lot, so I hope it helps someone.

title
1 Docker containerization of Rails application in local environment
2 Create a VPC on AWS. Create a public subnet
3 Create a private subnet
4 Create an EC2 instance
5 Create an RDS
6 Upload Docker container to AWS

The articles that I referred to are listed at the end of (6).

Docker containerization of Rails application in local environment

Docker container environment configuration (local version)

IMG_CE2774B27B97-1.jpeg

The configuration is above. Deploy nginx as a web server. The app server installs puma.

First, containerize your existing Rails app.

Premise

Account created on AWS Account created on docker hub docker installed Rails app running in a local environment

Build

Add the following files to the folder structure of the current application.

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

easy explanation

** db container ** Pull mysql: 5.7 from docker hub with image. Connect 3306 on the host side and 3306 port on the container side with ports. Use the network fitO2-network that is common to the app container side in networks.

** app container ** Specify the Dockerfile directory (context) with build and create a container from the Dockerfile. In volumes, the directory where docker-compose.yml on the host side exists and/fitO2 on the container side are mounted (common). Specify the configuration file with command and start puma (application server). Connect 3000 on the host side and 3000 ports on the container side with ports. It is specified that it will be executed after the app container is created by depends_on. Use the network fitO2-network that is common to the db container side in networks.

** web container ** Create a container from Dockerfile by specifying the directory (context) where ./nginx_docker is located in build. It is specified that it will be executed after the app container is created by depends_on.

FitO2-network is set in ** networks **.

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

easy explanation

Install the ruby: 2.5.1 image from docker hub with FROM. The necessary packages are installed in the first RUN. The working directory is set to/fitO2 in WORKDIR. COPY is copying the gemfile and gemfile.lock on the host side to the/fitO directory of the container. Install bundler on the second RUN. Install the package from the gemfile on the third RUN. Creating a 4th RUN socket file.

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

#Start Nginx after build is complete
CMD /usr/sbin/nginx -g 'daemon off;' -c /etc/nginx/nginx.conf

easy explanation

Install the nginx: 1.15.8 image from docker hub with FROM. RUN deletes the include directory. Copy the Nginx configuration file to the container with ADD. I try to start Nginx after the build is completed with CMD.

fitO2/nginx_docker/nginx.conf



upstream fitO2 {
  server unix:///fitO2/tmp/sockets/puma.sock;
}

server {
  listen 80;
# =========Switch between local and production===========
  # 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;
  }
}

This is the nginx configuration file. For local environments, set server_name to 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

This is the puma configuration file. The bind "unix: // # {app_root} /tmp/sockets/puma.sock" part must match the server in nginx.conf.

reference

config/database.yml


default: &default
  adapter: mysql2
  encoding: utf8
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
#Password and Username are docker-compose.Combine with yml
  username: root
  password: password
  host: db

development:
  <<: *default
  database: fitO2_development

test:
  <<: *default
  database: fitO2_test

Create and start container

Change to your app's directory.

Create a container.

docker-compose build

Create a network.

docker network create fitO2-network

Start the container.

docker-compose up

The first time, the database is initialized. Open the terminal in another tab, move directly under the app and enter the following command.

docker-compose exec app rails db:create 
docker-compose exec app rails db:migrate
docker-compose exec app rails db:seed (Not needed without a seeder)

If it doesn't work, or if you make a trial and error, the seeder may be inserted halfway and it may be played due to validation, so delete the database once as shown below and then execute the above command again. please.

docker-compose exec app rails db:drop

http://localhost

You can access the site by visiting.

If an error occurs, check the log in the docker-compose up terminal.

For the time being, I was able to convert an existing application into a Docker container.

Continue to next time (2) Create a VPC on AWS. Create a public subnet.

Recommended Posts

[Rails AWS Docker] Build an existing Ruby on Rails + MySQL application with Docker and deploy it on AWS (5)
[Rails AWS Docker] Build an existing Ruby on Rails + MySQL application with Docker and deploy it on AWS (6)
[Rails AWS Docker] Build an existing Ruby on Rails + MySQL application with Docker and deploy it on AWS (3)
[Rails AWS Docker] Build an existing Ruby on Rails + MySQL application with Docker and deploy it on AWS (1)
[Rails AWS Docker] Build an existing Ruby on Rails + MySQL application with Docker and deploy it on AWS (4)
Build an environment with Docker on AWS
Build Metabase with Docker on Lightsail and make it https with nginx
Deploy to heroku with Docker (Rails 6, MySQL)
How to build a Ruby on Rails development environment with Docker (Rails 6.x)
How to build a Ruby on Rails development environment with Docker (Rails 5.x)
Ruby on Rails ✕ Docker ✕ MySQL Introducing Docker and docker-compose to apps under development
[Ruby on Rails] Let's build an environment on mac
[Rails] How to build an environment with Docker
Building an environment for WordPress, MySQL and phpMyAdmin with Docker Compose on EC2
Rails6 I tried to introduce Docker to an existing application
Build Rails (API) x MySQL x Nuxt.js environment with Docker
Build WordPress environment with Docker (Local) and AWS (Production)
How to install Docker in the local environment of an existing Rails application [Rails 6 / MySQL 8]
Maybe it works! Create an image with Docker and share it!
[Docker] Build a site on Hugo and publish it on GitHub
Rails application development environment construction with Docker [Docker, Rails, Puma, Nginx, MySQL]
Java: Start WAS with Docker and deploy your own application
How to deploy a Rails application on AWS (article summary)
Deploy a Docker application with Greengrass
[Docker] How to back up and restore the DB data of Rails application on docker-compose [MySQL]
Ruby on Rails development environment construction with Docker + VSCode (Remote Container)
How to make an application with ruby on rails (assuming that the environment has been built)
Procedure for building a Rails application development environment with Docker [Rails, MySQL, Docker]
Build environment with vue.js + rails + docker
How to build an environment with Docker, which is the minimum required to start a Rails application
(Ruby on Rails6) Creating a database and displaying it in a view
[Environment construction with Docker] Rails 6 & MySQL 8
How to build Rails + Vue + MySQL environment with Docker [2020/09 latest version]
Deploy Rails on Docker to heroku
Steps to build a Ruby on Rails development environment with Vagrant
Build a web application development environment that uses Java, MySQL, and Redis with Docker CE for Windows
Build debug environment on container --Build local development environment for Rails tutorial with Docker-
I built a rails environment with docker and mysql, but I got stuck
How to build a Ruby on Rails environment using Docker (for Docker beginners)
Enable Docker build cache on GitHub Action and deploy to Amazon ECS
Getting Started with Micronaut 2.x ~ Native Build and Deploy to AWS Lambda ~
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)
[Ruby on Rails] Creating an inquiry form
Building Rails 6 and PostgreSQL environment with Docker
Deploy heroku with Rails6 (Cloud9 + Ubuntu) + MySQL
Create Rails 6 + MySQL environment with Docker compose
[Docker] Development environment construction Rails6 / Ruby2.7 / MySQL8
Notes on using FCM with Ruby on Rails
[Ruby on Rails] Controller test with RSpec
Deploy to Heroku [Ruby on Rails] Beginner
Ruby on Rails application new creation command
[Ruby on Rails] Model test with RSpec
Deploy your application with VPC + EC2 + Docker.
Build an Ultra96v2 development environment on Docker 1
How to build Rails 6 environment with Docker
Introduce Docker to the development environment and test environment of existing Rails and MySQL applications
A memorandum when building an environment with Ruby3.0 x Rails6.1 x Docker x CentOS Stream
Run Docker environment Rails MySQL on Heroku. devise and hiding the twitter API
How to build an environment of [TypeScript + Vue + Express + MySQL] with Docker ~ Vue edition ~
Build a development environment to create Ruby on Jets + React apps with Docker