Got it 🚀 — let’s walk through end-to-end deployment of a GitHub application (say a Node.js app) to DigitalOcean using GitHub Actions + CI/CD. I’ll show you the YAML workflow, DigitalOcean setup, and the exact configuration files you’ll need.
1. Prerequisites
-
DigitalOcean Droplet or App Platform
- Droplet = VM (SSH deploy).
- App Platform = PaaS (GitHub integration or API deploy).
- Here I’ll show Droplet deployment (SSH + Docker) and App Platform variant.
-
Secrets in GitHub repo (Settings → Secrets and Variables → Actions):
DO_API_TOKEN
→ DigitalOcean Personal Access TokenDO_SSH_KEY
→ private SSH key (if deploying to Droplet via SSH)DO_SSH_HOST
→ Droplet IP (e.g.,157.230.x.x
)DO_SSH_USER
→ usuallyroot
or a created user
-
Dockerfile in your repo (for container build).
Example Dockerfile
:
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install --production
COPY . .
EXPOSE 3000
CMD ["npm", "start"]
2. GitHub Action Workflow (CI/CD)
Create: .github/workflows/deploy.yml
name: CI/CD to DigitalOcean
on:
push:
branches:
- main # deploys when main branch is updated
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
# 1. Checkout code
- name: Checkout repository
uses: actions/checkout@v3
# 2. Set up Docker
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
# 3. Log in to DigitalOcean Container Registry (if using DOCR)
- name: Login to DO Container Registry
uses: docker/login-action@v2
with:
registry: registry.digitalocean.com
username: do
password: $
# 4. Build & Push Docker Image
- name: Build and Push Docker image
run: |
IMAGE=registry.digitalocean.com/my-registry/myapp:$(date +%s)
echo "IMAGE=$IMAGE" >> $GITHUB_ENV
docker build -t $IMAGE .
docker push $IMAGE
# 5. Deploy to Droplet via SSH
- name: Deploy via SSH
uses: appleboy/ssh-action@v1.0.3
with:
host: $
username: $
key: $
script: |
docker pull $IMAGE
docker stop myapp || true
docker rm myapp || true
docker run -d -p 80:3000 --name myapp $IMAGE
3. App Platform Alternative (simpler)
If you prefer DigitalOcean App Platform (PaaS, no Droplet maintenance):
- Create
spec.yaml
in root:
name: myapp
services:
- name: web
github:
branch: main
repo: your-username/your-repo
deploy_on_push: true
run_command: "npm start"
build_command: "npm install"
environment_slug: node-js
http_port: 3000
instance_size_slug: basic-xxs
instance_count: 1
- Then create a GitHub Action to trigger redeploy via API:
jobs:
deploy-app-platform:
runs-on: ubuntu-latest
steps:
- name: Trigger DigitalOcean App Platform Deployment
run: |
curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $" \
"https://api.digitalocean.com/v2/apps/<APP_ID>/deployments"
Replace <APP_ID>
with your App Platform ID.
4. CI/CD Flow Explained
-
Commit → Push to GitHub
main
branch → GitHub Action starts. -
Docker Build & Push → Image pushed to DigitalOcean Container Registry.
-
SSH Deployment (Droplet) → Pulls the image, restarts container.
-
App Platform (if used) → API call redeploys new code automatically.
5. Security Notes
- Use
DO_SSH_KEY
with least privilege user (notroot
ideally). - Use GitHub Environments for staging/prod separation.
- Consider monitoring with DigitalOcean’s metrics + GitHub Action notifications.