Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save pil0u/c48bd756326dd58f35758a5de77d9806 to your computer and use it in GitHub Desktop.

Select an option

Save pil0u/c48bd756326dd58f35758a5de77d9806 to your computer and use it in GitHub Desktop.
Self-hosting made easy

Create and deploy a new Rails app with Dokku on a VPS

Initial publication: 2025-11-17

Assumptions

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.

Setup server (OVH)

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 on

Install and setup Dokku (only once)

https://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]

Create a simple Rails app and deploy it to Dokku

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 example

Create 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:migrate

Commit and push.

Add the dokku remote and deploy with git push:

git remote add dokku "ssh://[email protected]:12345/example"
git push dokku main

🎉

Adjustments after first deploy

Add a Ruby version in Gemfile

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

Add a Procfile

Create a Procfile file at the root of the project, and add:

web: bundle exec puma -C config/puma.rb

Add an SSL certificate (enable HTTPS)

dokku letsencrypt:enable example
dokku letsencrypt:cron-job --add

-> https://example.123.45.67.89.sslip.io/up

Automate deploy when push on main branch

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_actions

Go to your GitHub repo Settings, add these repository secrets:

  • DOKKU_HOST -> 123.45.67.89
  • DOKKU_PORT -> 12345
  • DOKKU_SSH_PRIVATE_KEY -> private key of the key you just generated (= content of the gihub_actions file)

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment