DEV Community

Cover image for Rails CI/CD with Dokku & GitHub Actions
Sulman Baig
Sulman Baig

Posted on • Originally published at sulmanweb.com

Rails CI/CD with Dokku & GitHub Actions

As developers, we're always looking for ways to streamline our deployment process while maintaining security and reliability. Today, I'm excited to share my experience setting up an automated deployment pipeline for a Rails application using Dokku and GitHub Actions. This setup has transformed our deployment process from a manual, error-prone task into a smooth, automated workflow.

The Challenge

Managing production deployments can be tricky. You want something robust like Heroku but with more control over your infrastructure. Enter Dokku - a lightweight, open-source Platform as a Service (PaaS) that gives you Heroku-like features on your own server.

Prerequisites

Before we dive in, make sure you have:

Setting Up Secure Deployment Keys

The first step in our automation journey is setting up secure SSH keys for deployment. This is crucial for allowing GitHub Actions to securely communicate with our Dokku server.

# On your production server
ssh-keygen -t ed25519 -f dokku
Enter fullscreen mode Exit fullscreen mode

This command generates two files:

  • dokku - Your private key (keep this secret!)
  • dokku.pub - Your public key (safe to share)

Next, we need to configure Dokku and the server to trust these keys:

# Add the key to Dokku
echo "YOUR_PUBLIC_KEY_CONTENT" | dokku ssh-keys:add github

# Add to authorized keys for additional security
echo "YOUR_PUBLIC_KEY_CONTENT" >> ~/.ssh/authorized_keys
Enter fullscreen mode Exit fullscreen mode

GitHub Repository Configuration

With our keys in place, we need to store the private key securely in GitHub. Here's how:

  1. Navigate to your repository's Settings → Secrets and variables → Actions
  2. Create a new secret named PRODUCTION_DOKKU_SSH_PRIVATE_KEY
  3. Paste your private key content

This secret will be securely encrypted and only accessible during the deployment process.

The Magic: GitHub Actions Workflow

Now for the exciting part - setting up our automated deployment pipeline. Create or modify .github/workflows/ci.yml:

deploy_production:
    needs: [ test ]
    if: github.event_name == 'push' && github.ref == 'refs/heads/main'
    runs-on: ubuntu-24.04

    steps:
      - name: Cloning repo
        uses: actions/checkout@v3
        with:
          fetch-depth: 0

      - name: Push to dokku
        uses: dokku/github-action@master
        with:
          branch: 'main'
          trace: '1'
          git_push_flags: '--force'
          git_remote_url: 'ssh://dokku@SERVER_IP:22/APP_NAME_IN_DOKKU'
          ssh_private_key: ${{ secrets.PRODUCTION_DOKKU_SSH_PRIVATE_KEY }}
Enter fullscreen mode Exit fullscreen mode

Let's break down what's happening here:

Workflow Triggers

if: github.event_name == 'push' && github.ref == 'refs/heads/main'
Enter fullscreen mode Exit fullscreen mode

This condition ensures deployments only happen when code is pushed to the main branch - perfect for a trunk-based development workflow.

Job Dependencies

needs: [ test ]
Enter fullscreen mode Exit fullscreen mode

By specifying needs: [ test ], we ensure our tests pass before any deployment occurs. This is crucial for maintaining code quality!

Deployment Configuration

The dokku/github-action@master action handles the heavy lifting:

  • branch: 'main' - Specifies which branch to deploy
  • trace: '1' - Enables detailed logging for troubleshooting
  • git_push_flags: '--force' - Ensures clean deployments
  • git_remote_url - Connects to your Dokku server
  • ssh_private_key - Securely authenticates using our previously configured key

The Deployment Process

With everything set up, deploying is as simple as:

git push origin main
Enter fullscreen mode Exit fullscreen mode

This triggers the following sequence:

  1. Your code is pushed to GitHub
  2. GitHub Actions detects the push to main
  3. The test suite runs
  4. If tests pass, the deployment job begins
  5. Your code is securely deployed to the Dokku server

Personal Insights and Tips

Through implementing this setup, I've learned some valuable lessons:

  1. Security First: Always use dedicated deployment keys and never store sensitive information in your repository.
  2. Test Dependencies: Make deployment dependent on test success to prevent broken code from reaching production.
  3. Logging Matters: The trace: '1' option has saved hours of debugging by providing detailed deployment logs.

Looking Forward

This setup has dramatically improved our deployment workflow, but there's always room for enhancement. Future improvements might include:

  • Adding staging environment deployments
  • Implementing automatic database backups pre-deployment
  • Setting up deployment notifications in Slack

Remember, the goal of automation isn't just to save time - it's to build confidence in your deployment process and free up mental energy for solving more interesting problems.

Have you implemented a similar setup? I'd love to hear about your experiences and any improvements you've made to this workflow!

Happy deployments!


Originally published at: https://sulmanweb.com.

Top comments (0)