Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for Kamal deployment #518

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft

Support for Kamal deployment #518

wants to merge 2 commits into from

Conversation

drnic
Copy link
Contributor

@drnic drnic commented Oct 14, 2024

Deploy to own servers with Kamal

Kamal offers zero-downtime deploys, rolling restarts, asset bridging, remote builds, accessory service management, and everything else you need to deploy and manage your web app in production with Docker. Originally built for Rails apps, Kamal will work with any type of web app that can be containerized.

First, create your production credentials file.

bin/rails credentials:edit --environment production

Next, uncomment the database: section

database:
  password: some-long-string

Second, create a Docker Hub access token and store it as local env var KAMAL_REGISTRY_PASSWORD.

Next, edit config/deploy.yml:

  1. Change my-docker-user to your Docker Hub username
  2. Change 168.192.0.1 to the IP or hostname of your target Linux server
  3. If you need to ssh into that server as anything other than root user, then uncomment ssh: section and edit your ssh username.
  4. Change hostedgpt.example.com to the public CNAME or A record that points to your server IP address.

Next, commit all the changes to git so Kamal picks them up.

git add .
git commit -m "Add production credentials and Kamal config"

Install yq tool that is used by .kamal/secrets to extract a value from rails credentials:

brew install yq

Now, run the command to setup the Postgres database, build HostedGPT using docker buildx, and deploy it to your server:

kamal setup

credentials.yml template

bin/rails credentials:edit --environment production

now produces a credentials file containing secret_key_base and active_record_encryption and database.password used if you have a PG accessory.

# Used as the base secret for all MessageVerifiers in Rails, including the one protecting cookies.
secret_key_base: 54525919e0d725faeb623d42f175015ca4e8bc4235fb5305fd883c8759c8fda15c7f63d9cd7beb8e367b33aaf4c011a7b4a6de4b9f4fa908f83692c2a4defc69

active_record_encryption:
  primary_key: 0e9TgzlNe57wlOZzzwoOvtah7WFtNcM6
  deterministic_key: aiq6ShRd7ej9D404RkfRVQ8mQBgcYLrf
  key_derivation_salt: l36v3QE4CgcdAPmNd5GsH0gWstmnj2PY

database:
  password: UYnCLe9zlYymVmQqs8Uztq4JDeLzscva

@drnic drnic force-pushed the kamal2 branch 7 times, most recently from 4d386d4 to c7f8636 Compare October 14, 2024 09:58
@drnic drnic marked this pull request as ready for review October 14, 2024 10:14
@drnic drnic changed the title [draft] Support for Kamal deployment Support for Kamal deployment Oct 14, 2024
@krschacht
Copy link
Contributor

krschacht commented Oct 19, 2024

Sorry for delay on reviewing this! Thanks for teeing this up!! Is this PR ready to go or are there any other things you’re changing? If so I’ll give it a try and then merge it in.

I'll start digging into this PR anyway. I've been eager to figure out Kamal so you creating this PR is a great excuse. No better time than the present! :)

Copy link
Contributor

@krschacht krschacht left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A bunch of small clarifying questions as I'm ramping up on this.

Gemfile.lock Show resolved Hide resolved
password: some-long-string
```

Second, create a Docker Hub access token and store it as local env var `KAMAL_REGISTRY_PASSWORD`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know github lets you host containers. I was using that for a different github project. If I were to enable github container registery for HostedGPT would that save people the trouble of needing to create a Docker Hub account? It must be that Kamal needs to pull from a docker container registery? (I need to watch the Kamal tutorial video)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think Kamal likes to build a new image and deploy it; whereas docker compose supports running pre-built containers or re-building them.

Specifically:

  • the servers processes are going to run based on the image that is built from the local src project
  • the accessories processes are run based on existing images.

So each person who wants to use Kamal will be building their own image to their own docker registry (docker hub, or wherever).

pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
port: <%= ENV['HOSTEDGPT_DATABASE_PORT'] || 5432 %>
<% if RUBY_PLATFORM =~ /darwin/ %>
<% if ENV["HOSTEDGPT_DATABASE_HOST"] %>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rails will already, by default, read DATABASE_URL from the environment and use that as the database configuration instead of what's in database.yml. Does that make it so we don't need to declare all these new ENV variables?

I'm pretty sure other users of HostedGPT have asked for these config so maybe the DATABASE_URL behavior is just too unknown. It probably doesn't hurt to add these regardless.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think if DATABASE_URL or PRIMARY_DATABASE_URL env var is provided, then rails ignores the database.yml file. So database.yml is only for users who are not using these env vars.

I thought it'd made sure all the existing behaviour/defaults existed if the new env vars weren't provided. It's definitely difficult to read YAML + ERB :)

# Set number of cores available to the application on each server (default: 1).
# WEB_CONCURRENCY: 2

HOSTEDGPT_FORCE_SSL: "false"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why disable SSL, was there some complication with Kamal? I thought I remembered hearing that Kamal would auto-configure SSL for you using Let's Authenticate.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like this either and perhaps it wasn't necessary. I just found I needed to turn off force_ssl for the app running behind kamal proxy. Hopefully we learn more over time about good Rails/Kamal practices.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have this deployed with kamal and the FORCE_SSL issue was related to the health check. I had to uncomment the config.ssl_options in production.rb:

# Skip http-to-https redirect for the default health check endpoint.
config.ssl_options = { redirect: { exclude: ->(request) { request.path == "/up" } } }

key_derivation_salt: <%= SecureRandom.alphanumeric(32) %>

# database:
# password: <%= SecureRandom.alphanumeric(32) %>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that this template is used when following the instructions to execute bin/rails credentials:edit --environment production. But the next instruction is to uncomment these two lines. Should we instead just uncomment them within this template file?

@drnic
Copy link
Contributor Author

drnic commented Oct 29, 2024

No urgency to see this PR merged - hopefully more people become adept at Kamal and can confirm this PR is "good" :)

@krschacht krschacht marked this pull request as draft November 24, 2024 00:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants