paint-brush
Упрощенное руководство по «докеразии» Ruby и Rails с помощью внешнего приложения React к@forison
347 чтения
347 чтения

Упрощенное руководство по «докеразии» Ruby и Rails с помощью внешнего приложения React

к Addo Boakye Forison13m2024/08/04
Read on Terminal Reader

Слишком долго; Читать

Докеризация включает в себя две ключевые концепции: образы и контейнеры. Изображения служат чертежами контейнеров и содержат всю необходимую информацию для создания контейнера. Контейнер — это экземпляр образа во время выполнения, включающий само изображение, среду выполнения и инструкции времени выполнения. В этой статье мы предоставим подробное практическое руководство по докеризации ваших приложений Rails и React.
featured image - Упрощенное руководство по «докеразии» Ruby и Rails с помощью внешнего приложения React
Addo Boakye Forison HackerNoon profile picture
0-item
1-item

Докеризация вашего Ruby on Rails с помощью внешнего приложения React может значительно улучшить ваш рабочий процесс разработки и процесс развертывания. Создавая стандартизированную среду для своего приложения, вы обеспечиваете единообразное поведение на разных этапах разработки, тестирования, производства и даже в разных системах. Фактически, он предназначен для минимизации проблем, связанных с системными различиями. Это руководство проведет вас через основные шаги, чтобы обеспечить бесперебойную работу вашего приложения Rails и React в контейнерах Docker.

Докер спешит на помощь

Зачем докеризовать приложение?

  • Согласованность в разных средах :
    • Docker гарантирует, что приложение работает одинаково независимо от того, где оно развернуто: на компьютере разработчика, в среде тестирования или на рабочем сервере. Эта согласованность достигается за счет контейнеризации всех зависимостей и конфигураций.


  • Управление зависимостями :
    • Контейнеры 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.

2. Установите зависимости

 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 : удаляет списки пакетов и документацию, чтобы уменьшить размер образа.

3. Установите Node.js и 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
  • 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.

4. Переменные среды

 ENV NODE_OPTIONS=--openssl-legacy-provider
  • ENV NODE_OPTIONS=--openssl-legacy-provider : устанавливает переменную среды для включения устаревшей поддержки OpenSSL для Node.js.

5. Установите рабочий каталог.

 WORKDIR /rails
  • WORKDIR /rails : устанавливает рабочий каталог для последующих инструкций в /rails .

6. Создайте аргументы и переменные среды

 ARG RAILS_ENV ENV RAILS_ENV=$RAILS_ENV
  • ARG RAILS_ENV : определяет аргумент сборки с именем RAILS_ENV для указания среды Rails (например, development , test , production ).


  • ENV RAILS_ENV=$RAILS_ENV : устанавливает для переменной среды RAILS_ENV значение аргумента сборки.

7. Установите Gems приложений

 COPY Gemfile Gemfile.lock ./ RUN bundle install
  • COPY Gemfile Gemfile.lock ./ : копирует Gemfile и Gemfile.lock в рабочий каталог.


  • RUN bundle install : Устанавливает драгоценные камни Ruby, указанные в Gemfile .

8. Установите внешние зависимости

 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 .

9. Скопируйте код приложения

 COPY . .
  • COPY . . : копирует весь код приложения в рабочий каталог.

10. Предварительная компиляция кода Bootsnap

 RUN bundle exec bootsnap precompile --gemfile app/ lib/
  • RUN bundle exec bootsnap precompile --gemfile app/ lib/ : Предварительно компилирует кэш Bootsnap для ускорения загрузки приложения Rails. Bootsnap — это драгоценный камень, который ускоряет загрузку Ruby и Rails за счет кэширования дорогостоящих вычислений.

11. Предварительная компиляция ресурсов для производства

 RUN if [ "$RAILS_ENV" = "production" ]; then \ SECRET_KEY_BASE=1 bin/rails assets:precompile; \ fi
  • RUN if [ "$RAILS_ENV" = "production" ]; then ... : Условно запускает предварительную компиляцию ресурсов, только если для RAILS_ENV установлено значение production . Этот шаг имеет решающее значение для подготовки ресурсов к производственной среде.

12. Скрипт точки входа

 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 : делает скрипт точки входа исполняемым.

13. Определите точку входа и команду

 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-compose.yml используется для определения и запуска многоконтейнерных приложений Docker. Он позволяет вам настраивать службы, сети и тома вашего приложения в одном файле. В данном случае мы собираемся использовать два сервиса. Вот файл docker-compose.yml для приложения Rails:

1. Служба базы данных ( 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.

2. Служба веб-приложений ( 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-точка входа

Сценарий 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


  • if [ "${*}" == "./bin/rails server" ]; then ... 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 "${@}"