Automating Deployments with GitHub Actions
Deploying a Next.js app is a thrilling milestone. But manual deployments? They can quickly turn excitement into frustration. It's not just the repetition—it's the risk of missing a step or making a mistake that could bring your app crashing down. What if you could push a button—or better yet, let GitHub handle it for you?
That's where GitHub Actions comes in. By automating your deployments, you can focus on building and improving your app instead of worrying about repetitive tasks. Think of it as setting up an autopilot for your development workflow.
In this post, I'll guide you through using GitHub Actions to automate deployments for your Next.js app. Let's make your workflow smoother and more reliable!
Why Automate Deployments?
Manual deployments are not only tedious—they're prone to errors. All it takes is skipping a step or running the wrong command to end up with downtime or a broken build, or even data loss. It's stressful, and let's face it: nobody wants that on a Friday night.
Automating your deployments eliminates these risks, ensuring consistency, reducing human error, and freeing up your time for tasks that matter more.
Automating deployments solves these problems:
- 🚀 Speed: Push your changes, and GitHub Actions will take care of the rest.
- ✅ Reliability: Every step happens in the correct order, every time.
- 📈 Scalability: As your project grows, automation keeps things running smoothly.
- 😌 Peace of Mind: No more late-night deployment disasters—just clean, consistent workflows.
Step 1: Preparing Your Environment
Before diving into GitHub Actions, let's prepare the groundwork for success. Think of this step as setting the stage for a smooth, stress-free automation process. With a bit of preparation now, you'll save countless hours (and avoid headaches) down the line.
-
A Deployed App Ensure your app is already live on a platform like Vercel, DigitalOcean, etc. For this guide, I'll assume you're using DigitalOcean.
-
A GitHub Repository Your app's source code should be hosted on GitHub. If you haven't already, create a new repository and push your code to it.
-
Access Credentials Gather the credentials you'll need to deploy, such as an SSH key or an API token. For DigitalOcean, you'll need:
- A personal access token (PAT) with write access to your account.
- Your droplet IP address and SSH key.
Step 2: Setting Up a GitHub Actions Workflow
Now that your environment is set, let's move to the exciting part—building a workflow that takes care of your deployments, so you don't have to. Think of this as a blueprint where you specify what needs to happen, when it should happen, and how GitHub should handle it—all in one YAML file.
2.1 Understanding the Workflow File
A GitHub Actions workflow file is written in YAML format. It defines:
- Name: A descriptive label for your workflow.
- Trigger Events: Specify when the workflow should run (e.g., on
push
, onpull_request
, or manually). - Jobs: Groups of tasks that execute in a virtual environment, such as building or deploying your app.
This file will serve as your automation script, making deployments predictable and error-free.
2.2 Create a Workflow File
-
Navigate to the Workflow Directory
Ensure your repository contains a.github/workflows/
directory. If it doesn't exist, create it at the root level of your project. -
Create the Workflow File
Inside the directory, create a file calleddeploy.yml
. This file will define the workflow for automating your deployment.
2.3 Define the Workflow
Now, let's break the workflow file into its main sections:
Workflow Name
The name
block is a simple but important detail—it identifies your workflow in the GitHub Actions UI.
1name: Deploy to DigitalOcean
Trigger Events
The on
block defines when the workflow should run. In this case:
push
: Runs the workflow automatically whenever changes are pushed to themain
branch, but only if the modified files are within specified directories.workflow_dispatch
: Allows you to trigger the workflow manually via the GitHub interface.
1on:
2 push:
3 branches: ["main"]
4 paths:
5 - "src/**"
6 - "content/**"
7 - "public/**"
8 workflow_dispatch:
The on
block specifies when your workflow should run. In this example:
push
: Runs automatically whenever you push changes to themain
branch, but only if the modified files are insrc/
,content/
, orpublic/
.The
paths
directive ensures that the workflow runs only when changes are made to specific directories, avoiding unnecessary triggers.workflow_dispatch
: Lets you trigger the workflow manually from the GitHub Actions interface.
Jobs Section
The jobs
block is where the magic happens—it organizes your tasks into "jobs," which GitHub can execute independently.
Here, we're defining a single job called build
that runs on an Ubuntu virtual machine.
1jobs:
2 build:
3 runs-on: ubuntu-latest
2.4 Adding Deployment Steps
Each job consists of steps, which are the specific tasks GitHub will execute in order. Let's break the deployment process into logical steps and see how to configure each one:
What Does This Step Do?
Deploying your app to a DigitalOcean droplet involves:
- Connecting to the server via SSH.
- Pulling the latest changes from your Git repository.
- Installing dependencies and building the app.
- Restarting the app using a process manager like
PM2
.
How Do You Configure It?
Here's the YAML code to define these steps in your workflow file:
1steps:
2 - name: Deploy to DigitalOcean droplet via SSH
3 uses: appleboy/ssh-action@v1.2.0
4 with:
5 host: ${{ secrets.SERVER_HOST }}
6 username: ${{ secrets.SERVER_USERNAME }}
7 key: ${{ secrets.SERVER_PRIVATE_KEY }}
8 port: ${{ secrets.SERVER_PORT }}
9 script: |
10 #!/bin/bash
11 # Ensure Node.js and npm are in the PATH
12 export PATH=$PATH:/home/ubuntu/.nvm/versions/node/v22.11.0/bin
13
14 # Navigate to the app directory and pull the latest changes
15 cd <PATH_TO_YOUR_APP>
16 git pull
17 npm install
18 npm run build
19
20 # Check if PM2 process is running; restart or start accordingly
21 if pm2 list | grep -q "<APP_NAME>"; then
22 pm2 reload <APP_NAME>
23 else
24 pm2 start npm --name "<APP_NAME>" -- start
25 fi
26
27 # Verify the running processes
28 pm2 list
Breaking It Down:
-
uses
: Indicates the GitHub Action being utilized. In this case,appleboy/ssh-action
allows executing commands over SSH. -
with
: Contains the settings and secrets needed for the deployment, including:host
: Your server's IP address (stored as a GitHub Secret).username
: The server username, such asroot
orubuntu
.key
: Your private SSH key for secure authentication.port
: The port for SSH (default is22
).
-
script
: Contains the series of commands executed on your server. These include:- Adding Node.js to the PATH: Ensures the build tools can run properly.
- Pulling the latest code: Syncs your server with the latest GitHub changes.
- Installing dependencies and building the app: Prepares your app for deployment.
- Managing the app with PM2: Either restarts or starts the app, ensuring minimal downtime.
Step 3: Setting Up GitHub Secrets
GitHub Actions requires sensitive information like credentials to be stored securely as secrets. These secrets are encrypted and can be accessed by your workflows.
- Go to your repository's Settings > Secrets and variables > Actions.
- Add the following secrets:
SERVER_HOST
: Your droplet's IP address.SERVER_USERNAME
: Your droplet's username (e.g.,root
).SERVER_PRIVATE_KEY
: Your SSH private key.SERVER_PORT
: Your SSH port (default is22
).
With these secrets in place, your workflow can securely access your server—without the risk of hardcoding sensitive credentials in the YAML file.
Step 4: Testing Your Workflow
Now it's time for the moment of truth: testing your workflow. This step is both exciting and nerve-wracking—like starting up a freshly built machine for the first time. Here's how to make sure everything is running as expected.
- Push a change to the
main
branch (e.g., update theREADME
file). - Go to the Actions tab in your repository to monitor the workflow's progress.
- Check your server to verify the app has been deployed successfully.
If something goes wrong, don't panic. GitHub Actions provides detailed logs to help you debug issues step by step. You'll be able to see exactly where things went wrong and make the necessary adjustments.
What's Next?
Setting up GitHub Actions is just the first step in optimizing your workflow. From adding pre-deployment tests to fine-tuning workflows for specific environments, the possibilities are endless. As you dive deeper into what's possible, you'll find endless opportunities to refine your process and focus on what really matters: building great apps.
Adding Pre-Deployment Tests
Ensure your code is deployment-ready by running automated tests before every push to production.
Optimizing for Multiple Environments
Learn how to manage workflows for staging, production, and more.
Proactive Monitoring
Keep tabs on your deployments by integrating tools that provide real-time alerts and analytics.
Stay tuned for these and other insights to make your development process faster, more reliable, and stress-free.
Automating deployments with GitHub Actions isn't just about saving time—it's about building confidence in your workflow. By eliminating manual steps, you reduce errors and focus on what you do best: creating amazing apps.
I hope this guide helps you take the next step in streamlining your deployment process. Have questions or insights? Let me know—I'd love to hear from you!
Remember that you can find me as J1Loop on github. Or you can contact me on LinkedIn.