Докеризация вашего Ruby on Rails с помощью внешнего приложения React может значительно улучшить ваш рабочий процесс разработки и процесс развертывания. Создавая стандартизированную среду для своего приложения, вы обеспечиваете единообразное поведение на разных этапах разработки, тестирования, производства и даже в разных системах. Фактически, он предназначен для минимизации проблем, связанных с системными различиями. Это руководство проведет вас через основные шаги, чтобы обеспечить бесперебойную работу вашего приложения Rails и React в контейнерах Docker.
Docker гарантирует, что приложение работает одинаково независимо от того, где оно развернуто: на компьютере разработчика, в среде тестирования или на рабочем сервере. Эта согласованность достигается за счет контейнеризации всех зависимостей и конфигураций.
Контейнеры Docker включают все необходимые зависимости для запуска приложения. Это означает, что вариации в системных библиотеках или отсутствие зависимостей от разных систем не влияют на функциональность приложения.
Контейнеры Docker работают изолированно друг от друга и от хост-системы. Эта изоляция предотвращает конфликты между различными приложениями и их зависимостью от одной системы.
Примечание. Требуется знание синтаксиса Docker.
Докеризация включает в себя две ключевые концепции: образы и контейнеры. Образы служат образцами контейнеров и содержат всю необходимую информацию для создания контейнера, включая зависимости и конфигурации развертывания. Контейнер — это экземпляр образа во время выполнения, включающий само изображение, среду выполнения и инструкции времени выполнения. Docker в целом устанавливает стандарт для поставки программного обеспечения.
Чтобы объяснить Docker простой аналогией: подумайте о контейнерах как о транспортных контейнерах на складе, об изображениях как о предметах, помещенных внутри этих контейнеров, а о транспортном судне как о системе, в которой работают контейнеры.
Всякий раз, когда вы настраиваете и создаете свое приложение, необходимы определенные конфигурации среды. Например, вы не можете запустить приложение Rails без установленной в вашей системе среды Ruby. Аналогично, вы не можете запустить приложение React без Node.js
и не можете установить пакеты React без менеджера пакетов Node, такого как npm
или Yarn
и т. д.
Поскольку контейнер работает изолированно от системы пользователя, мы собираемся сделать все эти пакеты доступными в нашем контейнере так же, как если бы мы собирали его непосредственно в нашей системе, таким образом, контейнер будет действовать в нем как система. собственный, как виртуальная машина. Существуют различия между докером и виртуальной машиной, но этот пример предназначен только для дальнейшего объяснения.
Теперь давайте продолжим и докеризуем приложение Rails. Для этого нам понадобятся три файла в нашем приложении Rails: Dockerfile
, docker-compose.yml
и bin/docker-entrypoint
. Давайте рассмотрим каждый из этих файлов подробно.
Примечание. Требуется знание синтаксиса Docker.
Dockerfile
— это схема создания контейнера Docker. Он содержит ряд инструкций, которые Docker использует для создания образа, который затем можно использовать для запуска контейнеров. Давайте разберем Dockerfile
для приложения Ruby on Rails и React:
ARG RUBY_VERSION=3.1.4 FROM ruby:$RUBY_VERSION
ARG RUBY_VERSION=3.1.4
: определяет аргумент сборки с именем RUBY_VERSION
со значением по умолчанию 3.1.4
. Это можно переопределить во время сборки.
FROM ruby:$RUBY_VERSION
: использует базовый образ ruby
с версией, указанной в RUBY_VERSION
. Это настраивает контейнер со средой выполнения Ruby. Как я уже упоминал ранее, для запуска приложения Rails вам необходимо установить 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
: обновляет список пакетов из репозиториев, используя -qq
для тихого вывода.
apt-get install -y
... : устанавливает различные пакеты: build-essential
: необходимые пакеты для сборки программного обеспечения (например, GCC).
libvips
: библиотека для обработки изображений.
bash
, bash-completion
: оболочка Bash и ее автодополнение.
libffi-dev
: библиотека интерфейса внешних функций.
tzdata
: данные о часовом поясе.
postgresql
: клиент базы данных PostgreSQL.
curl
: инструмент для передачи данных с URL-адресов.
apt-get clean
: очищает локальный репозиторий полученных файлов пакетов.
rm -rf /var/lib/apt/lists/ /usr/share/doc /usr/share/man
: удаляет списки пакетов и документацию, чтобы уменьшить размер образа. 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 -
: загружает и запускает сценарий установки NodeSource для установки Node.js.
apt-get install -y nodejs
: устанавливает Node.js.
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
добавляет ключ Yarn GPG для проверки пакетов.
echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
: добавляет репозиторий Yarn в список источников.
apt-get update && apt-get install -y yarn
: обновляет список пакетов и устанавливает Yarn. ENV NODE_OPTIONS=--openssl-legacy-provider
ENV NODE_OPTIONS=--openssl-legacy-provider
: устанавливает переменную среды для включения устаревшей поддержки OpenSSL для Node.js. WORKDIR /rails
WORKDIR /rails
: устанавливает рабочий каталог для последующих инструкций в /rails
. ARG RAILS_ENV ENV RAILS_ENV=$RAILS_ENV
ARG RAILS_ENV
: определяет аргумент сборки с именем RAILS_ENV
для указания среды Rails (например, development
, test
, production
).
ENV RAILS_ENV=$RAILS_ENV
: устанавливает для переменной среды RAILS_ENV
значение аргумента сборки. COPY Gemfile Gemfile.lock ./ RUN bundle install
COPY Gemfile Gemfile.lock ./
: копирует Gemfile
и Gemfile.lock
в рабочий каталог.
RUN bundle install
: Устанавливает драгоценные камни Ruby, указанные в Gemfile
. COPY package.json yarn.lock ./ RUN yarn install --frozen-lockfile
COPY package.json yarn.lock ./
: копирует package.json
и yarn.lock
в рабочий каталог.
RUN yarn install --frozen-lockfile
: Устанавливает внешние зависимости с помощью Yarn, гарантируя использование точных версий в yarn.lock
. COPY . .
COPY . .
: копирует весь код приложения в рабочий каталог. RUN bundle exec bootsnap precompile --gemfile app/ lib/
RUN bundle exec bootsnap precompile --gemfile app/ lib/
: Предварительно компилирует кэш Bootsnap для ускорения загрузки приложения Rails. Bootsnap — это драгоценный камень, который ускоряет загрузку Ruby и Rails за счет кэширования дорогостоящих вычислений. RUN if [ "$RAILS_ENV" = "production" ]; then \ SECRET_KEY_BASE=1 bin/rails assets:precompile; \ fi
RUN if [ "$RAILS_ENV" = "production" ]; then
... : Условно запускает предварительную компиляцию ресурсов, только если для RAILS_ENV
установлено значение production
. Этот шаг имеет решающее значение для подготовки ресурсов к производственной среде. COPY bin/docker-entrypoint /rails/bin/ RUN chmod +x /rails/bin/docker-entrypoint
COPY bin/docker-entrypoint /rails/bin/
: копирует сценарий пользовательской точки входа в контейнер.
RUN chmod +x /rails/bin/docker-entrypoint
: делает скрипт точки входа исполняемым. ENTRYPOINT ["/rails/bin/docker-entrypoint"] EXPOSE 5000 // you can use any port of your choice CMD ["./bin/rails", "server"]
ENTRYPOINT ["/rails/bin/docker-entrypoint"]
: устанавливает сценарий точки входа, который будет запускаться при запуске контейнера. Этот сценарий обычно настраивает среду, подготавливает базу данных и запускает приложение.
EXPOSE 5000
: указывает, что контейнер прослушивает порт 5000. Это функция документации, и порт не публикуется.
CMD ["./bin/rails", "server"]
: определяет команду по умолчанию, запускаемую при запуске контейнера, то есть запуск сервера Rails. Файл docker-compose.yml
используется для определения и запуска многоконтейнерных приложений Docker. Он позволяет вам настраивать службы, сети и тома вашего приложения в одном файле. В данном случае мы собираемся использовать два сервиса. Вот файл docker-compose.yml
для приложения 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
: указывает образ Docker, который будет использоваться для этого сервиса. В данном случае это образ PostgreSQL 14.2, основанный на дистрибутиве Alpine Linux. Альпийские изображения известны своим небольшим размером, что позволяет уменьшить общий размер изображения.
container_name: demo-postgres-14.2
: называет контейнер demo-postgres-14.2
. Это имя используется для ссылки на контейнер в командах и журналах.
volumes
: postgres_data:/var/lib/postgresql/data:
монтирует именованный том postgres_data
в /var/lib/postgresql/data
внутри контейнера. В этом каталоге PostgreSQL хранит свои данные, гарантируя сохранение данных базы данных между перезапусками контейнера.
command: "postgres -c 'max_connections=500'"
: переопределяет команду по умолчанию для образа PostgreSQL. Он запускает PostgreSQL с опцией конфигурации, позволяющей увеличить максимальное количество подключений до 500.
environment
: POSTGRES_DB: ${POSTGRES_DB}
: устанавливает имя создаваемой базы данных по умолчанию, используя переменную среды POSTGRES_DB
.
POSTGRES_USER: ${POSTGRES_USER}
: устанавливает имя пользователя по умолчанию для доступа к базе данных PostgreSQL с использованием переменной среды POSTGRES_USER
.
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
: устанавливает пароль для пользователя по умолчанию, используя переменную среды POSTGRES_PASSWORD
.
ports
:"5432:5432"
: сопоставляет порт 5432 на хосте с портом 5432 в контейнере. Это позволяет получить доступ к PostgreSQL на хост-компьютере через порт 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: .
: указывает контекст сборки для образа Docker. В этом случае, .
ссылается на текущий каталог. Это означает, что Docker будет использовать Dockerfile в текущем каталоге для создания образа.args
: RAILS_ENV=${RAILS_ENV}
: передает аргумент сборки RAILS_ENV
в процесс сборки Docker, позволяя вам указать среду Rails (например, development
, test
или production
).
command: "./bin/rails server -b 0.0.0.0"
: переопределяет команду по умолчанию для образа Docker. Запускает сервер Rails и привязывает его ко всем сетевым интерфейсам ( 0.0.0.0
), что необходимо для доступности сервиса извне контейнера.
environment:
RAILS_ENV=${RAILS_ENV}
: устанавливает среду Rails внутри контейнера с помощью переменной среды RAILS_ENV
.
POSTGRES_HOST=${POSTGRES_HOST}
: устанавливает адрес хоста PostgreSQL.
POSTGRES_DB=${POSTGRES_DB}
: устанавливает имя базы данных.
POSTGRES_USER=${POSTGRES_USER}
: устанавливает пользователя PostgreSQL.
POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
: устанавливает пароль пользователя PostgreSQL.
RAILS_MASTER_KEY=${RAILS_MASTER_KEY}
: Устанавливает главный ключ Rails, который используется для шифрования учетных данных и других секретов.
volumes
:
.:/rails
: монтирует текущий каталог (где находится файл docker-compose.yml
) в /rails
внутри контейнера. Это позволяет вам редактировать файлы на вашем хосте и отражать эти изменения внутри контейнера.
app-storage:/rails/storage
: монтирует именованный том app-storage
в /rails/storage
внутри контейнера. Обычно это используется для хранения файлов, специфичных для Rails, таких как журналы, загрузки и кэшированные файлы.
depends_on
:
db
: гарантирует, что demo-web
служба ожидает готовности службы db
перед запуском. Docker Compose управляет порядком запуска служб на основе этого параметра. ports:
"3000:3000"
: сопоставляет порт 3000 на хосте с портом 3000 в контейнере. Это позволяет вам получить доступ к приложению Rails на хост-компьютере через порт 3000. codevolumes: postgres_data: app-storage:
postgres_data
: определяет именованный том postgres_data
используемый службой db
для сохранения данных PostgreSQL.app-storage
: определяет именованный том app-storage
, используемый demo-web
службой для хранения данных, специфичных для приложения, таких как загрузки и журналы. Сценарий bin/docker-entrypoint
является важной частью настройки Docker. Он выполняется при запуске контейнера и обычно отвечает за настройку среды, подготовку базы данных и другие задачи инициализации, необходимые перед запуском основного приложения. Вот пример сценария bin/docker-entrypoint
и подробное объяснение каждой части:
bashCopy code#!/bin/bash set -e
#!/bin/bash
: эта строка указывает, что сценарий следует запускать с использованием оболочки 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
"${*}"
), ./bin/rails server
. *
— это специальный параметр, который содержит все позиционные параметры, передаваемые в скрипт.
./bin/rails БД
: Если условие выполнено, эта команда попытается создать базу данных. Это эквивалентно запуску rails db:create
, который настраивает базу данных, как определено в файле конфигурации базы данных ( config/database.yml
).
./bin/rails БД
: Эта команда запустит rails db:prepare
, что обеспечит настройку и миграцию базы данных. Он создаст базу данных, если она не существует, и выполнит миграцию, если база данных уже создана. Это комбинация rails db:create
и rails db:migrate
.
bashCopy codeexec "${@}"
exec "${@}"
: заменяет текущий процесс оболочки командой, переданной в качестве аргументов сценарию. Символ @
содержит все позиционные параметры, передаваемые в скрипт. Например, если сценарий вызывается с помощью ./bin/rails server
, эта строка фактически запускает ./bin/rails server
как основной процесс контейнера. Хорошо продуманный Dockerfile
необходим для создания надежной и согласованной среды для вашего приложения Ruby on Rails и React. Определив базовый образ, задав переменные среды и установив зависимости, вы гарантируете, что ваше приложение будет бесперебойно работать в различных средах.
Docker не только оптимизирует процесс разработки, но и повышает надежность вашего приложения в рабочей среде. Есть области оптимизации, но это всего лишь общий обзор того, как докеризовать приложение Rails.
Dockerfile
, docker-compose.yml
и 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 "${@}"