A production-grade walkthrough of Buddy CI/CD for web developers and DevOps engineers. Learn to build visual pipelines, sandbox actions, cache Docker layers, and deploy to AWS, Vercel, and Kubernetes with zero downtime.
Buddy is a modern continuous integration and delivery platform that makes DevOps accessible to development teams. Unlike Jenkins (which requires heavy XML configuration) or GitHub Actions (which demands YAML expertise), Buddy uses a visual GUI builder where you connect pipeline steps like building blocks.
| Concept | Description |
|---------|-------------|
| Pipeline | A sequence of automated actions triggered by a Git push, schedule, or API event |
| Action | A single step in a pipeline (e.g., Build Docker Image, Run Tests, Deploy to AWS) |
| Sandbox | Each action runs in an isolated Docker container with its own filesystem and environment |
| Trigger | Events that start pipelines: push, pull request, schedule, manual, API call |
After signing up at buddy.works, connect your GitHub, GitLab, or Bitbucket repository:
# buddy.yml — declarative pipeline config (alternative to GUI)
- pipeline: "Production Deployment"
trigger_mode: ON_EVERY_PUSH
refs:
- refs/heads/main
actions:
- action: "Install Dependencies"
type: BUILD
docker_image_name: node
docker_image_tag: "20-alpine"
execute_commands:
- npm ci
- npm run lint
- npm run build
# Optimized Dockerfile for Buddy's layer caching
FROM node:20-alpine AS deps
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
FROM node:20-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build
FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static
COPY --from=builder /app/public ./public
EXPOSE 3000
CMD ["node", "server.js"]
Buddy's Build Cache feature stores Docker image layers between pipeline executions. This dramatically cuts build times.
Without cache: npm ci (2 min 30s) + Docker build (4 min) = 6m 30s total
With Buddy cache: npm ci (8s) + Docker build (45s) = 53s total (87% faster)
In the Build Docker Image action:
package-lock.json hashBuddy provides project-level and pipeline-level variable stores.
# Set secrets in Buddy UI: Variables → Add Variable
NEXT_PUBLIC_GA_ID=G-XXXXXXXX
DATABASE_URL=postgresql://...
AWS_ACCESS_KEY_ID=AKIAXXXXXXXX
AWS_SECRET_ACCESS_KEY=xxxxxxxxxxxxx
VERCEL_TOKEN=xxxxxxxx
Best Practices:
$VARIABLE_NAME# buddy.yml — Vercel deployment action
- action: "Deploy to Vercel Production"
type: VERCEL
token: "$VERCEL_TOKEN"
project: "ajitdev-portfolio"
team: "ajitdev01"
scope: "production"
cache: false
This triggers a Vercel deployment via the Vercel REST API, streams build logs directly in Buddy's interface, and fails the pipeline if the deployment returns an error.
# buddy.yml — Zero-downtime EC2 deployment
- action: "SSH Deploy to EC2 (Blue-Green)"
type: SSH_COMMANDS
host: "$EC2_HOST"
port: "22"
login: "ec2-user"
authentication_mode: PRIVATE_KEY
private_key: "$EC2_PRIVATE_KEY"
commands:
- docker pull ajitdev/api:latest
- docker stop api-green || true
- docker rm api-green || true
- docker run -d --name api-green -p 3001:3000 ajitdev/api:latest
- curl --retry 5 --retry-delay 3 http://localhost:3001/healthz
- docker stop api-blue || true
- docker rename api-green api-blue
- echo "Blue-green deployment successful"
// app/api/healthz/route.ts — Health check endpoint
import { NextResponse } from 'next/server';
export async function GET() {
return NextResponse.json({
status: 'healthy',
timestamp: new Date().toISOString(),
version: process.env.npm_package_version ?? '1.0.0',
});
}
export const runtime = 'edge';
# buddy.yml — Kubernetes rolling update
- action: "Deploy to EKS"
type: KUBERNETES_APPLY_DEPLOYMENT_CONFIGURATION
auth_mode: KUBERNETES_CERTIFICATE
server: "$EKS_SERVER_URL"
client_ca: "$EKS_CA"
client_cert: "$EKS_CERT"
client_key: "$EKS_KEY"
config_path: "k8s/deployment.yaml"
record: true
# k8s/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: ajitdev-web
namespace: production
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
selector:
matchLabels:
app: ajitdev-web
template:
metadata:
labels:
app: ajitdev-web
spec:
containers:
- name: web
image: ajitdev/web:${BUDDY_EXECUTION_ID}
ports:
- containerPort: 3000
livenessProbe:
httpGet:
path: /api/healthz
port: 3000
initialDelaySeconds: 10
periodSeconds: 5
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "500m"
# Complete buddy.yml for a Next.js application
- pipeline: "Full Production Pipeline"
trigger_mode: ON_EVERY_PUSH
refs:
- refs/heads/main
actions:
# Step 1: Install and test
- action: "Lint & Type Check"
type: BUILD
docker_image_name: node
docker_image_tag: "20-alpine"
cached_dirs:
- path: node_modules
key: package-lock.json
execute_commands:
- npm ci
- npx tsc --noEmit
- npm run lint
# Step 2: Security scan
- action: "Vulnerability Scan"
type: BUILD
docker_image_name: aquasec/trivy
docker_image_tag: latest
execute_commands:
- trivy fs --severity HIGH,CRITICAL .
# Step 3: Build Docker image
- action: "Build Docker Image"
type: DOCKERFILE
dockerfile_path: Dockerfile
image_name: "ajitdev/web"
image_tag: "$BUDDY_EXECUTION_REVISION"
cache_build_args: true
# Step 4: Push to registry
- action: "Push to DockerHub"
type: DOCKER_PUSH
docker_image_name: "ajitdev/web"
docker_image_tag: "$BUDDY_EXECUTION_REVISION"
login: "$DOCKER_USERNAME"
password: "$DOCKER_PASSWORD"
# Step 5: Deploy to production
- action: "Deploy to Vercel"
type: VERCEL
token: "$VERCEL_TOKEN"
project: "ajitdev-portfolio"
scope: "production"
# Step 6: Notify Slack
- action: "Slack Deployment Notification"
type: SLACK
webhook_url: "$SLACK_WEBHOOK"
channel: "#deployments"
content: "✅ Production deployment completed for commit $BUDDY_EXECUTION_REVISION"
Buddy's Execution History tab shows:
# Enable failure notifications
- action: "Alert on Failure"
type: EMAIL
recipients:
- "ajitk23192@gmail.com"
subject: "⚠️ Pipeline Failed: $BUDDY_PIPELINE_NAME"
body: "Execution $BUDDY_EXECUTION_ID failed at step: $BUDDY_FAILED_ACTION"
trigger: ON_FAILURE
| Feature | Buddy | GitHub Actions | |---------|-------|----------------| | UI Builder | ✅ Visual GUI | ❌ YAML only | | Docker Cache | ✅ Smart layer cache | ⚠️ Manual setup needed | | Build Speed | ✅ ~80% faster | Standard | | Pricing | $75/month unlimited | Free for public repos | | Marketplace | 100+ integrations | 16,000+ actions | | Self-hosted | ✅ Supported | ✅ Supported | | Open Source | ❌ Commercial | ✅ Open source workflows |