Initial publication: 2025-11-17
Server OS is Ubuntu 24.04, fresh install
Server IP is 123.45.67.89
SSH port is 12345
App name is example
I built this document for my personal use cases, your kilometrage may vary.
I highly recommend reading https://dokku.com/docs/, the source of truth.
ssh [email protected]
# set up password on first connection
ssh [email protected] # login again
sudo apt update # update system
sudo apt dist-upgrade
sudo nano /lib/systemd/system/ssh.socket # change default SSH port for security
# change ListenStream port to 12345 (pick some other number)
sudo reboot
ssh [email protected] -p 12345 # command to connect from now onhttps://dokku.com/docs/getting-started/installation/
# install command (long)
wget -NP . https://dokku.com/install/v0.36.11/bootstrap.sh
sudo DOKKU_TAG=v0.36.11 bash bootstrap.sh
# add the default SSH key (your machine) as admin dokku SSH key
cat ~/.ssh/authorized_keys | sudo dokku ssh-keys:add admin
# set global domain using sslip, handles DNS gracefully for default deployment to example.123.45.67.89.sslip.io
dokku domains:set-global 123.45.67.89.sslip.io
sudo dokku plugin:install https://github.com/dokku/dokku-postgres.git
sudo dokku plugin:install https://github.com/dokku/dokku-letsencrypt.git
# set global email for letsencrypt generated certificates
dokku letsencrypt:set --global email [email protected]Prepare the apps in Dokku, 1 for the webapp, 1 for the database (using PostgreSQL here):
dokku apps:create example
dokku postgres:create example-db
dokku postgres:link example-db exampleCreate the app on the local machine and push to Dokku:
# skipping tests, docker (we will use buildpacks like Heroku), kamal, choosing postgresql as database
rails new example --database=postgresql --javascript=importmap --css=tailwind --skip-docker --skip-keeps --skip-action-mailbox --skip-action-text --skip-action-storage --skip-jbuilder --skip-test --skip-system-test --skip-kamal
rails db:create db:migrateCommit and push.
Add the dokku remote and deploy with git push:
git remote add dokku "ssh://[email protected]:12345/example"
git push dokku main🎉
At the top of the Gemfile, add the same Ruby version as in .ruby-version
source ...
ruby '3.4.7'
gem 'rails' ...Run bundle and commit both Gemfile and Gemfile.lock
Create a Procfile file at the root of the project, and add:
web: bundle exec puma -C config/puma.rbdokku letsencrypt:enable example
dokku letsencrypt:cron-job --add-> https://example.123.45.67.89.sslip.io/up
On the server, generate a pair of SSH keys dedicated to GitHub Actions and add it to Dokku's allowed keys
ssh-keygen # call it github_actions
cat github_actions.pub | sudo dokku ssh-keys:add github_actionsGo to your GitHub repo Settings, add these repository secrets:
DOKKU_HOST->123.45.67.89DOKKU_PORT->12345DOKKU_SSH_PRIVATE_KEY-> private key of the key you just generated (= content of thegihub_actionsfile)
Create this GitHub Action workflow (example .github/workflows/deploy.yml):
name: Deploy production
on:
workflow_dispatch:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Cloning repo
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Push to dokku
uses: dokku/github-action@master
with:
command: deploy
branch: main
git_remote_url: "ssh://dokku@${{ secrets.DOKKU_HOST }}:${{ secrets.DOKKU_PORT }}/home130"
git_push_flags: "-vvv"
ssh_private_key: ${{ secrets.DOKKU_SSH_PRIVATE_KEY }}Commit and push.