[Docker Compose] Build ứng dụng Rails, PostgreSQL một cách đơn giản nhất
Bài đăng này đã không được cập nhật trong 7 năm
Lời mở đầu
Mình là một lập trình viên và mình chưa từng viết một dòng code ruby nào, chưa có build ứng dụng ruby on rails bao giờ, và rồi một ngày đẹp trời mình nhận được một nhiệm vụ dường như rất đơn giản đó là chạy một ứng dụng ruby on rails kết nối với hệ quản trị cơ sở dữ liệu PostgreSQL trên môi trường máy local của mình. Có thể với những bạn đang là dev ruby thì việc này sẽ hoàn thành chỉ trong một nốt nhạc, thế nhưng với mình lại khác, một loạt câu hỏi mình đã đặt ra:
- Cần cài đặt những gì?
- Chạy những precommands nào?
- Start server như thế nào?
- Mình còn chưa dùng thằng PostgreSQL trên môi trường local bao giờ thì làm sao nhỉ :-?
Vậy mục đích bài viết này của mình là để chỉ ra cho bạn từ một lập trình viên không biết gì về ruby có thể tạo môi trường phát triển cho ứng dụng ruby rails ngay trên máy tính của bạn một cách đơn giản.
Giải pháp
Mình hướng tới là build ứng dụng chứ không phải phát triển ứng dụng rails do đó giải pháp mình chọn đó là sử dụng docker một cách đơn giản để tạo môi trường develop cũng như testing. Một số khái niệm cần biết về docker bạn có thể tham khảo bài viết trước của mình Docker với lập trình viên web
Yêu cầu
- Cài đặt docker và docker-compose trên máy của bạn
- Bài hướng dẫn của mình được thực hiện trên hệ điều hành ubuntu 16.04
Thực hiện
Đưa thư mục làm việc về rails project
- Sau khi đã cài đặt xong docker và docker-compose trên máy thì việc đầu tiên mình cần thực hiện đó là download project rails về máy của mình. Bạn có thể tham khảo một sample app có sẵn trên git-hub.
Định nghĩa Dockerfile
-
Đi tới đường dẫn thư mục project đã clone tạo Dockerfile với nội dung như sau
FROM ruby:2.3.1 RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs RUN mkdir /myapp WORKDIR /myapp ADD Gemfile /myapp/Gemfile ADD Gemfile.lock /myapp/Gemfile.lock RUN bundle install ADD . /myapp
Chú thích Dockerfile:
Phiên bản ruby:2.3.1 thì bạn có thể tùy chỉnh phiên bản sao cho phù hợp với project mà bạn đang muốn build
Update apt packages và cài đặt các một số additional requirements cho Rails
Để code project của mình có thể chạy được bên trong container mình sẽ tạo sẵn thư mục myapp
để copy code bên ngoài máy host của mình vào trong container.
Chọn đường dẫn làm việc hiện tại sẽ là trong myapp
Copy Gemfile và Gemfile.lock
Bundle install để cài đặt các gói dependency cần thiết cho project
Copy toàn bộ source code vào /myapp
Pull Postgres image
Nếu chỉ dừng lại ở đây thì ứng dụng của mình sẽ chỉ chạy nếu như nó không có sử dụng kết nối tới tớ cơ sở dữ liệu. Tuy nhiên ứng dụng như mình đề cập có sử dụng kết nối với database là PostgreSQL do đó mình cần một image PostgreSQL và sẽ sử dụng Docker-compose kết nối mọi thứ với nhau.
- Pull Postgre image từ trên cộng đồng docker-hub, vẫn lựa chọn phiên bản phù hợp sau dấu
:
. Ví dụ mình sẽ sử dụng phiên bản postgreSQL 9.4$ docker pull postgres:9.4
Định nghĩa file docker-compose.yml
- Tại thư mục làm việc trong ứng dụng của bạn, cùng với Dockerfile tạo file docker-compose.yml với nội dung như sau ( Ở đây mình vẫn sử dụng docker-compose version 2, hiện tại đã có version 3 nếu như bạn muốn tìm hiểu thêm)
version: '2' services: db: image: postgres:9.4 environment: POSTGRES_USER: pguser POSTGRES_PASSWORD: password POSTGRES_DB: myapp web: build: . command: bundle exec rails s -p 3000 -b '0.0.0.0' volumes: - .:/myapp ports: - "3000:3000" links: - db
Một lợi ích nữa của việc sử dụng docker-compose đó là mình sẽ không cần nhớ câu lệnh để start, stop server ứng dụng rails là gì, mình chỉ cần biết tới nó một lần và định nghĩa ngay trong file docker-compose.yml
Bạn sẽ đặt ra một câu hỏi đó là tại sao trong Dockerfile đã add source code vào trong image rồi mà trong docker-compose.yml cần khai báo mount thư mục source code ở máy host của mình vào nữa?. Lý do ở đây đó chính là nếu mình chạy docker buil .
thì nó sẽ được thực hiện tại thời gian build time
còn docker-compose sẽ làm việc trong suốt quá trình run time
để đảm bảo rằng bạn có thay đổi code trên máy host thì sẽ không cần khởi động lại container, mà code mới và kết quả nó trả về sẽ luôn được cập nhật.
Các khai báo bên trong docker-compose file của mình đều rất cơ bản và mình đã giới thiệu từ những bài post trước về docker của mình nên mình sẽ không nói lại ở đây nữa.
Như vậy mình đã có một bản thiết kế đầy đủ cho images gồm những gì, container sau khi được tạo ra sẽ như thế nào.
Config ứng dụng để kết nối database
Trong file config/database.yml
default: &default
adapter: postgres
encoding: utf8
pool: 5
username: pguser
password: password
host: db
development:
<<: *default
database: myapp
username và password của db thì mình sẽ follow theo khởi tạo trong docker-compose file.
Kiểm tra lại trước khi khởi chạy
- Mình có thể gặp phải lỗi ngay ở lần chạy ứng dụng đầu tiên có thể vì lí do xung đột cổng. Giả sử ở đây mình đang expose ra web cổng 3000 do đó để access thì bạn cần kiểm tra rằng trên máy của bạn cổng 3000 có đang bị thằng nào sử dụng không, nếu có thì mình có thể sửa lại chút trong docker-compose.yml là sẽ expose ra một cổng khác.
Để kiểm tra những cổng nào đang được sử dụng thì có thể dùng lệnh sau:
$ netstat -ntlp
Khởi chạy
Chạy docker-compose
$ docker-compose up
Tạo dữ liệu ban đầu
Do database đã được khởi tạo khi mình stat docker-compose do đó mình chỉ cần migrate data.
$ docker-compose exec web bundle exec rake db:migrate
Câu lệnh trên sẽ được thực hiện trong container có chứa service web.
Nếu project của bạn có tạo seef file cho database thì chạy lệnh
$ docker-compose exec web bundle exec rake db:seed
Đó là các bước đủ để mình build một ứng dụng rails, giờ việc còn lại là kiểm tra kết quả tại địa chỉ localhost:3000
Start/Stop container
Bạn có thể start/stop service tùy vào mục đích sử dụng Mỗi lần như vậy chỉ cần vào đường dẫn trong mục project (cùng đường dẫn với docker-compose.yml) ` #stop $ docker-compose stop
#start docker-compose start `
Tham khảo
Kết luận
- Qua bài viết mong là đã giúp ích được cho bạn trong việc buil một ứng dụng rails cũng như tìm hiểu về Docker.
- Cảm ơn bạn đã dành thời gian đọc bài chia sẻ của mình!
All rights reserved