GitHub Actions Deploy
Automate deployments to Nexlayer on every push to main. Build Docker images, push to GitHub Container Registry, and deploy — all in one workflow.
Overview
This GitHub Actions workflow gives you a complete CI/CD pipeline for deploying to Nexlayer. When you push to main, it builds your frontend and backend Docker images, pushes them to GitHub Container Registry tagged with the commit SHA, updates your nexlayer.yaml with the new image tags, and deploys everything via the Nexlayer API.
The Pipeline
Push to main
You push code to the main branch (or trigger manually).
Build images
GitHub Actions builds Docker images for your frontend and backend using Buildx with layer caching.
Push to GHCR
Images are pushed to GitHub Container Registry, tagged with the commit SHA for traceability.
Update nexlayer.yaml
The workflow updates your deployment config with the new image tags automatically.
Deploy to Nexlayer
The updated YAML is sent to the Nexlayer API, which rolls out the new version.
Setup
1. Add the workflow file
Copy the YAML below and save it as .github/workflows/deploy.yml in your repository.
2. Add your Nexlayer API key
Go to your GitHub repo → Settings → Secrets and variables → Actions, and add:
NEXLAYER_API_KEY→Your API key from app.nexlayer.ioGITHUB_TOKEN is provided automatically by GitHub Actions — you don't need to add it.
3. Add a nexlayer.yaml
Make sure your repo has a nexlayer.yaml at the root. The workflow will update the image tags automatically on each deploy. Check the PERN App or Custom Fullstack templates for examples.
4. Push to main
That's it. Every push to main will build, push, and deploy automatically. You can also trigger it manually from the Actions tab.
Workflow File
Save this as .github/workflows/deploy.yml in your repository:
name: Build and Deploy PERN App to Nexlayer
on:
push:
branches:
- main
workflow_dispatch: # Allow manual triggering
env:
SHORT_SHA: ${{ github.sha }}
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build-and-deploy:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push Frontend image
uses: docker/build-push-action@v5
with:
context: ./frontend
file: ./frontend/Dockerfile
push: true
platforms: linux/amd64
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/frontend:${{ env.SHORT_SHA }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Build and push Backend image
uses: docker/build-push-action@v5
with:
context: ./backend
file: ./backend/Dockerfile
push: true
platforms: linux/amd64
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/backend:${{ env.SHORT_SHA }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Update nexlayer.yaml
run: |
# Extract the short SHA
SHORT_SHA=$(echo ${{ github.sha }} | cut -c1-7)
# Update frontend image in nexlayer.yaml
sed -i "s|image:.*frontend.*|image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/frontend:$SHORT_SHA|" nexlayer.yaml
# Update backend image in nexlayer.yaml
sed -i "s|image:.*backend.*|image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/backend:$SHORT_SHA|" nexlayer.yaml
# Display the updated file for verification
cat nexlayer.yaml
- name: Deploy to Nexlayer
env:
NEXLAYER_API_KEY: ${{ secrets.NEXLAYER_API_KEY }}
run: |
# Deploy to Nexlayer using the API
curl -X POST https://app.nexlayer.io/startUserDeployment \
-H "Content-Type: text/x-yaml" \
-H "Authorization: Bearer $NEXLAYER_API_KEY" \
--data-binary @nexlayer.yaml
echo "PERN App deployed to Nexlayer!"
echo "Check your deployment status at: https://app.nexlayer.io"Make It Yours
This workflow assumes a frontend/ and backend/ directory structure with a Dockerfile in each. Adjust the context and file paths in the build steps to match your project layout.
If you only have one service (e.g. a single Next.js app), remove the second build step and simplify the sed command to update just one image tag.
To deploy on different branches, update the branches list in the on.push trigger. You can also add separate workflows for staging vs production.