Skip to content

This is an app for 2024 workshops "Deploy with Kamal: A Hands-On Workshop"

Notifications You must be signed in to change notification settings

visualitypl/kamal-workshops-app

Repository files navigation

README

This is a simple Rails 7.1 application built based on Rails "blog app" guide. We will be using this app to learn how to deploy a Rails app to VPS with Kamal.

Sources:

Pre-requisites:

  • Ruby 3.4.1
  • installed and configured git
  • installed and configured ssh
  • ssh-key without passphrase
  • docker installed and updated

Workshop instructions

TASK 1—Sign up to the Companion app

  1. Find or create an SSH key without a passphrase

    https://linuxize.com/post/how-to-setup-passwordless-ssh-login/#setup-ssh-passwordless-login

  2. Go to kamal.cklos.foo

  3. Click on Sign up button

  4. Enter signup code form slides, username, password, PUBLIC part of SSH key

  5. Test your SSH connection to assigned servers

TASK 2—Create a new Rails 8 app and deploy it with Kamal

  1. Generate a new application

    gem update rails
    rails _8.0.1_ new kamal-workshops-new
    
  2. Add Posts scaffold (optional)

    bin/rails generate scaffold Posts title:string 
    bin/rails db:migrate
    

    set root "posts#index" in config/routes.rb

  3. Edit config/deploy.yml

    image: <docker_username- e.g. kamal_gh_1>/kamal_workshops_new
    
    servers:
      web:
        - <IP address - e.g. 255.255.255.100>
    
    proxy:
      ssl: true
      host: <Host - e.g pluto.cklos.foo>
    
    registry:
      username: <docker_username - e.g. kamal_gh_1>
    
  4. Set KAMAL_REGISTRY_PASSWORD environment variable in terminal

    export KAMAL_REGISTRY_PASSWORD=<docker_token>
    
  5. Commit changes

  6. Deploy with kamal setup

  7. Go to pluto.cklos.foo

    You have deployed your application.

Task 3—Migrate Rails 7 app to Kamal deployment

0 Clone the repository

git clone [email protected]:visualitypl/kamal-workshops-app.git
git clone https://github.com/visualitypl/kamal-workshops-app.git

Example files for this task:

1 Add kamal to Gemfile

gem "kamal", require: false

2 initialize kamal

bundle install
kamal init

3 Setup deploy.yml

We will need to edit:

  • service (name of the app: blog-space)
  • image (#{Docker Hub username from the companion app}/#{name of the app})
  • servers (IP from the companion app)
  • proxy (with hostname)
  • registry (username: #{Docker Hub username from the companion app})
  • env (clear, secret)
  • accessories

4 Setup .kamal/secrets

We will need to edit:

  • KAMAL_REGISTRY_PASSWORD (Docker Hub token from the companion app)
  • SECRET_KEY_BASE (generate secret key base with rails secret)
  • POSTGRES_PASSWORD (pick any password)
  • REDIS_PASSWORD (pick any password)
  • REDIS_URL (substitute password in string: "redis://:$REDIS_PASSWORD@blog-space-redis:6379/0")

5 Deploy

To install docker, start postgres and redis containers, kamal-proxy and deploy the app we need to run:

kamal server bootstrap
kamal env push
kamal accessory boot postgres && kamal accessory boot redis 
# or kamal accessory boot all
kamal deploy

Alternatively, you can run a command that calls all the above:

kamal setup

6 Check the result

To check the result, run:

kamal audit
kamal details

Visit the app at hostname you set in the proxy.

Task 4-Deploy staging destination

Example files for this task:

5.1 Add config for staging destination

Create config/deploy.staging.yml. We only need to override values from config/deploy.yml that are different for staging.

servers:
  web:
    hosts:
      - [HOST IP] ## CHANGE ME

  worker:
    hosts:
      - [HOST IP] ## CHANGE ME

env:
  clear:
    RAILS_ENV: "staging"
    POSTGRES_DB: "blog_space_staging"

accessories:
  postgres:
    files:
      - "config/init.staging.sql:/docker-entrypoint-initdb.d/init.sql"

  redis:
    cmd: "redis-server --requirepass <%= File.read('.env.staging')[/REDIS_PASSWORD="(.*?)"/, 1] %>"

5.2 Add env vars for staging destination

Create .env.staging and add:

  • SECRET_KEY_BASE (generate secret key base with rails secret)
  • POSTGRES_PASSWORD (pick a password)
  • REDIS_PASSWORD (pick a password)
  • REDIS_URL ("redis://:<REDIS_PASSWORD>@blog-space-redis:6379/0", substitute the password with above)

Notice that we are not setting KAMAL_REGISTRY_PASSWORD env var, because we are using the same one as in production.

5.3 Deploy

To use kamal with staging destination we need to pass -d staging flag to all commands. Like before we need to setup docker on hosts, push env, deploy postgres accessory and deploy the app.

kamal setup -d staging
kamal server bootstrap -d staging
kamal env push -d staging
kamal accessory boot all -d staging
kamal deploy -d staging

5.4 Check the result

To check the result, run:

kamal audit -d staging
kamal details -d staging

Visit the app at http://#{STAGING-IP}

6. Breaking and fixing

6.1 Breaking

We will break the app by generating a migration that will fail.

bundle exec rails generate migration addAuthorToArticle
class AddAuthorToArticle < ActiveRecord::Migration[7.1]
  def change
    add_column :articles, :author, :string, null: false
  end
end

Commit the changes and push them to the server.

git add -A
git commit -m "Add author to article"
kamal deploy

Inspect the output of the deploy command and notice that the app have not been deployed to the server.

6.2 Breaking even more

Fix the migration by adding a default value to the author column. BUT at the same time break something else.

class AddAuthorToArticle < ActiveRecord::Migration[7.1]
  def change
    add_column :articles, :author, :string, null: false, default: ""
  end
end

Comment the "delete_barons_comments" route in config/routes.rb

# post "delete_barons_comments", on: :member

Commit the changes and push them to the server.

This time the migration were applied to the database. But "the core functionality" of the app is lost.

6.3 The Rollback

Rollback to previous version of the app:

kamal rollback <VERSION>

# to find the version run:
kamal audit

6.4 Cleanup

Remove the migration that we added previously.

This task has no solution here ;)

About

This is an app for 2024 workshops "Deploy with Kamal: A Hands-On Workshop"

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published