I use asdf
to manage my runtime versions (Ruby and Node). This makes life a lot easier when switching between multiple codebases and allows me to easily to switch machines due to the presence of a .tool-versions
file in each of my repositories.
Where this gets a little complicated is creating a new Ruby on Rails project, as my local (in a directory) version of tools may be different to my global (laptop wide) versions.
To ensure I’m not getting versions mixed up, I like to setup my local versions before creating the application.
Setup using asdf
Create a folder from the terminal on your machine and navigate into it.
mkdir my_new_rails_project
cd my_new_rails_project
From here we will tell asdf
which versions of Ruby and Node we want to use. I’ve previously tried to also specify the Postgres version too but that caused more issues than it solved.
asdf local ruby 3.4.1
asdf local nodejs 22.9.0
By default the yarn
version is usually set to v1.x
which is pretty old in comparison to the current v4.x
that is available, so lets fix that.
yarn set version stable
yarn -v
# 4.6.0
I sometimes have issues where the above command fails with an error saying that the Node version is incorrect. This can usually be fixed with a asdf reshim nodejs
command.
Add the node-modules
linker to the newly created .yarnrc.yml
. This tells yarn to use the old node modules folder structure, which Rails typically relies on
echo "nodeLinker: node-modules" >> .yarnrc.yml
Rails new
You should now be ready to run the rails new
command. You may need to install the rails
gem for the your version of Ruby - there’s nothing special for you to do here other than following the Rails documentation
When running the rails new
command, be sure to run it from the directory that you have manually created.
Instead of naming the project in the rails new
command you’ll want to use the existing directory.
This is achieved by running rails new .
rather than something like rails new my_new_rails_project
as described in the documentation - the .
tells the Rails CLI tool to use the current directory
My go to is
rails new . --css tailwind -j esbuild --skip-spring --skip-system-test --asset-pipeline=propshaft --database=sqlite3
Prepare to deploy
Dockerfile
We’re using a different version of Node than the default Dockerfile expects, so we’ll make some updates
Remove npm install -g yarn@$YARN_VERSION && \
from the “# Install JavaScript dependancies” section.
Add the following after the “# Install JavaScript dependancies” section.
# Setup yarn
RUN corepack enable
RUN yarn set version stable
Change RUN yarn install --frozen-lockfile
to RUN yarn install --immutable
in the # Install node modules
section.
Kamal
Update deploy.yml
and .secrets
deploy.yml
Find and replace your-user
with your GitHub handle i.e. dcyoung-dev
Update the servers
section to specify hosts
and options
. Network allows for a private network to be established on your machine, useful for running multiple applications.
servers:
web:
hosts:
- 5.75.164.130
options:
network: your_project_name
Update proxy
hostname
to your domain name
Update registry
server
to use GitHub i.e. server: ghcr.io
. Why use Docker when you’re already using GitHub 🤷‍♂️
.secrets
I use 1Password to manage my secrets. Update the GITHUB_TOKEN
to read a personal access token from 1Password GITHUB_TOKEN=$(op read "op://VaultName/GitHub/personal_access_token")
and then update the KAMAL_REGISTRY_PASSWORD
to use the GITHUB_TOKEN
i.e. KAMAL_REGISTRY_PASSWORD=$GITHUB_TOKEN
Server Setup
With the private network being used you’ll have to SSH into your machine and set this up in Docker manually. If this is your first application, run kamal setup
first. It will fail but should have Docker installed on your server. You can then run the following:
ssh root@<server_ip_address>
then docker network create your_project_name
- your_project_name
comes from servers:web:options:network
in your deploy.yml
DNS
I usually use Cloudflare to manage my DNS. Where ever you manage your DNS jump in and create a new A
record, I usually use a subdomain pointing to the IP address of my server. In Cloudflare you can leave the Proxy status set to “proxied”.
Deploy
Make sure you have committed and pushed your code to GitHub.
Make sure Docker is running on your local machine.
Then run
kamal setup
Once complete you can visit your new web application