Continuous Deployment
Overview
- Setting GitHub secrets
- Creating a GitHub action
At this point, we can deploy our software to either our main site or a staging site with a single command. Let's take the next step and automate the deployment process. We will use GitHub Actions to deploy our software to our staging area. This will allow us to deploy our software with a single push to the repository. As with other aspects of Kamal, this can be done by taking three small steps.
For this chapter, we will use the Rails example application defined in Local, and automatically deploy it to a staging server every time we push to the main branch of the repository—but only if the tests pass. Your processes and needs may be different, but the steps should be similar.
Setting GitHub Secrets
The first step is to set up the secrets in GitHub. GitHub Actions: Using secrets in GitHub Actions This is done by going to the repository and selecting the Settings tab. From there, select the Secrets tab and add the following secrets:
SSH_PRIVATE_KEY
– The private key used to connect to the serverKAMAL_REGISTRY_PASSWORD
– The password to your Docker registryRAILS_MASTER_KEY
– The master key for your Rails applicationACCESS_KEY_ID
– The access key ID for your S3 object storageSECRET_ACCESS_KEY
– The secret access key for your S3 object storageENDPOINT_URL
– The endpoint URL for your S3 object storageREGION
– The region for your S3 object storageBUCKET_NAME
– The bucket name for your S3 object storage
If you generated a new SSH key when you assembled your ingredients,
the SSH_PRIVATE_KEY
can be found by running cat ~/.ssh/id_ed25519
on your local machine.
The RAILS_MASTER_KEY
can be found by running cat config/master.key
in your Rails application. The rest you can get from your password manager.
Yes, this means that your secrets will need to be maintained in two places. This is unfortunate but necessary, as GitHub can't access your password manager, and secrets placed in GitHub can't be retrieved. Fortunately, secrets rarely change, so this is not a big issue.
As an alternative to using the web interface, you can use the GitHub CLI to set the secrets. Here are some example commands:
gh secret set SSH_PRIVATE_KEY < ~/.ssh/id_ed25519
gh secret set RAILS_MASTER_KEY < config/master.key
Creating a Second Kamal Secrets File
You already have a .kamal/secrets
file in your Rails application. This file is used to extract the secrets for your application. You will need to create a second file called .kamal/secrets.cd
that will be used to extract the secrets in GitHub Actions.
# .kamal/secrets.cd
# (This file should extract secrets from the environment)
This file is much simpler than your existing secrets file. It only needs to extract the secrets from the environment.
Creating a GitHub Action
The final step is to create a GitHub Action that will deploy your software to your staging server. This is done by updating a file called .github/workflows/ci.yml
in your repository.
Before proceeding, let's review what we see at the top of that file:
# .github/workflows/ci.yml (part: on)
# This file is a YAML file that defines the GitHub Action. The first part of the file defines when the action should run.
# In this case, it will run every time you push to the main branch of the repository.
Following that are a number of jobs. The last job is named test
and runs the tests for the application. Now let's add a job to deploy the application, which is only to be run if the tests pass.
# .github/workflows/ci.yml (part: deploy)
# This checks out the code, sets up Ruby (which installs Kamal), uses the SSH agent with your private key,
# sets up Docker builds, and then deploys the application using your secrets and replacing the
# .kamal/secrets file with the .kamal/secrets.cd file. This last change is committed to git locally but never pushed to the repository.
If you don't have an existing .github/workflows/ci.yml
file, simply create one. If you do have a test job, remove the needs: test
line from the deploy job.
If you have a non-Ruby application, you can install Kamal by adding the following after the Ruby setup step:
- name: Install Kamal
run: |
bundle init
bundle add kamal
bundle binstub kamal
Once ready, commit these files to your repository and push them to GitHub. You should see the action run and deploy your application.