CI/CD for Startups: Where to Start Without a DevOps Engineer
Setting up CI/CD as a solo technical founder or CTO is intimidating. Tutorials assume infrastructure already exists, YAML configs look cryptic, and dozens of tools compete for your attention. No wonder most startups still deploy manually.
Yet in my work with startups across France — from Paris to Bordeaux to Montpellier — I've seen that a working pipeline rarely takes more than a day to set up. The peace of mind is immediate.
With CI/CD in place, deploying becomes as routine as a git push. You do it 10 times a day without thinking about it.
The 3 minimum components
Component 1: GitHub Actions
GitHub Actions is the automation engine. On every push to main, it triggers your pipeline: tests, build, deploy. Free up to 2,000 minutes/month, integrated natively with your repo.
Component 2: Docker
Docker packages your app with all its dependencies into a portable image. It runs identically on your machine, in CI, and in production. No more *"it works on my machine"*.
Component 3: A compatible host
A simple VPS is enough to start: DigitalOcean, Hetzner, or Scaleway (French provider). Budget €6–€20/month. Already on AWS? ECS or App Runner integrate seamlessly.
Concrete example: a pipeline in 50 lines
# Stage 1: dependencies
FROM node:20-alpine AS deps
WORKDIR /app
COPY package*.json ./
RUN npm ci
# Stage 2: build
FROM node:20-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build
# Stage 3: production image (minimal)
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
EXPOSE 3000
CMD ["node", "server.js"]# .github/workflows/deploy.yml
name: CI/CD
on:
push:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: '20', cache: 'npm' }
- run: npm ci && npm test
deploy:
needs: test
runs-on: ubuntu-latest
permissions: { contents: read, packages: write }
steps:
- uses: actions/checkout@v4
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/build-push-action@v5
with:
push: true
tags: ghcr.io/${{ github.repository }}:latest
- uses: appleboy/ssh-action@v1
with:
host: ${{ secrets.VPS_HOST }}
username: ${{ secrets.VPS_USER }}
key: ${{ secrets.VPS_SSH_KEY }}
script: |
docker pull ghcr.io/${{ github.repository }}:latest
docker stop app 2>/dev/null || true
docker rm app 2>/dev/null || true
docker run -d --name app --restart unless-stopped \
-p 3000:3000 --env-file /home/deploy/.env \
ghcr.io/${{ github.repository }}:latest
sleep 5 && curl -sf http://localhost:3000/api/healthClassic mistakes to avoid
- ▸No staging environment — deploy to staging first, production on tags
- ▸Skipping tests — if tests fail, the deployment should never run
- ▸Secrets in code — use GitHub Secrets for CI,
.envfiles on the server - ▸No observability — add Sentry (free tier) before your first real users
When to call a freelance DevOps engineer
This minimal setup covers MVP needs. Escalate to a freelance DevOps when: traffic outgrows a single VPS, you need Kubernetes or ECS with auto-scaling, compliance requirements apply (SOC 2, ISO 27001), or the team is spending more time on deployments than on the product.
Conclusion
CI/CD isn't just for big engineering teams. GitHub Actions + Docker + a €10/month VPS gets you a working pipeline in hours. Start simple, evolve as your product grows. Questions? Let's talk.
Zouhir Echarif El Idrissi El Kandri
Freelance DevOps & Développeur Web