Skip to content

CI/CD for Teams Without a DevOps Team

A
abemon
| | 11 min read | Written by practitioners
Share

The real problem: deploying is scary

We know the pattern. A team of 3-8 developers. The “deployment process” is: someone SSHs into the server, runs git pull, prays, and executes the build commands. If something breaks, that same someone spends the next two hours fixing it manually while the team waits.

Deployments happen on Friday at 6pm (“so we don’t bother users”). Nobody wants to deploy. Features accumulate on a development branch for weeks. When they finally merge, the conflict is epic and the deployment is a coin flip.

If this sounds familiar, you do not need a DevOps team. You need a CI/CD pipeline that a development team can maintain without a dedicated profile. This article explains how to set one up with tools that cost between EUR 0 and EUR 50 per month.

What CI/CD is (without the jargon)

Continuous Integration (CI): every time someone pushes to a branch, tests and quality checks run automatically. If they fail, the branch cannot be merged. This prevents broken code from reaching the main branch.

Continuous Deployment (CD): every time the main branch receives a merge, it deploys automatically to production (or to a staging environment, depending on your setup). This prevents change accumulation and reduces the risk of each individual deployment.

Together, CI/CD turns “deploying” from a traumatic event into something that happens 5 times a day without anyone thinking twice.

The minimum viable stack

You do not need Jenkins. You do not need Kubernetes. You do not need Terraform. You need three things.

1. GitHub Actions (or GitLab CI)

GitHub Actions is free for public repositories and includes 2,000 minutes/month on the free plan for private repositories. For most small teams, that is enough. If you exceed it, the Team plan at $4/user/month includes 3,000 minutes.

A minimum viable pipeline has three stages:

Lint and format. Verify that code follows team conventions. ESLint for JavaScript/TypeScript, Ruff for Python, PHP_CodeSniffer for PHP. Time: 10-30 seconds. This stage is cheap and catches 40% of problems before anyone reviews them manually.

Tests. Run unit and integration tests. If your project has no tests, start here: write tests for the 5 most critical functions. You do not need 90% coverage on day one. You need the critical paths covered. Time: 30 seconds to 5 minutes.

Build. Compile the project and verify the build succeeds. For Next.js, npm run build. For WordPress with a custom theme, verify the theme compiles. For Python, verify dependencies resolve. Time: 1-5 minutes.

If all three stages pass, the branch is ready for review. If any fails, the PR is marked as failed and cannot be merged.

2. A hosting service with automatic deploy

Deploy should trigger when a merge hits the main branch. No SSH, no manual scripts, no prayers.

Railway. Our favorite for small teams. Connect your repository, configure the production branch, and every push deploys automatically. Supports Node.js, Python, PHP, Go, and virtually anything that runs in a container. Starter plan: $5/month. We use it for all our Railway WordPress projects and for the APIs that serve our AI agents.

Vercel. If your project is Next.js, Vercel is the obvious choice. Automatic deploy, preview deployments for every PR, and a global CDN. Generous free plan for small projects.

Render. Similar to Railway, with a slightly different pricing model. Good included database support.

Traditional hosting (cPanel, Hostinger). You can configure a webhook that executes a deploy script when GitHub Actions completes successfully. Not as elegant, but it works. We have set this up for several WordPress sites on Hostinger using GitHub Actions that SSH into the server and run the deploy commands.

3. A notification channel

The pipeline needs to communicate results to the team. A message in Slack or Teams when a deploy completes (or fails) is sufficient. GitHub Actions has native integrations with both. If you use something else, a webhook to a bot is trivial to configure.

Do not underestimate this piece. Without notifications, nobody looks at the pipeline until something fails visibly in production.

The pipeline we run on our projects

This is the actual pipeline we execute for a typical project (Next.js or WordPress):

Push to feature branch
  └── GitHub Actions: lint + tests + build
       ├── Fails → PR marked as failed, notification
       └── Passes → PR ready for review

Review approved + merge to main
  └── GitHub Actions: full build
       ├── Fails → Urgent notification, merge auto-reverted
       └── Passes → Automatic deploy to staging

Tests on staging (manual or automated)
  └── Manual approval (one click in GitHub Actions)
       └── Deploy to production + notification

For low-risk projects (blogs, corporate websites), we remove the staging step and deploy directly to production. For projects with user data (ERPs, transactional platforms), staging is mandatory.

Total time from merge to production: 3-8 minutes for projects without staging, 3-8 minutes plus manual approval for projects with staging. Compare that with the hour you spent SSHing.

The four mistakes we see in teams without DevOps

Mistake 1: No tests, therefore no CI. “We don’t have tests so CI doesn’t help us.” False. Lint and build verification are already CI. They catch real problems. Add tests incrementally: 5 tests this week, 5 next week. In two months you have a functional safety net.

Mistake 2: Pipelines that take 20 minutes. If your pipeline takes more than 10 minutes, developers will stop paying attention to it. Optimize: run lint and tests in parallel, cache dependencies (node_modules, pip cache), use lightweight Docker images. Our slowest pipeline takes 6 minutes. Most are 2-4.

Mistake 3: Deploying to production without automatic rollback. Having a zero downtime deployment strategy is fundamental. Railway and Vercel have one-click rollback. If your hosting service does not, configure it yourself: keep the last 3 deployed versions and a script that reverts to the previous one. This is not optional. It is what allows you to deploy without fear.

Mistake 4: Not protecting the main branch. Without branch protection, someone will push directly to main at 11pm “because it’s a small change.” Configure branch protection in GitHub: require PR, require CI passing, require at least 1 approval. Five minutes of configuration that prevent days of debugging.

Real costs

For a team of 5 developers with 2-3 active repositories:

ComponentToolCost/month
CI/CDGitHub Actions (free plan)EUR 0
HostingRailway StarterEUR 5-20
NotificationsSlack free tierEUR 0
MonitoringUptimeRobot freeEUR 0
TotalEUR 5-20

If you need more CI minutes or heavier test execution:

ComponentToolCost/month
CI/CDGitHub Team (5 users)EUR 20
HostingRailway ProEUR 20-50
NotificationsSlack ProEUR 7.25/user
MonitoringBetter UptimeEUR 20
TotalEUR 96-127

Both scenarios are orders of magnitude cheaper than a dedicated DevOps engineer (EUR 4,000-6,000/month in most European markets, or $8,000-12,000/month in the US).

When you DO need a dedicated DevOps person

A CI/CD pipeline solves 80% of deployment problems for a small team. But there are scenarios where you need more:

  • Multiple environments (dev, staging, production, demo) with different configurations
  • Infrastructure as code because your application needs queues, databases, caches, and auxiliary services
  • Compliance requiring deployment auditing, environment segregation, and full traceability
  • Auto-scaling because your traffic is highly variable

If you are in any of these cases, a DevOps profile (internal or external) makes sense. But even then, start with the basic pipeline and add complexity only when you need it. Premature infrastructure optimization is the DevOps equivalent of premature code optimization: it wastes time and adds maintenance burden.

For teams that need CI/CD but lack internal capacity to set it up, our cloud and DevOps team configures complete pipelines in 1-2 weeks. We also offer managed services that include ongoing pipeline operation.

If your project runs on WordPress on Railway or traditional hosting, we have specific experience with both platforms. You can also explore our approach to infrastructure in our development services section.

About the author

A

abemon engineering

Engineering team

Multidisciplinary engineering, data and AI team headquartered in the Canary Islands. We build, deploy and operate custom software solutions for companies at any scale.