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).
The configuration is above. Deploy nginx as a web server. The app server installs puma.
Account created on AWS Account created on docker hub docker installed Rails app running in a local environment
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
** 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
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
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
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