An automated CI/CD pipeline for a FastAPI application containerized with Docker, deployed on a Debian (VMware) virtual infrastructure via a GitHub Self-Hosted Runner.
Features • Architecture • Installation • Usage • Author
- ⚡ Automatic deployment on every
pushtomain - 🧪 Unit tests automatically executed with Pytest
- 🐳 Docker containerization with automatic restart
- 🏠 100% self-hosted infrastructure, zero cloud costs
- 📖 Auto-generated Swagger documentation by FastAPI
flowchart LR
A[💻 Developer] -->|git push| B[📦 GitHub Repository]
B -->|Trigger| C[⚙️ GitHub Actions CI]
C -->|pytest| D{Tests OK?}
D -->|✅| E[🖥️ Debian VM<br/>Self-Hosted Runner]
D -->|❌| F[🚫 Pipeline Stop]
E -->|docker build & run| G[🚀 App Live<br/>:8000]
style A fill:#4A90D9,color:#fff
style B fill:#24292e,color:#fff
style C fill:#2088FF,color:#fff
style E fill:#A81D33,color:#fff
style G fill:#2ECC71,color:#fff
| Step | Environment | Actions |
|---|---|---|
| 1. Test | ☁️ GitHub Cloud | Code checkout → Setup Python 3.11 → Install dependencies → pytest |
| 2. Deploy | 🖥️ Debian VM (self-hosted) | docker build → stop/remove old container → run new container (--restart always) |
| Component | Technology |
|---|---|
| API Framework | Python 3.11 · FastAPI |
| Containerization | Docker |
| CI/CD Orchestration | GitHub Actions |
| Deployment Environment | Debian 12 (VMware, NAT network) |
| Deployment Agent | GitHub Self-Hosted Runner (systemd service) |
DevOps-Project-1/
├── .github/
│ └── workflows/
│ └── deploy.yml # Automated CI/CD pipeline
├── src/
│ ├── app.py # FastAPI application code
│ ├── requirements.txt # Python dependencies
│ └── test_app.py # Pytest unit tests
├── Dockerfile # Docker image build instructions
└── README.md
- Debian 12 VM (VMware, NAT or bridge network)
- Administrator access (
sudo) on the VM - GitHub repository with runner configuration rights
sudo apt update && sudo apt install -y docker.io
sudo usermod -aG docker $USER
newgrp dockermkdir ~/actions-runner && cd ~/actions-runner
# Configure using commands provided in
# Settings > Actions > Runners > New self-hosted runner
./config.sh --url https://github.com/AvotraAder/DevOps-Project-1 --token <YOUR_TOKEN>
# Install and start the systemd service
sudo ./svc.sh install
sudo ./svc.sh start💡 The runner now runs in the background and listens for jobs triggered by GitHub Actions.
Once the pipeline has executed successfully:
1. Get the VM's IP address
hostname -I2. Access the application
| Resource | URL |
|---|---|
| 🌐 Main endpoint | http://<YOUR_VM_IP>:8000/ |
| 📖 Swagger documentation | http://<YOUR_VM_IP>:8000/docs |
| 📘 ReDoc documentation | http://<YOUR_VM_IP>:8000/redoc |
The .github/workflows/deploy.yml file runs automatically on every push to the main branch:
Job 1: test (GitHub Cloud)
- Retrieves code
- Installs Python 3.11 and dependencies
- Runs unit tests with
pytest
Job 2: deploy (Self-Hosted Debian VM)
- Local runner intercepts the task
- Builds (
docker build) the new Docker image - Stops and removes old container if it exists
- Launches new container with automatic restart (
--restart always)
Runner is not showing up in GitHub Actions
# Check runner status
cd ~/actions-runner && ./run.shDocker permission denied error
sudo usermod -aG docker $USER
newgrp docker
# Restart the runner
sudo systemctl restart actions.runnerApplication not accessible from host machine
# Verify container is running
docker ps
# Check VM network configuration
hostname -IThis project is licensed under the MIT License — see the LICENSE file for details.
Avotra Ader
If this project helped you, consider giving it a ⭐!