Dockerize rails app using Docker and Docker compose
Bài đăng này đã không được cập nhật trong 5 năm
Chào các bạn, như tiêu đề thì bài viết này mình sẽ trình bày cách đóng gói một ứng dụng Rails sử dụng Docker and Docker Compose.
Bài viết này gồm các nội dung chính sau:
- Docker là gì
- Dockerize Rails app
- Docker Compose là gì
- Docker Compose a Rails app
1. Docker là gì
Như mình tìm hiểu thì Docker được định nghĩa như sau:
Docker là một công cụ được thiết kế để giúp cho việc khởi tạo, deploy, và chạy các ứng dụng được dễ dàng hơn thông qua việc sử dụng containers.
Container cho phép lập trình viên có thể đóng gói một ứng dụng với tất cả các thành phần cần thiết của ứng dụng, bao gồm cả các libraries, dependencies ... nói chung là toàn bộ những thứ cần thiết để ứng dụng có thể chạy được.
Bằng cách đóng gói ứng dụng trong container thì việc chạy ứng dụng sẽ dễ dàng hơn vì không phải bận tâm về sự khác nhau về môi trường local của mỗi lập trình viên.
Docker có thể giống với một máy ảo virtual machine, nhưng cụ thể hơn thì nó lại không phải là một virtual machine. Thay vì tạo ra toàn bộ một hệ điều hành ảo, docker cho phép ứng dụng sử dụng chung một nhân Linux với máy tính mà chúng ta đang chạy. Điều này giúp tăng đáng kể hiệu suất cũng như giảm thiểu kích thước của ứng dụng.
Và điều quan trọng là Docker là dự án open source, vì vậy ai cũng có thể đóng góp cải thiện Docker cũng như có thể tùy biến để phù hợp cho mục đích sử dụng của họ.
Docker image
Docker image là một file, sử dụng để execute code trong một docker container.
Dockerfile
Docker image có thể được build từ một file text chứa cấu hình cũng như những câu lệnh cần thiết để build nên image. Nó là một tập hợp các câu lệnh sẽ chạy trong quá trình build image, các cấu hình cho image này, một hàng trong file sẽ là một câu lệnh hoặc một cấu hình cho việc build image.
Các bạn có thể cài đặt docker qua hướng dẫn ở đây: link
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt-get update
apt-cache policy docker-ce
sudo apt-get install -y docker-ce
sudo systemctl start docker
Đến đây mình sẽ trình bày cách để đóng gói một ứng dụng Rails sử dụng Docker.
Để có thể dockerize một ứng dụng, đầu tiên chúng ta cần một file Dockerfile, chúng ta build một image từ Dockerfile đó, sau đó chạy image đó trong một container .
Đầu tiên là Dockerfile:
FROM ruby:2.5.3
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
ENV RAILS_ENV='development'
ENV RAKE_ENV='development'
COPY . /usr/src/app
RUN bundle install
CMD ["rails", "s"]
EXPOSE 3000
Ở Dockerfile dành cho ứng dụng rails, mình cần một image cơ bản từ Dockerhub Bạn cần tìm kiếm cho mình một image cơ bản phù hợp ở dockerhub, bạn có thể tìm kiếm với từ khóa như rails hoặc ruby, sẽ có nhiều hướng dẫn để viết một file Dockerfile phù hợp.
FROM ruby:2.5.3
Dòng này thực hiện pull image ruby:2.5.3 từ dockerhub về, nó sẽ chứa những thứ cần thiết như các thư viện lõi cho một ứng dụng ruby.
Nếu trên host có image thì nó sẽ sử dụng image trên host hiện tại, ví dụ FROM my_image
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs
Tác dụng: Chạy những command trong quá trình build, ở đây mình cần cài đặt một vài thiết lập môi trường cần thiết
RUN mkdir -p /usr/src/app
Và tạo một thư mục cho riêng app sẽ chạy, và khai báo thư mục này vào WORKDIR
ENV RAILS_ENV='development'
ENV là nơi khai báo các biến môi trường cho ứng dụng.
COPY . /usr/src/app
Câu này sẽ copy toàn bộ code vào thư mục /usr/src/app
của image
Chừng đó là chúng ta có toàn bộ code của ứng dụng rails trong image. Tiếp theo sẽ build app rails thông qua các command cần thiết.
RUN bundle install
Chạy main process
CMD ["rails", "s"]
Và expose sẽ xác định cổng giao tiếp với container
EXPOSE 3000
2. Dockerize Rails app
Như vậy chúng ta đã có một Dockerfile, tiếp theo cần build image, chạy lệnh theo format sau để build image:
docker build [OPTIONS] PATH | URL | -
run
docker build -t notification-api:dev .
Bao giờ thấy thông báo như sau là bạn đã build thành công.
Successfully built dab0ce26ab25
Successfully tagged notification-api:dev
Kiểm tra images hiện có bằng lệnh docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
notification-api dev dab0ce26ab25 16 minutes ago 1.02GB
<none> <none> ca174f7482f3 25 minutes ago 1.02GB
<none> <none> fd44886b3688 49 minutes ago 1.02GB
<none> <none> 66023411bea2 13 days ago 1.02GB
<none> <none> af255225455c 13 days ago 1.02GB
notification-app dev 22a7b7055719 2 weeks ago 1.3GB
mysql 5.7 f6509bac4980 3 weeks ago 373MB
mysql dev f6509bac4980 3 weeks ago 373MB
mysql latest f6509bac4980 3 weeks ago 373MB
mysql <none> 2151acc12881 3 weeks ago 445MB
node 6 ab290b853066 3 months ago 884MB
ruby 2.5.3 72aaaee1eea4 5 months ago 873MB
Như vậy chúng ta đã build thành công, chạy lệnh sau để chạy image này trong một container.
docker run -d --name notification-api -p 3000:3000 notification-api:dev
Kiểm tra các container đang chạy bằng lệnh docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
584e052335e7 notification-api:dev "rails s" 17 minutes ago Up 17 minutes 0.0.0.0:3000->3000/tcp notification-api
Nếu status là up tức là container đã chạy bình thường và chúng ta có thể sử dụng app như bình thường thông qua localhost:3000. tuy nhiên đến đây vẫn còn thiếu config db để app có thể sử dụng được, các bạn hãy đọc tiếp phần dưới nhé.
3. Docker compose là gì
Như định nghĩa mình tìm hiểu được ở document của docker thì Docker compose được định nghĩa như sau:
Docker compose là một công cụ để định nghĩa và khởi chạy multiple docker containers.
Trường hợp chúng ta có một số lượng containers cần chạy cho một ứng dụng, docker compose là công cụ tuyệt vời để chạy và quản lý chúng.
Docker compose được định nghĩa và cấu hình thông qua file docker-compose.yml
, chúng ta sẽ cấu hình thông qua file này.
Bạn có thể cài đặt Docker Compose qua link này: link
sudo curl -L https://github.com/docker/compose/releases/download/1.18.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker-compose --version
Kiểm tra docker status bằng lệnh sau
4. Docker compose a rails app and mysql
Để chạy rails app sẽ cần có database nên cần có image cho db, ở đây mình sẽ dùng mysql. Trước tiên cần tạo một image cho mysql
File Dockerfile này mình sẽ để ở thư mục riêng nhé, mục đích để build riêng một image mysql, bạn cũng có thể dùng image khác mà không cần build riêng.
FROM mysql:5.7
run docker build -t mysql:dev .
Kiểm tra image bằng lệnh docker images
Nội dung file docker-compose.yml
version: "3"
services:
db:
image: "mysql:dev"
restart: unless-stopped
ports:
- "330:3306"
environment:
MYSQL_PASSWORD: 'toor'
MYSQL_ROOT_PASSWORD: 'toor'
volumes:
- /var/lib/mysql57-data:/var/lib/mysql
api:
image: notification-api:dev
command: bash -c "bundle install && rake db:create db:migrate && bundle exec rails s -p 3000 -b '0.0.0.0'"
volumes:
- .:/usr/src/app
ports:
- "3000:3000"
depends_on:
- db
File này dùng cú pháp của file yaml khá quen thuộc:
- Dòng đầu tiên là khai báo version
- Các scope tiếp theo theo thứ tự là services -> <service_name> -> các config cho container
image:
khai báo tên imageport:
khai báo port (<port host>:<port container>
)environment:
để khai báo biến môi trườngvolumes:
khai báo vùng nhớ cho container, mount vùng nhớ cho container để sau khi dừng container sẽ không bị mất data.
Cấu hình cho file config/database.yml
sử dụng host db là service đã khai báo trong docker-compose.yml
host: db
Cuối chạy lệnh
docker-compose up
Nếu thấy thông báo api_1 | * Listening on tcp://0.0.0.0:3000
tức là app đã được chạy, bây giờ chúng ta có thể truy cập app qua localhost:3000
Như vậy mình vừa trình bày các bước để dockerrize rails app bằng Docker và Docker compose.
Cảm ơn mọi người đã theo dõi bài viết, nếu có thắc mắc gì hãy comment phía dưới để cùng giải đáp nhé.
All rights reserved