Automating CI/CD Pipelines with GitHub Actions and Docker in 2026

6 دقیقه لوستل
Automating CI/CD with GitHub Actions & Docker 2026
Automating CI/CD with GitHub Actions & Docker 2026

Why CI/CD Still Feels Like a Chore (and How to Fix It in 2026)

Every developer knows the pain: you push code, wait for a manual build, ssh into a server, pull the latest image, restart containers… and hope nothing breaks. In 2026, that’s no longer acceptable. With GitHub Actions maturing and Docker becoming the universal runtime, automating your entire pipeline is not only possible it’s shockingly straightforward once you see the pattern. This guide walks through a complete, production‑ready CI/CD workflow that builds a Python FastAPI app, runs tests, pushes the image to Docker Hub, and deploys to a cloud VM. No magic, no over‑engineering, just a pipeline that saves hours every week.

What You’ll Actually Build

We’ll create a single GitHub Actions workflow that triggers on every push to main. It will:

1. Check out the code 2. Run unit tests inside a temporary container 3. Build a production Docker image 4. Push the image to Docker Hub 5. SSH into a server and deploy the new container

By the end, you’ll have a secure, idempotent pipeline you can adapt for Node.js, Go, or any stack.

Project Setup: A Simple FastAPI App

Let’s start with a minimal app. Inside your repo, create main.py and a Dockerfile.

from fastapi import FastAPI\napp = FastAPI()\n\n@app.get("/")\ndef read_root():\n return {"hello": "world"}
FROM python:3.12-slim\nWORKDIR /app\nCOPY requirements.txt .\nRUN pip install --no-cache-dir -r requirements.txt\nCOPY . .\nCMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80"]

Don’t forget a requirements.txt with fastapi and uvicorn. Push this to GitHub. We’re ready for the pipeline.

Writing the GitHub Actions Workflow

In your repo, create .github/workflows/deploy.yml. GitHub automatically picks it up. The workflow will have three jobs: test, build-push, and deploy. They run sequentially, and we’ll cache Docker layers to speed things up.

name: CI/CD Pipeline\n\non:\n push:\n branches: [ main ]\n\njobs:\n test:\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v4\n - name: Build test image\n run: docker build -t fastapi-test .\n - name: Run tests\n run: docker run --rm fastapi-test pytest .\n\n build-and-push:\n needs: test\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v4\n - name: Log in to Docker Hub\n uses: docker/login-action@v3\n with:\n username: {{ secrets.DOCKER_USERNAME }}\n password: {{ secrets.DOCKER_PASSWORD }}\n - name: Build and push\n uses: docker/build-push-action@v5\n with:\n push: true\n tags: yourusername/fastapi-app:latest\n\n deploy:\n needs: build-and-push\n runs-on: ubuntu-latest\n steps:\n - name: Deploy via SSH\n uses: appleboy/ssh-action@v1.0.3\n with:\n host: {{ secrets.SERVER_HOST }}\n username: {{ secrets.SERVER_USER }}\n key: {{ secrets.SERVER_SSH_KEY }}\n script: |\n docker pull yourusername/fastapi-app:latest\n docker stop fastapi-app || true\n docker rm fastapi-app || true\n docker run -d --name fastapi-app -p 80:80 yourusername/fastapi-app:latest That’s the entire pipeline. When you push to main, tests run first. If they pass, the image is built and pushed to Docker Hub. Finally, the server pulls the new image and restarts the container. Zero‑downtime deploys can be added later with a blue‑green strategy, but this gets you 90% of the way. Why This Works So Well in 2026 GitHub Actions now has first‑class Docker cache support (docs.docker.com) that reduces build times dramatically. The docker/build-push-action v5 automatically manages multi‑arch images if needed. And the whole pipeline stays inside GitHub, so you don’t need Jenkins or a separate orchestrator. Secrets are stored in the repo’s settings and never exposed in logs assuming you use the secrets context correctly. Adding Real Value: Test Parallelisation and Security Scanning A basic pipeline is good, but production requires more. Here are two powerful additions you can drop into the same workflow. Parallelise tests with matrix builds: strategy:\n matrix:\n python-version: [3.11, 3.12]\nsteps:\n - uses: actions/setup-python@v5\n with:\n python-version: {{ matrix.python-version }}\n - run: pip install -r requirements.txt && pytest

Scan the final image for vulnerabilities before pushing:

- name: Run Trivy vulnerability scanner\n uses: aquasecurity/trivy-action@0.24.0\n with:\n image-ref: yourusername/fastapi-app:latest\n format: 'table'\n exit-code: '1'\n severity: 'CRITICAL,HIGH'

Insert the scanner between build and push, and the pipeline will fail if a critical CVE is found. This level of automation is what makes a CI/CD setup actually trustworthy.

Secret Management That Doesn’t Leak

One common mistake: hardcoding credentials in the workflow. Instead, go to your GitHub repo → Settings → Secrets and variables → Actions, and add DOCKER_USERNAME, DOCKER_PASSWORD, SERVER_HOST, SERVER_USER, and SERVER_SSH_KEY. The SSH key should be a private key whose public counterpart is already in the server’s ~/.ssh/authorized_keys. Limit the key’s permissions on the server for extra security. Now no sensitive data lives in your code.

Real‑World Links and References

The official documentation is always the best friend: • GitHub Actions DocumentationDocker Build with GitHub ActionsSSH Action by appleboyTrivy Action for vulnerability scanning

These are living resources that keep up with the latest changes in 2026.

Common Pitfalls and How to Avoid Them

1. “It works on my machine” – your Docker image is the only artifact that should reach production. Running tests inside the same base image ensures consistency.

2. Over‑caching – Docker layer caching is great, but caching the whole pip install step without invalidating on requirements change can mask dependency bugs. Use cache-from and cache-to with mode=max only for stable layers.

3. Long‑lived SSH keys – rotate your deploy keys regularly, and consider using short‑lived GitHub OIDC tokens to authenticate to cloud providers instead of static credentials. In 2026, most platforms support OIDC natively.

4. Ignoring pipeline failures – set up branch protection rules so that the deploy job can only run if tests pass, and require status checks before merging.

Wrap‑Up: From Push to Production in Minutes

The workflow we just built is not a toy. It’s the same pattern used by teams shipping hundreds of times per day. By combining GitHub Actions, Docker, and a sprinkle of security scanning, you turn every git push into a safe, automated deployment. That means fewer late‑night debugging sessions, faster feedback loops, and a release process you can actually trust.

In 2026, automation isn’t optional it’s the baseline. The pipeline described here gives you that baseline without locking you into any proprietary platform. Customize it for your own stack, add notifications (Slack, Discord, email), and you’ll wonder why you ever deployed manually.

سوالات متداول

مراحل انجام کار

  1. 1
    Set up the GitHub repository
    Create a new repository on GitHub, add your FastAPI code and Dockerfile, and push the initial commit. Enable Actions from the repo settings if not already active.
  2. 2
    Store secrets securely
    Go to Settings > Secrets and variables > Actions. Add DOCKER_USERNAME, DOCKER_PASSWORD, SERVER_HOST, SERVER_USER, and SERVER_SSH_KEY. The SSH key must be the private key matching a public key on the target server.
  3. 3
    Create the workflow file
    Inside .github/workflows/deploy.yml, paste the full pipeline YAML shown in the article. Ensure branch triggers match your default branch (main or master). Commit and push this file.
  4. 4
    Trigger the first run
    Push any change to the main branch. GitHub Actions will automatically start the workflow. Monitor the Actions tab in your repository to see the test, build-push, and deploy jobs execute in sequence.
  5. 5
    Add security scanning
    Insert the Trivy scan step before the push-to-registry step. Set the severity threshold to HIGH,CRITICAL and exit-code 1 to block insecure images. This keeps vulnerable dependencies out of production automatically.
شریکول: X / Twitter LinkedIn Telegram

اړوند مقالې