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:
- A Dokku server set up and running
- An existing Rails application deployed to the server
- Administrative access to both the server and your GitHub repository
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
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
GitHub Repository Configuration
With our keys in place, we need to store the private key securely in GitHub. Here's how:
- Navigate to your repository's Settings → Secrets and variables → Actions
- Create a new secret named
PRODUCTION_DOKKU_SSH_PRIVATE_KEY
- 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 }}
Let's break down what's happening here:
Workflow Triggers
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
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 ]
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
This triggers the following sequence:
- Your code is pushed to GitHub
- GitHub Actions detects the push to main
- The test suite runs
- If tests pass, the deployment job begins
- Your code is securely deployed to the Dokku server
Personal Insights and Tips
Through implementing this setup, I've learned some valuable lessons:
- Security First: Always use dedicated deployment keys and never store sensitive information in your repository.
- Test Dependencies: Make deployment dependent on test success to prevent broken code from reaching production.
-
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)