Як розгорнути ваше Rails додаток разом з Postgres за допомогою Kamal 2 на VPS

Раніше я написав статтю про те, як розгорнути додаток Rails на VPS за допомогою Kamal тут. Тоді Kamal був ще досить новим інструментом, але тепер Kamal 2 був запущений і додається за замовчуванням у Rails 8, з деякими змінами порівняно з попередньою версією.

Щоб розгорнути додаток Rails за допомогою Kamal 2, виконайте наступні кроки:

Попередні вимоги

Перед початком переконайтесь, що у вас є наступне:

  1. Додаток Ruby on Rails з налаштованою PostgreSQL для бази даних.
  2. Реєстр Docker для зберігання ваших Docker-образів. Я рекомендую використовувати DockerHub або AWS ECS.
  3. VPS (дроплет) з останньою версією Ubuntu та налаштованим доступом через SSH. Ви можете використовувати будь-якого постачальника, але я б порекомендував Hetzner або Digital Ocean.
  4. Рекомендується зміцнити ваш сервер, щоб запобігти можливим атакам. Хоча зміцнення сервера може здатися складним завданням, особливо якщо ви не знайомі з Linux, я створив детальний скрипт для повного зміцнення нового екземпляра Ubuntu і підготовки його до запуску Docker контейнерів у продакшн. Ви можете отримати його тут.

Крок 1: Встановіть Kamal

Якщо ви використовуєте Rails 8, Kamal вже буде встановлений у вашому проекті. Якщо ні, ви можете встановити його наступним чином:

gem install kamal

kamal init

Це створить файл deploy.yml у папці config.

Крок 2: Налаштуйте параметри розгортання

Тепер давайте налаштуємо різні секції у файлі deploy.yml.

# Назва вашого додатку. Використовується для унікальної конфігурації контейнерів.
service: mynewapp

Вкажіть назву вашого додатку. Вона використовується для унікальної конфігурації контейнерів, пов'язаних з вашим додатком.

# Назва Docker образу.
image: talha/mynewapp

Вкажіть назву Docker образу вашого додатку. Замініть talha/mynewapp на назву вашого репозиторію Docker Hub.

# Розгорніть на цих серверах.
servers:
  web:
    hosts:
      - 123.123.45.678

Вкажіть IP-адреси серверів, на яких буде розгорнуто ваш додаток. Ви можете додати кілька серверів.

proxy:
  ssl: true
  host: mynewapp.com

Kamal 2 використовує Kamal proxy замість Traefik, що використовувався у версії 1. Ви можете прочитати більше про це тут, але для використання з Kamal просто додайте хост, на якому ви хочете приймати вхідний трафік, і увімкніть SSL. Це використовуватиме SSL сертифікати від Lets Encrypt для автоматичного TLS. Переконайтесь, що DNS вашого домену налаштовано на ваш сервер.

Конвенція над конфігурацією для перемоги 🚀.

registry:
  # Вкажіть сервер реєстру, якщо не використовуєте Docker Hub
  # server:
  username:
    - KAMAL_REGISTRY_USERNAME

  # Завжди використовуйте токен доступу замість реального пароля, коли це можливо.
  password:
    - KAMAL_REGISTRY_PASSWORD

Вкажіть облікові дані для доступу до реєстру Docker, де буде розміщено ваш образ додатку. Використовуйте змінні середовища, щоб не додавати свої облікові дані в git.

# Вставка змінних ENV в контейнери (секрети беруться з .env).
# Не забудьте виконати `kamal env push` після внесення змін!
env:
  clear:
    RAILS_ENV: production
    RACK_ENV: production
    RAILS_LOG_TO_STDOUT: true
    RAILS_SERVE_STATIC_FILES: true
  secret:
    - RAILS_MASTER_KEY
    - SMTP_PASSWORD
    - SMTP_SERVER
    - SMTP_LOGIN
    - DB_HOST
    - POSTGRES_USER
    - POSTGRES_PASSWORD

Вкажіть змінні середовища, які будуть вставлені в контейнери. Змінні clear є загальнодоступними, тоді як змінні secret є приватними. Ці змінні беруться з файлу secrets, який знаходиться в папці .kamal.

Kamal 2 змінив спосіб, яким секрети потрапляють у ваш файл deploy.yml.
Тепер Kamal використовує файл .kamal/secrets для впровадження секретів. Ви можете прочитати більше про це тут.

Якщо ви хочете все ще використовувати файл .env для зберігання змінних середовища, ви можете використати наступну настройку.

Додайте наступне на початку файлу deploy.yml.

<% require "dotenv"; Dotenv.load(".env") %>

Тепер, якщо ваш файл .env містить значення, як:

KAMAL_REGISTRY_USERNAME=username  
KAMAL_REGISTRY_PASSWORD=password  

# CREDENTIALS S3  
S3_ACCESS_KEY_ID=your-access-id  
S3_ACCESS_KEY_SECRET=your-secret-access-key

Ви можете впровадити їх, додавши наступне у файл .kamal/secrets:

KAMAL_REGISTRY_USERNAME=$KAMAL_REGISTRY_USERNAME  
KAMAL_REGISTRY_PASSWORD=$KAMAL_REGISTRY_PASSWORD  

S3_ACCESS_KEY_ID=$S3_ACCESS_KEY_ID  
S3_ACCESS_KEY_SECRET=$S3_ACCESS_KEY_SECRET

Далі я рекомендую використовувати користувача, відмінного від root, для розгортання на вашому сервері. Якщо ви використовували мій скрипт для зміцнення сервера, він автоматично створить користувача на ім'я docker. Тому ми можемо використовувати:

# Використовувати інший користувач ssh, а не root  
ssh:  
  user: docker

Тепер налаштуємо PostgreSQL як додаткову службу:

# Використовувати додаткові служби (секрети беруться з .kamal/secrets).  
accessories:  
  db:  
    image: postgres:17.0  
    host: 123.123.45.678  
    env:  
      clear:  
        POSTGRES_USER: mynewapp  
        POSTGRES_DB: mynewapp_production  
      secret:  
        - POSTGRES_PASSWORD  
        - POSTGRES_USER  
    files:  
      - config/init.sql:/docker-entrypoint-initdb.d/setup.sql  
    directories:  
      - data:/var/lib/postgresql/data

Визначте додаткові служби, необхідні для додатка. У цьому випадку налаштовується служба PostgreSQL з вказаною версією та змінними середовища. Директива files дозволяє надати власну точку входу. Файл config/init.sql повинен створювати базу даних, як вказано в конфігурації config/database.yml.

Створіть файл під назвою init.sql в папці config, як показано нижче:

CREATE DATABASE mynewapp_production;  
CREATE DATABASE mynewapp_production_cache;  
CREATE DATABASE mynewapp_production_queue;  
CREATE DATABASE mynewapp_production_cable;

Це створить бази даних для додатка, а також для solid queue, solid cable та solid cache, які є новими доповненнями до Rails 8.

Також потрібно оновити файл database.yml наступним чином:

production:  
  primary: &primary_production  
    <<: *default  
    database: mynewapp_production  
    username: <%= ENV["POSTGRES_USER"] %>  
    password: <%= ENV["POSTGRES_PASSWORD"] %>  
    host: <%= ENV["DB_HOST"] %>  
  cache:  
    <<: *primary_production  
    database: mynewapp_production_cache  
    migrations_paths: db/cache_migrate  
  queue:  
    <<: *primary_production  
    database: mynewapp_production_queue  
    migrations_paths: db/queue_migrate  
  cable:  
    <<: *primary_production  
    database: mynewapp_production_cable  
    migrations_paths: db/cable_migrate

Є ще кілька інших секцій у вашому файлі deploy.yml, таких як aliases, assetpath_ та builder. Вам не потрібно вносити зміни в ці секції. Якщо ви хочете використовувати віддалений builder для побудови Docker образів на зовнішній машині, ви можете налаштувати це в секції builder наступним чином:

# Налаштування побудови образу.  
builder:  
  arch: amd64  
  local: false  
  remote: ssh://[email protected]  
  args:  
    RUBY_VERSION: 3.3.6  
  secrets:  
    - KAMAL_REGISTRY_USERNAME  
    - KAMAL_REGISTRY_PASSWORD  
    - RAILS_MASTER_KEY

Крок 3: Розгортання додатка

Коли ви завершите всі кроки та створите файл config/deploy.yml і будете готові до розгортання, запустіть:

kamal setup

Це налаштує і розгорне три Docker контейнери на вашому сервері, а саме web app, kamal proxy і db. Тепер ви зможете отримати доступ до вашого додатку за вказаним доменом.
🥳

Крок 4: Щоденний робочий процес

Використовуйте команди Kamal для вашого щоденного робочого процесу розгортання:

Щоб розгорнути нову версію вашого додатку:

kamal deploy

Щоб почати сесію bash в новому контейнері:

kamal app exec -i bash

Щоб запустити консоль Rails у новому контейнері:

kamal app exec -i ‘bin/rails console’

Щоб переглянути журнали:

kamal app logs

Висновок

Вітаємо! Ви успішно розгорнули ваше Ruby on Rails додаток з PostgreSQL на VPS, використовуючи Kamal 2. 🚀

Нещодавно я розгорнув https://findyouragent.ai через Kamal 2 разом з кількома сервісами, такими як Solid Queue та PostgresQL. Зайдіть і перевірте.

Якщо вам сподобався цей пост, поставте лайк і не забудьте підписатися на мене тут, на Medium та Twitter.

Перекладено з: How to deploy your Rails app along with Postgres via Kamal 2 on a VPS

Leave a Reply

Your email address will not be published. Required fields are marked *