f in x
DevOps and CI/CD: The Definitive Pillar Guide to Automated Pipelines and Painless Deployments
> cd .. / HUB_EDITORIALE
Sviluppo di siti web

DevOps and CI/CD: The Definitive Pillar Guide to Automated Pipelines and Painless Deployments

[2026-06-16] Author: Ing. Calogero Bono

The problem you've seen (and we've seen dozens of times)

Your team pushes a new feature and the site crashes. Or you spend days manually configuring servers, forgetting a permission. Or tests only run when the 'senior' dev is around, and when they're not, you deploy blind. If any of this sounds familiar, your development cycle is the bottleneck. We at Meteora Web have been there. Since 2017 we've helped businesses move from chaotic manual releases to automated pipelines that cut errors and downtime. This guide covers everything you need to build a solid DevOps culture and working CI/CD pipelines – from dev environment to production server.

DevOps is not a tool, it's a culture (and a way to stop fighting)

Too often we see teams buy Jenkins, install GitLab, then keep working the same way: devs write code, throw it over the wall to ops, and when something breaks blame flies. DevOps removes that wall. It doesn't mean everyone does everything, but dev and ops share goals, metrics and processes. Infrastructure is code, deployments are repeatable, tests are automated.

Where to start practically

Before touching any tool, answer three questions:

  • How long does it take from commit to production deploy?
  • How many manual steps are in between?
  • How often does a deploy break something that worked?

If the first answer is "days" and the third is "often", you have your first goal: reduce time and increase confidence. You don't need everything at once. Start with one repository, one staging environment, a pipeline that runs tests and deploys to staging automatically. Then expand.

GitHub Actions: the integrated CI/CD we use almost always

For new projects, GitHub Actions is the quickest choice. It's integrated with your repo, no server management, clean YAML syntax. We at Meteora Web use it for custom Laravel, Vue and WordPress projects. Here's a concrete example: workflow that runs tests, builds, and deploys to a Linux server via SSH.

name: Deploy to production

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: '8.2'
          extensions: mbstring, pdo, bcmath

      - name: Install dependencies
        run: composer install --no-dev --optimize-autoloader

      - name: Run tests
        run: php artisan test

      - name: Deploy via SSH
        uses: appleboy/ssh-action@v1.0.3
        with:
          host: ${{ secrets.DEPLOY_HOST }}
          username: ${{ secrets.DEPLOY_USER }}
          key: ${{ secrets.DEPLOY_KEY }}
          script: |
            cd /var/www/project
            git pull origin main
            composer install --no-dev --optimize-autoloader
            php artisan migrate --force
            php artisan optimize

Secrets matter: never write host, user or keys in the YAML file. Use GitHub secrets. We often see projects with credentials in plain text – that's the first mistake we fix.

Sponsored Protocol

Smart triggers

Not everything needs to go to production on every push. Use filters: branches, paths, tags. For example, run the pipeline only if you touch files in src/ or tests/, not when you edit documentation.

CI pipeline: automated linting, testing and building

CI (Continuous Integration) is the heart of the process. Every time a dev pushes, the platform automatically runs linting (ESLint, PHP_CodeSniffer), unit tests, static analysis, and build. If any step fails, the pipeline blocks and the team is notified. No broken code reaches deployment.

Practical steps for a solid CI

  • Lint: enforce shared rules and block the pipeline if they fail.
  • Unit tests: minimum coverage (e.g. 70%), but meaningful tests beat inflated percentages.
  • Build: compile assets (npm run build), verify the package is deployable.
  • Security scan: tools like Dependabot or Snyk for dependency vulnerabilities. We always integrate them.

A tip: don't run the full test suite on every push to every branch. For feature branches, run only fast unit tests. The full suite goes on main branches before merge.

Sponsored Protocol

CD: automated deploy to staging and production

Continuous Delivery (CD) is the natural next step: after CI passes, code is automatically deployed to staging, and with a click (or automatically after approval) to production. The goal is to make deployment a boring, repeatable operation, not a stressful event.

Staging first

Every production deploy should pass through staging first. Staging must be identical to production in terms of infrastructure, data (anonymized) and configurations. We use the same Ansible playbook for both, changing only the target host.

GitLab CI/CD: the self-hosted alternative with full control

If for compliance or sensitive data you cannot rely on GitHub Actions, GitLab CI/CD with self-hosted runners is the choice. We at Meteora Web chose GitLab for several projects handling health data in Southern Italy: full control, no minute limits, private repos without hidden costs.

Quick comparison

FeatureGitHub ActionsGitLab CI/CD
Hosted free runners2000 min/month (with public repo)400 min/month
Self-hosted runnerYesYes, native
Container registryGHCRGitLab Container Registry
Auto DevOpsNoYes (predefined templates)

GitLab CI/CD is configured with a .gitlab-ci.yml file in the root. Here's an example that deploys to a server using Docker after testing and building:

stages:
  - test
  - build
  - deploy

variables:
  DOCKER_TLS_CERTDIR: "/certs"

test:
  stage: test
  image: php:8.2-cli
  script:
    - composer install
    - php artisan test

build:
  stage: build
  image: docker:latest
  services:
    - docker:dind
  script:
    - docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA .
    - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA

deploy:
  stage: deploy
  image: alpine:latest
  script:
    - apk add --no-cache openssh-client
    - eval $(ssh-agent -s)
    - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - > /dev/null
    - ssh server.com "docker pull $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA && docker stack deploy ..."

Note: secrets (protected variables) are set in the CI/CD Settings of the project.

Sponsored Protocol

Infrastructure as Code with Terraform: stop configuring manually

If you still SSH into servers to install packages or tweak Nginx, you're wasting time and compromising security. Infrastructure as Code (IaC) means describing servers, networks, databases and DNS in versioned files. Terraform is the most popular tool: you declare the desired state and it applies it.

Providers, state and modules

Each provider (AWS, DigitalOcean, Cloudflare) has documentation. The state file (terraform.tfstate) tracks real resources – keep it in a remote backend (S3, GitLab). Reusable modules avoid rewriting the same code for each project.

provider "digitalocean" {
  token = var.do_token
}

resource "digitalocean_droplet" "web" {
  image  = "ubuntu-22-04-x64"
  name   = "web-prod-01"
  region = "fra1"
  size   = "s-2vcpu-4gb"
  ssh_keys = [var.ssh_key_id]
}

output "ip" {
  value = digitalocean_droplet.web.ipv4_address
}

We use Terraform for every new project: provisioning servers, databases, load balancers and domains in a single command. You never forget a firewall or a DNS record.

Ansible: server configuration and deploy without surprises

Ansible complements Terraform: while Terraform creates infrastructure, Ansible configures it (installs PHP, Nginx, sets up vhost, deploys the application). It's agentless: just SSH and Python on the server.

---
- name: Deploy Laravel application
  hosts: webservers
  become: yes
  tasks:
    - name: Ensure git is installed
      apt:
        name: git
        state: present

    - name: Clone repository
      git:
        repo: 'https://github.com/user/project.git'
        dest: /var/www/project
        version: main

    - name: Install composer dependencies
      composer:
        command: install
        working_dir: /var/www/project
        no_dev: yes

    - name: Set permissions
      file:
        path: /var/www/project/storage
        state: directory
        mode: '0775'
        owner: www-data

Combine Terraform + Ansible in a CI/CD pipeline: after terraform apply, run an Ansible playbook to configure and deploy. Full automation.

Sponsored Protocol

Feature flags: continuous deployment without breaking production

Even with perfect pipelines, some features need gradual rollout. Feature flags (toggles) let you deploy code turned off and activate it later without a new deploy. Tools like LaunchDarkly or a simple database flags managed by the app. In Laravel projects we use a FeatureFlag model with cache: just an admin panel to enable a new function for a percentage of users.

Concrete benefit

Deploy the code on Monday, test in production on a small group. If it works, increase the percentage. If something breaks, disable the flag in seconds – no rollback. Reduces risk and enables more frequent releases.

Blue-Green and Canary deployment: real zero downtime

Deploying without stopping the service is possible with two complementary strategies.

Blue-Green

Maintain two identical environments (blue and green). Traffic points to blue. Deploy the new version on green, test, then switch the load balancer to green. If something goes wrong, switch back to blue. Zero downtime, instant rollback. Cost: double the servers.

Canary

Instead of a full switch, route a small percentage of traffic to the new version (e.g., 5% of users). Monitor errors and latency. If stable, increase gradually to 100%. Tools: Kubernetes (with service mesh like Istio) or configurable load balancers. For smaller projects, a simple Nginx proxy with weighted upstream can simulate canary.

Monitoring and alerting: if you don't measure, you can't improve

CI/CD pipelines and automated infrastructure are useless if you don't know whether production is healthy. Monitoring is not optional – it's the feedback loop that closes the DevOps cycle.

Sponsored Protocol

Prometheus + Grafana

Prometheus collects metrics (CPU, memory, request rate, error rate). Grafana visualizes them in dashboards. You can also export custom metrics from your application (e.g., number of processed orders, average response time).

SLO/SLA

Service Level Objective (SLO): the threshold you commit to (e.g., uptime 99.9%, latency under 200ms). Service Level Agreement (SLA) is the contract with the customer. Set alerts when you exceed the SLO burn rate, not after it's already broken.

# example alert rule in Prometheus
groups:
  - name: example
    rules:
      - alert: HighErrorRate
        expr: job:request_errors:rate1m{job="api"} > 0.05
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "Error rate above 5% for 5 minutes"

We always include a basic Prometheus + Grafana setup in projects that require guaranteed uptime. The cost of neglected monitoring is much higher than a few hours of setup.

In summary – what to do now

  1. Audit your current process. Time the manual steps. Pick a pilot project (not the most critical one).
  2. Set up a CI pipeline. GitHub Actions or GitLab CI: start with lint and tests on every push to the main branch.
  3. Add automated staging. Deploy to staging automatically after CI passes.
  4. Automate infrastructure. Terraform for provisioning, Ansible for configuration. Version everything.
  5. Introduce feature flags. Even simple: a configuration file in the repository.
  6. Choose a deployment strategy. Blue-green if you have budget, canary if you have variable traffic.
  7. Monitor. At least uptime and error rate. Then application metrics.

Each step reduces risk and increases release frequency. You don't need to do everything at once: start with one piece, measure improvement, continue. We've been guiding clients through this journey for 8 years. If you want to talk, we're based in Sciacca but work everywhere. The digital divide is closed one working pipeline at a time – not with slides.

Ing. Calogero Bono

> AUTHOR_EXTRACTED

Ing. Calogero Bono

Ingegnere Informatico, co-fondatore di Meteora Web. Esperto in architetture software, sicurezza informatica e sviluppo sistemi scalabili.
[ Read Full Dossier ]

> METEORA_WEB // DIGITAL AGENCY

We build the digital presence your business deserves.

Websites, social media, online advertising, e-commerce and high-performance hosting, engineered with method by computer engineers in Sciacca, for all of Italy.

> MW_JOURNAL

> READ_ALL()