![Search icon](https://hackernoon.imgix.net/search-new.png?w=19&h=19)
Việc Docker hóa Ruby on Rails của bạn bằng ứng dụng giao diện người dùng React có thể cải thiện đáng kể quy trình phát triển và quy trình triển khai của bạn. Bằng cách tạo môi trường tiêu chuẩn hóa cho ứng dụng của mình, bạn đảm bảo hành vi nhất quán trong các giai đoạn phát triển, thử nghiệm, sản xuất khác nhau và thậm chí trên các hệ thống khác nhau. Trên thực tế, nó được thiết kế để giảm thiểu các vấn đề liên quan đến sự khác biệt của hệ thống. Hướng dẫn này sẽ hướng dẫn bạn các bước cần thiết để giúp ứng dụng Rails và React của bạn chạy trơn tru trong vùng chứa Docker.
Docker đảm bảo rằng ứng dụng chạy theo cùng một cách bất kể nó được triển khai ở đâu, cho dù trên máy của nhà phát triển, môi trường thử nghiệm hay máy chủ sản xuất. Tính nhất quán này đạt được bằng cách chứa tất cả các phụ thuộc và cấu hình.
Bộ chứa Docker bao gồm tất cả các phần phụ thuộc cần thiết để ứng dụng chạy. Điều này có nghĩa là các biến thể trong thư viện hệ thống hoặc các phần phụ thuộc bị thiếu trên các hệ thống khác nhau không ảnh hưởng đến chức năng của ứng dụng.
Các container Docker chạy độc lập với nhau và với hệ thống máy chủ. Sự cô lập này ngăn ngừa xung đột giữa các ứng dụng khác nhau và sự phụ thuộc của chúng trên cùng một hệ thống.
Lưu ý: Cần có kiến thức về cú pháp Docker
Dockerization liên quan đến hai khái niệm chính: hình ảnh và vùng chứa. Hình ảnh đóng vai trò là bản thiết kế cho vùng chứa, chứa tất cả thông tin cần thiết để tạo vùng chứa, bao gồm cả các phần phụ thuộc và cấu hình triển khai. Vùng chứa là một phiên bản thời gian chạy của một hình ảnh, bao gồm chính hình ảnh đó, môi trường thực thi và các hướng dẫn thời gian chạy. Docker nói chung thiết lập một tiêu chuẩn cho phần mềm vận chuyển.
Để giải thích Docker bằng một phép tương tự đơn giản: hãy coi container là các container vận chuyển trong bãi, hình ảnh là các vật phẩm được đặt bên trong các container này và tàu vận chuyển là hệ thống mà các container chạy trên đó.
Bất cứ khi nào bạn thiết lập và xây dựng ứng dụng của mình, cần phải có một số cấu hình môi trường nhất định. Ví dụ: bạn không thể chạy ứng dụng Rails nếu không cài đặt môi trường Ruby trên hệ thống của mình. Tương tự, bạn không thể chạy ứng dụng React mà không có Node.js
và bạn không thể cài đặt các gói React mà không có trình quản lý gói Node như npm
hoặc Yarn
, v.v.
Vì vùng chứa chạy tách biệt với hệ thống của người dùng nên chúng tôi sẽ cung cấp tất cả các gói này trong vùng chứa của mình giống như chúng tôi đã làm trong trường hợp chúng tôi xây dựng nó trực tiếp trên hệ thống của mình, do đó, vùng chứa sẽ hoạt động như một hệ thống trên đó sở hữu, giống như một máy ảo. Có sự khác biệt giữa docker và máy ảo nhưng ví dụ này chỉ nhằm giải thích thêm.
Bây giờ, hãy tiếp tục và neo ứng dụng Rails. Để thực hiện việc này, chúng ta sẽ cần ba tệp trong ứng dụng Rails của mình: Dockerfile
, docker-compose.yml
và bin/docker-entrypoint
. Chúng ta hãy xem xét chi tiết từng tập tin này.
Lưu ý: Cần có kiến thức về cú pháp Docker
Dockerfile
là bản thiết kế chi tiết để tạo vùng chứa Docker. Nó chứa một loạt hướng dẫn mà Docker sử dụng để xây dựng một image, sau đó có thể được sử dụng để chạy các container. Hãy chia nhỏ Dockerfile
cho ứng dụng Ruby on Rails và React:
ARG RUBY_VERSION=3.1.4 FROM ruby:$RUBY_VERSION
ARG RUBY_VERSION=3.1.4
: Xác định đối số bản dựng có tên RUBY_VERSION
với giá trị mặc định là 3.1.4
. Điều này có thể được ghi đè tại thời điểm xây dựng.
FROM ruby:$RUBY_VERSION
: Sử dụng hình ảnh cơ sở ruby
với phiên bản được chỉ định bởi RUBY_VERSION
. Điều này sẽ thiết lập vùng chứa với thời gian chạy Ruby. Giống như tôi đã đề cập trước đó, để chạy ứng dụng Rails, bạn cần cài đặt Ruby. RUN apt-get update -qq && \ apt-get install -y build-essential libvips bash bash-completion libffi-dev tzdata postgresql curl && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* /usr/share/doc /usr/share/man
apt-get update -qq
: Cập nhật danh sách gói từ kho lưu trữ, với -qq
cho đầu ra yên tĩnh.
apt-get install -y
... : Cài đặt các gói khác nhau: build-essential
: Các gói cần thiết để xây dựng phần mềm (như GCC).
libvips
: Thư viện xử lý ảnh.
bash
, bash-completion
: Bash shell và tính năng tự động hoàn thành của nó.
libffi-dev
: Thư viện Giao diện chức năng nước ngoài.
tzdata
: Dữ liệu múi giờ.
postgresql
: Máy khách cơ sở dữ liệu PostgreSQL.
curl
: Công cụ chuyển dữ liệu từ URL.
apt-get clean
: Dọn dẹp kho lưu trữ cục bộ của các tệp gói được truy xuất.
rm -rf /var/lib/apt/lists/ /usr/share/doc /usr/share/man
: Xóa danh sách gói và tài liệu để giảm kích thước hình ảnh. RUN curl -fsSL https://deb.nodesource.com/setup_current.x | bash - && \ apt-get install -y nodejs && \ curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \ echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \ apt-get update && \ apt-get install -y yarn
curl -fsSL https://deb.nodesource.com/setup_current.x | bash -
: Tải xuống và chạy tập lệnh thiết lập NodeSource để cài đặt Node.js.
apt-get install -y nodejs
: Cài đặt Node.js.
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
: Thêm khóa GPG Sợi để xác minh các gói của nó.
echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
: Thêm kho lưu trữ của Yarn vào danh sách các nguồn.
apt-get update && apt-get install -y yarn
: Cập nhật danh sách gói và cài đặt Yarn. ENV NODE_OPTIONS=--openssl-legacy-provider
ENV NODE_OPTIONS=--openssl-legacy-provider
: Đặt biến môi trường để bật hỗ trợ OpenSSL kế thừa cho Node.js. WORKDIR /rails
WORKDIR /rails
: Đặt thư mục làm việc cho các hướng dẫn tiếp theo thành /rails
. ARG RAILS_ENV ENV RAILS_ENV=$RAILS_ENV
ARG RAILS_ENV
: Xác định đối số xây dựng có tên RAILS_ENV
để chỉ định môi trường Rails (như development
, test
, production
).
ENV RAILS_ENV=$RAILS_ENV
: Đặt biến môi trường RAILS_ENV
thành giá trị của đối số bản dựng. COPY Gemfile Gemfile.lock ./ RUN bundle install
COPY Gemfile Gemfile.lock ./
: Sao chép Gemfile
và Gemfile.lock
vào thư mục làm việc.
RUN bundle install
: Cài đặt đá quý Ruby được chỉ định trong Gemfile
. COPY package.json yarn.lock ./ RUN yarn install --frozen-lockfile
COPY package.json yarn.lock ./
: Sao chép package.json
và yarn.lock
vào thư mục làm việc.
RUN yarn install --frozen-lockfile
: Cài đặt các phần phụ thuộc giao diện người dùng bằng Sợi, đảm bảo nó sử dụng các phiên bản chính xác trong yarn.lock
. COPY . .
COPY . .
: Sao chép tất cả mã ứng dụng vào thư mục làm việc. RUN bundle exec bootsnap precompile --gemfile app/ lib/
RUN bundle exec bootsnap precompile --gemfile app/ lib/
: Biên dịch trước bộ đệm Bootsnap để có thời gian khởi động ứng dụng Rails nhanh hơn. Bootsnap là một gem giúp tăng tốc thời gian khởi động Ruby và Rails bằng cách lưu vào bộ nhớ đệm các phép tính đắt tiền. RUN if [ "$RAILS_ENV" = "production" ]; then \ SECRET_KEY_BASE=1 bin/rails assets:precompile; \ fi
RUN if [ "$RAILS_ENV" = "production" ]; then
... : Chỉ chạy quá trình biên dịch trước nội dung có điều kiện nếu RAILS_ENV
được đặt thành production
. Bước này rất quan trọng để chuẩn bị tài sản cho môi trường sản xuất. COPY bin/docker-entrypoint /rails/bin/ RUN chmod +x /rails/bin/docker-entrypoint
COPY bin/docker-entrypoint /rails/bin/
: Sao chép tập lệnh điểm nhập tùy chỉnh vào vùng chứa.
RUN chmod +x /rails/bin/docker-entrypoint
: Làm cho tập lệnh điểm vào có thể thực thi được. ENTRYPOINT ["/rails/bin/docker-entrypoint"] EXPOSE 5000 // you can use any port of your choice CMD ["./bin/rails", "server"]
ENTRYPOINT ["/rails/bin/docker-entrypoint"]
: Đặt tập lệnh điểm nhập sẽ chạy khi vùng chứa khởi động. Tập lệnh này thường thiết lập môi trường, chuẩn bị cơ sở dữ liệu và khởi động ứng dụng.
EXPOSE 5000
: Cho biết container lắng nghe trên cổng 5000. Đây là một tính năng tài liệu và không xuất bản cổng.
CMD ["./bin/rails", "server"]
: Chỉ định lệnh mặc định sẽ chạy khi container khởi động, tức là khởi động máy chủ Rails. Tệp docker-compose.yml
được sử dụng để xác định và chạy các ứng dụng Docker nhiều vùng chứa. Nó cho phép bạn định cấu hình các dịch vụ, mạng và ổ đĩa của ứng dụng trong một tệp duy nhất. Trong trường hợp này, chúng tôi sẽ sử dụng hai dịch vụ. Đây là tệp docker-compose.yml
cho ứng dụng Rails:
db
) codedb: image: postgres:14.2-alpine container_name: demo-postgres-14.2 volumes: - postgres_data:/var/lib/postgresql/data command: "postgres -c 'max_connections=500'" environment: POSTGRES_DB: ${POSTGRES_DB} POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} ports: - "5432:5432"
image: postgres:14.2-alpine
: Chỉ định hình ảnh Docker để sử dụng cho dịch vụ này. Trong trường hợp này, đó là hình ảnh PostgreSQL 14.2 dựa trên bản phân phối Alpine Linux. Hình ảnh Alpine được biết đến với kích thước nhỏ, có thể giúp giảm kích thước hình ảnh tổng thể.
container_name: demo-postgres-14.2
: Đặt tên cho vùng chứa demo-postgres-14.2
. Tên này được sử dụng để tham chiếu vùng chứa trong lệnh và nhật ký.
volumes
: postgres_data:/var/lib/postgresql/data:
Gắn một tập được đặt tên postgres_data
vào /var/lib/postgresql/data
bên trong vùng chứa. Thư mục này là nơi PostgreSQL lưu trữ dữ liệu của nó, đảm bảo rằng dữ liệu cơ sở dữ liệu vẫn tồn tại giữa các lần khởi động lại vùng chứa.
command: "postgres -c 'max_connections=500'"
: Ghi đè lệnh mặc định của hình ảnh PostgreSQL. Nó khởi động PostgreSQL với tùy chọn cấu hình để tăng số lượng kết nối tối đa lên 500.
environment
: POSTGRES_DB: ${POSTGRES_DB}
: Đặt tên của cơ sở dữ liệu mặc định để tạo, sử dụng biến môi trường POSTGRES_DB
.
POSTGRES_USER: ${POSTGRES_USER}
: Đặt tên người dùng mặc định để truy cập cơ sở dữ liệu PostgreSQL, sử dụng biến môi trường POSTGRES_USER
.
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
: Đặt mật khẩu cho người dùng mặc định, sử dụng biến môi trường POSTGRES_PASSWORD
.
ports
:"5432:5432"
: Ánh xạ cổng 5432 trên máy chủ tới cổng 5432 trong vùng chứa. Điều này cho phép truy cập vào PostgreSQL trên máy chủ qua cổng 5432.demo-web
) codedemo-web: build: context: . args: - RAILS_ENV=${RAILS_ENV} command: "./bin/rails server -b 0.0.0.0" environment: - RAILS_ENV=${RAILS_ENV} - POSTGRES_HOST=${POSTGRES_HOST} - POSTGRES_DB=${POSTGRES_DB} - POSTGRES_USER=${POSTGRES_USER} - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} - RAILS_MASTER_KEY=${RAILS_MASTER_KEY} volumes: - .:/rails - app-storage:/rails/storage depends_on: - db ports: - "3000:3000"
build:
context: .
: Chỉ định bối cảnh xây dựng cho hình ảnh Docker. Trong trường hợp này, .
đề cập đến thư mục hiện tại. Điều này có nghĩa là Docker sẽ sử dụng Dockerfile trong thư mục hiện tại để xây dựng image.args
: RAILS_ENV=${RAILS_ENV}
: Truyền đối số xây dựng RAILS_ENV
cho quy trình xây dựng Docker, cho phép bạn chỉ định môi trường Rails (như development
, test
hoặc production
).
command: "./bin/rails server -b 0.0.0.0"
: Ghi đè lệnh mặc định của hình ảnh Docker. Khởi động máy chủ Rails và liên kết nó với tất cả các giao diện mạng ( 0.0.0.0
), điều này cần thiết để dịch vụ có thể truy cập được từ bên ngoài vùng chứa.
environment:
RAILS_ENV=${RAILS_ENV}
: Đặt môi trường Rails bên trong vùng chứa bằng biến môi trường RAILS_ENV
.
POSTGRES_HOST=${POSTGRES_HOST}
: Đặt địa chỉ máy chủ PostgreSQL.
POSTGRES_DB=${POSTGRES_DB}
: Đặt tên cơ sở dữ liệu.
POSTGRES_USER=${POSTGRES_USER}
: Đặt người dùng PostgreSQL.
POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
: Đặt mật khẩu người dùng PostgreSQL.
RAILS_MASTER_KEY=${RAILS_MASTER_KEY}
: Đặt khóa chính Rails, được sử dụng để mã hóa thông tin xác thực và các bí mật khác.
volumes
:
.:/rails
: Gắn thư mục hiện tại (nơi chứa tệp docker-compose.yml
) vào /rails
bên trong vùng chứa. Điều này cho phép bạn chỉnh sửa các tệp trên máy chủ của mình và phản ánh những thay đổi đó bên trong vùng chứa.
app-storage:/rails/storage
: Gắn một khối lượng được đặt tên app-storage
vào /rails/storage
bên trong vùng chứa. Điều này thường được sử dụng để lưu trữ các tệp dành riêng cho Rails như nhật ký, tải lên và tệp được lưu trong bộ nhớ cache.
depends_on
:
db
: Đảm bảo rằng dịch vụ demo-web
đợi dịch vụ db
sẵn sàng trước khi bắt đầu. Docker Compose xử lý thứ tự bắt đầu dịch vụ dựa trên cài đặt này. ports:
"3000:3000"
: Ánh xạ cổng 3000 trên máy chủ tới cổng 3000 trong vùng chứa. Điều này cho phép bạn truy cập ứng dụng Rails trên máy chủ qua cổng 3000. codevolumes: postgres_data: app-storage:
postgres_data
: Xác định một tập được đặt tên postgres_data
được dịch vụ db
sử dụng để duy trì dữ liệu PostgreSQL.app-storage
: Xác định khối lượng app-storage
được đặt tên được sử dụng bởi dịch vụ demo-web
để duy trì dữ liệu dành riêng cho ứng dụng, chẳng hạn như nội dung tải lên và nhật ký. Tập lệnh bin/docker-entrypoint
là một phần quan trọng trong quá trình thiết lập Docker. Nó được thực thi khi vùng chứa khởi động và thường xử lý việc thiết lập môi trường, chuẩn bị cơ sở dữ liệu và các tác vụ khởi tạo khác cần thiết trước khi khởi động ứng dụng chính. Dưới đây là ví dụ về tập lệnh bin/docker-entrypoint
và giải thích chi tiết về từng phần:
bashCopy code#!/bin/bash set -e
#!/bin/bash
: Dòng này chỉ định rằng tập lệnh sẽ được chạy bằng shell Bash.
set -e
: Điều này hướng dẫn tập lệnh thoát ngay lập tức nếu bất kỳ lệnh nào trả về mã thoát khác 0. Điều này giúp đảm bảo rằng nếu bất kỳ bước nào không thành công, tập lệnh sẽ dừng thực thi, điều này có thể ngăn các bước tiếp theo chạy ở trạng thái không hợp lệ.
Tạo hoặc di chuyển cơ sở dữ liệu có điều kiện
# If running the rails server then create or migrate existing database if [ "${*}" == "./bin/rails server" ]; then ./bin/rails db:create ./bin/rails db:prepare fi
"${*}"
) có phải là ./bin/rails server
hay không. *
là một tham số đặc biệt chứa tất cả các tham số vị trí được truyền cho tập lệnh.
./bin/rails db
: Nếu điều kiện được đáp ứng, lệnh này sẽ cố gắng tạo cơ sở dữ liệu. Nó tương đương với việc chạy rails db:create
để thiết lập cơ sở dữ liệu như được xác định trong tệp cấu hình cơ sở dữ liệu ( config/database.yml
).
./bin/rails db
: Lệnh này sẽ chạy rails db:prepare
để đảm bảo cơ sở dữ liệu được thiết lập và di chuyển. Nó sẽ tạo cơ sở dữ liệu nếu nó không tồn tại và chạy di chuyển nếu cơ sở dữ liệu đã được tạo. Đây là sự kết hợp của rails db:create
và rails db:migrate
.
bashCopy codeexec "${@}"
exec "${@}"
: Điều này thay thế quy trình shell hiện tại bằng lệnh được truyền dưới dạng đối số cho tập lệnh. Biểu tượng @
chứa tất cả các tham số vị trí được truyền cho tập lệnh. Ví dụ: nếu tập lệnh được gọi với ./bin/rails server
, dòng này sẽ chạy ./bin/rails server
một cách hiệu quả như quy trình chính của vùng chứa. Dockerfile
được thiết kế tốt là điều cần thiết để tạo ra một môi trường nhất quán và đáng tin cậy cho ứng dụng Ruby on Rails và React của bạn. Bằng cách xác định hình ảnh cơ sở, đặt biến môi trường và cài đặt các phần phụ thuộc, bạn đảm bảo rằng ứng dụng của mình chạy trơn tru trên nhiều môi trường khác nhau.
Docker không chỉ hợp lý hóa quy trình phát triển của bạn mà còn nâng cao độ tin cậy của ứng dụng trong quá trình sản xuất. Có những lĩnh vực tối ưu hóa, nhưng đây chỉ là tổng quan chung về cách neo ứng dụng Rails.
Dockerfile
kết quả, docker-compose.yml
và bin/docker-entrypoint
ARG RUBY_VERSION=3.1.4 FROM ruby:$RUBY_VERSION # Install dependencies RUN apt-get update -qq && \ apt-get install -y build-essential libvips bash bash-completion libffi-dev tzdata postgresql curl && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* /usr/share/doc /usr/share/man # Install Node.js and Yarn RUN curl -fsSL https://deb.nodesource.com/setup_current.x | bash - && \ apt-get install -y nodejs && \ curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \ echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \ apt-get update && \ apt-get install -y yarn # Set environment variable to enable legacy OpenSSL support ENV NODE_OPTIONS=--openssl-legacy-provider # Rails app lives here WORKDIR /rails # Set environment variable for the build ARG RAILS_ENV ENV RAILS_ENV=$RAILS_ENV # Install application gems COPY Gemfile Gemfile.lock ./ RUN bundle install # Install frontend dependencies COPY package.json yarn.lock ./ RUN yarn install --frozen-lockfile # Copy application code COPY . . # Precompile bootsnap code for faster boot times RUN bundle exec bootsnap precompile --gemfile app/ lib/ # Precompiling assets for production without requiring secret RAILS_MASTER_KEY RUN if [ "$RAILS_ENV" = "production" ]; then \ SECRET_KEY_BASE=1 bin/rails assets:precompile; \ fi # Entrypoint prepares the database. COPY bin/docker-entrypoint /rails/bin/ RUN chmod +x /rails/bin/docker-entrypoint # Use an absolute path for the entry point script ENTRYPOINT ["/rails/bin/docker-entrypoint"] # Start the server by default, this can be overwritten at runtime EXPOSE 5000 CMD ["./bin/rails", "server"]
services: db: image: postgres:14.2-alpine container_name: demo-postgres-14.2 volumes: - postgres_data:/var/lib/postgresql/data command: "postgres -c 'max_connections=500'" environment: POSTGRES_DB: ${POSTGRES_DB} POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} ports: - "5432:5432" demo-web: build: context: . args: - RAILS_ENV=${RAILS_ENV} command: "./bin/rails server -b 0.0.0.0" environment: - RAILS_ENV=${RAILS_ENV} - POSTGRES_HOST=${POSTGRES_HOST} - POSTGRES_DB=${POSTGRES_DB} - POSTGRES_USER=${POSTGRES_USER} - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} - RAILS_MASTER_KEY=${RAILS_MASTER_KEY} volumes: - .:/rails - app-storage:/rails/storage depends_on: - db ports: - "3000:3000" volumes: postgres_data: app-storage:
#!/bin/bash set -e # If running the rails server then create or migrate existing database if [ "${*}" == "./bin/rails server" ]; then ./bin/rails db:create ./bin/rails db:prepare fi exec "${@}"