Buy my course: Security for Rails Developers.
Since Kamal 2 can host multiple sites on the same server, I am consolidating my apps into larger hosts so I have less servers to worry about. Most of my apps are Rails apps, but I have a few static jekyll sites like this blog and I decided to look into how could I move this site to a server I host other Rails apps on.
The first step of the process is to “dockerize” the jekyll site. Kamal Proxy will handle SSL and only requires something to process HTTP requests, so we will create a container with nginx, serving the static HTML files over port 80. To achieve this, we need to create the following Dockerfile in the root of the jekyll project:
# Dockerfile
# syntax = docker/dockerfile:1
FROM nginx
EXPOSE 80
I build my jekyll sites into the _site
folder, so the next step is to copy
that to default folder of nginx so it can serve those files:
# Dockerfile
# syntax = docker/dockerfile:1
FROM nginx
COPY ./_site /usr/share/nginx/html
EXPOSE 80
The next step is to setup Kamal for deployment. Once you installed the gem, run
kamal init
to create the default config file. We will adapt it to do the
following:
- load the
.env
file so we can set theKAMAL_REGISTRY_PASSWORD
from that - set the service name to our static site
- configure the image name
- configure a web host
- enable SSL for the proxy and setting the hostnames we want to use
- set the healthcheck path to the root of the site
- configure the registry
- set the builder context to “.”, so we don’t need to commit the build to the git repository
This is how config/deploy.yml
should look after doing all of the above:
# config/deploy.yml
<% require "dotenv"; Dotenv.load(".env") %>
# Name of your application. Used to uniquely configure containers.
service: mystaticsite
# Name of the container image.
image: registry/static-site
# Deploy to these servers.
servers:
web:
hosts:
- 1.1.1.1 # server IP
# Enable SSL auto certification via Let's Encrypt (and allow for multiple apps on one server).
# Set ssl: false if using something like Cloudflare to terminate SSL (but keep host!).
proxy:
ssl: true
hosts:
- domain.com
- www.domain.com
healthcheck:
path: /
interval: 3
timeout: 30
# Credentials for your image host.
registry:
server: registry.digitalocean.com
username:
- KAMAL_REGISTRY_PASSWORD
# Always use an access token rather than real password when possible.
password:
- KAMAL_REGISTRY_PASSWORD
# Configure builder setup.
builder:
arch: amd64
context: .
Now you just need to put the KAMAL_REGISTRY_PASSWORD
in the .env
file and you are basically ready to deploy. But you should add a .dockerignore
file and put everything else than your build directory into it:
# .dockerignore
# Ignore everything
*
# Allow build folder
!/_site
To make sure you always build before deployment, you can use a Kamal hook. Put
the following to .kamal/hooks/pre-build
:
#!/bin/sh
JEKYLL_ENV=production bundle exec jekyll build
All you have to do now is to deploy the app with kamal deploy
.
Or follow me on Twitter
I run an indie startup providing vulnerability scanning for your Ruby on Rails app.
It is free to use at the moment, and I am grateful for any feedback about it.If you would like to give it a spin, you can do it here: Vulnerability Scanning for your Ruby on Rails app!