프로덕션 배포를 위한 Rails 애플리케이션 도커화
이 튜토리얼은 새로운(또는 기존) Rails 애플리케이션을 고정화하려는 초보자를 위한 것입니다.
ℹ️ You can download all files on my Github repository.
목차
Starting with a basic Rails application
Let's start!
Going production!
Rails 애플리케이션을 도커화하는 이유는 무엇입니까?
Turn you Rails application into docker containers for production deployment can speed up your deployment, prevent errors and make it much easier to move from one service provider to another. It made my life easier (and I bet it can make yours too!).
Once in a container, all dependencies will always be installed and the system already configured to run an optimized version of you application.
It's also easy to update your container, run tests, use CI/CD and automatically deploy new version.
기본 Rails 애플리케이션으로 시작하기
For demonstration purposes, this Rails application is a simple contact list running Rails 6.1. The user can add, view, edit and delete records from the database. All records are saved on a local PostgreSQL instance.
설정
Everything is setup on the local machine. Rails connects to PostgreSQL through port 5432 and serves the application to browsers through port 3000.
이 자습서를 따르기 위해 이미 Rails 애플리케이션이 작동하고 실행 중이라고 가정합니다. 그렇지 않은 경우 테스트에 the tutorial application을 사용할 수 있습니다.
실행 중인 애플리케이션의 스크린샷을 따릅니다.
시작하자!
There are few steps to build a container to run our application.
- Adjust your database connection configuration.
- Write a
dockerfile
and build the container. - Upload your container to any could provider (free and optional).
- Write a Docker Compose file to execute your application on production.
config/database.yml 파일
This is the basic Rails configuration to connect the application to the datbase. It assumes there's a local instance of PostgreSQL running with username and password configured as below.
default: &default
adapter: postgresql
port: 5432
pool: 5
timeout: 5000
host: localhost
username: postgres
password: postgres
development:
<<: *default
database: devel_db
test:
<<: *default
database: test_db
production:
<<: *default
database: production_db
As you can see, all database connection configuration is fixed to the current environment. This can work for local environments, but as a good practice we should change them to environment variables, so we can adjust easily for any new environment we publish our app.
Let's change host
, username
and password
for now. The others settings can also be changed, but I don't want this tutorial to be too complex 😉
host: <%= ENV['DB_HOST'] || 'localhost' %>
username: <%= ENV['DB_USERNAME'] || 'postgres' %>
password: <%= ENV['DB_PASSWORD'] || 'postgres' %>
⚠️ Notice that we set default values for everything.
도커파일
The next step is create a file called Dockerfile
on the root path of your application. This file will instruct docker on how to build the application based on a image you choose.
I decided to use the image ruby:2.7.6-bullseye
because it's based on Debian 11 (Bullseye) and I like (and I'm used to) this distribuition.
FROM ruby:2.7.6
# Directory where the app will be installed on the container
WORKDIR /app
# Install NodeJS 14 repository
RUN curl -fsSL https://deb.nodesource.com/setup_14.x | bash -
# Update the system and install NodeJS
RUN apt-get update && apt-get -y install \
nodejs \
vim \
&& rm -rf /var/lib/apt/lists/*
# Install ruby gems
COPY Gemfile Gemfile.lock ./
RUN bundle install
# Install Yarn globally
RUN npm install -g yarn
# Run `yarn install`
COPY package.json yarn.lock ./
RUN yarn install
# Copy the application file to the container
COPY . .
# Pre-compile assets for production
RUN RAILS_ENV=production bundle exec rails assets:precompile
# Sets the default command that will run when the container starts
CMD ["bundle", "exec", "rails", "server", "-b", "0.0.0.0"]
ℹ️ More information of
Dockerfile
can be found on this link.
.dockerignore 파일
There are files and folders that we do not want to be copied to our docker container because they are not relevant to the application or they will be generated when the container is created. They are build folders, temporary files, log, etc.
Create a .dockerignore
file on your project root folder and add these lines:
node_modules/
log/
tmp/
컨테이너 빌드
Now it's time to build our application container.
⚠️ IMPORTANT: The
tag
attribute is the name of the container. Be sure to change it to your Doker Hub repository name, or use any name if you do not intent to push it to a cloud.
docker build . --tag fshayani/dockerizing_rails_application:latest
After the container is built successfully, we will upload it to Docker Hub. This way I can download it automatically on my production server.
ℹ️ This is a optional step. You can skip this step if you intent to build the container and use it on the same machine.
docker push fshayani/dockerizing_rails_application:latest
제작 들어갑니다!
Now that we have built our app container (and maybe pushed it to a cloud; did you?), it's time to move to the production server and deploy that application!
We need tell Docker how to pull and start the container and this can be done easly with docker compose
.
ℹ️ There are others technologies to deploy containers in production instead of Docker Compose, like Kubernetes, Docker Swarm, AWS ECS, etc; but that's not the scope of this tutorial.
Docker Compose 파일
Create a docker-compose.yml
file on production server. It can be placed anywhere, but be organized! 😉
services:
app: # That's the name of our application container
image: fshayani/dockerizing_rails_application:latest # The container Docker will use
ports:
- 3000:3000 # Map localhost:3000 to the container's port 3000
environment:
- DB_HOST=db # The name of our PostgreSQL container
- DB_USERNAME=postgres # PostgreSQL credentials
- DB_PASSWORD=postgres
- RAILS_ENV=production # We are on Production now!
- RAILS_SERVE_STATIC_FILES=true # Assets were already built by Dockerfile ;)
- RAILS_LOG_TO_STDOUT=true # So we can see Rails logs with `docker compose logs` command
- RAILS_MASTER_KEY=my_ultra_top_secret_master_key!! # Use you master key. There are better ways to keep this secret.
depends_on:
- db # Will start the container `db` before
db:
image: postgres:14
environment:
- POSTGRES_USER=postgres # Will create a instance of PostgreSQL with this credentials
- POSTGRES_PASSWORD=postgres
volumes:
- postgres:/var/lib/postgresql/data # Map PostgreSQL data to a persistant volume called `postgres`
volumes:
postgres: # Create a persistant volume on local machine, so we do not loose our DB on restarts
애플리케이션 시작하기
Now that everything is ready, let's start our application on the production server!
⚠️ ATTENTION: If that's our first time to run the application on the server,
probably your database will be empty. You have two options:dump
andrestore
your database on thedb
container or create a new from scratch running this command first:
docker compose run --rm app bundle exec rails db:setup
docker compose up
ℹ️ TIP: Add the flag
-d
to the command to run it on the background.
Rails 콘솔에 액세스
With Docker Compose, we can interact with our container and run any command on it (including bash
if necessary).
docker compose exec app bundle exec rails console
컨테이너 업데이트
When you make a new version of your application and want to deploy it to the production, all you need to do is:
- Build the new image.
- Push it to the cloud again.
- Pull it on the production server the production server (
docker compose pull
). - Rebuild your docker compose stack (
docker compose down; docker compose up
).
웹 서버 구성
Now that you application is deployed on the production server, you will have to configure any web server (Apache, Nginx, etc) to reverse proxy any calls to your domain to the port 3000 on localhost
.
That's a topic for another post ;)
마지막 팁!
There a application called Watchtower Docker 허브에 업로드하는 새 컨테이너를 자동으로 가져오고 자동으로 가져와 도커를 다시 빌드할 수 있습니다. 스택을 구성합니다. 한번 보세요 ;)Reference
이 문제에 관하여(프로덕션 배포를 위한 Rails 애플리케이션 도커화), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/shayani/dockerizing-a-rails-application-for-production-deployment-2elc텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)