Kamal Database Backups

Episode #485 by Teacher's Avatar David Kimura

Summary

In this episode, we look at some precautions we can take with our production environment and setup recurring backups for the database.
rails deployment kamal 13:23

Chapters

  • Introduction (0:00)
  • Setting up the prompt (3:49)
  • Testing the new prompt (5:14)
  • Adding the sandbox flag (5:33)
  • Backing up the database (7:39)
  • Kamal reboot vs restart (11:03)
  • Verifying backups are created (12:24)
  • Final thoughts (12:52)

Resources

Download Source Code

Summary

# Terminal
kamal console
kamal accessory boot postgres_backup
kamal accessory restart postgres_backup # won't copy new environment variables
kamal accessory reboot postgres_backup
kamal accessory logs postgres_backup

# .kamal/secrets
POSTGRES_PASSWORD=$(bin/rails runner "puts Rails.application.credentials.dig(:postgres, :password)")
POSTGRES_PASS=$(bin/rails runner "puts Rails.application.credentials.dig(:postgres, :password)")

# .irbrc
def rails_environment
  Rails.env
end

if defined?(Rails)
  def colorize(text, color_code) = "\e[#{color_code}m#{text}\e[0m"
  def red(text) = colorize(text, 31)
  def green(text) = colorize(text, 32)
  def blue(text) = colorize(text, 36)

  prompt = case rails_environment
  when "development"
             green(rails_environment)
  when "production"
             "\e[1;41;97m!!PRODUCTION!!\e[0m #{red(rails_environment)}"
  else
             blue(rails_environment)
  end

  IRB.conf[:PROMPT][:RAILS] = {
    PROMPT_I: "#{prompt}>",
    PROMPT_N: "#{prompt}>",
    PROMPT_S: "#{prompt}*",
    PROMPT_C: "#{prompt}?",
    RETURN: " => %s\n"
  }

  IRB.conf[:PROMPT_MODE] = :RAILS
end

# config/deploy.yml
aliases:
  console: app exec --interactive --reuse "bin/rails console --sandbox"
  shell: app exec --interactive --reuse "bash"
  logs: app logs -f
  dbc: app exec --interactive --reuse "bin/rails dbconsole"

accessories:
  postgres_backup:
    image: kartoza/pg-backup:17-3.5
    host: 192.168.1.217
    env:
      clear:
        POSTGRES_USER: example
        POSTGRES_DB: example_production
        POSTGRES_HOST: 192.168.1.217
        POSTGRES_PORT: 5432
        CRON_SCHEDULE: "*/10 * * * *"
      secret:
        - POSTGRES_PASS
    directories:
      - backups:/backups