Skip to content

Commit 2818712

Browse files
tofechatofecha
authored andcommitted
feat: production-ready python-probe with multi-environment support
1 parent 9880a1e commit 2818712

8 files changed

Lines changed: 374 additions & 13 deletions

File tree

.dockerignore

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
.git
2+
.gitignore
3+
.dockerignore
4+
.pytest_cache
5+
.coverage
6+
htmlcov
7+
*.log
8+
logs
9+
venv
10+
ENV
11+
env
12+
.venv
13+
.env
14+
.env.local
15+
**/__pycache__
16+
*.pyc
17+
*.pyo
18+
*.egg-info
19+
.DS_Store
20+
Thumbs.db
21+
.idea
22+
.vscode
23+
*.swp
24+
README.md
25+
docs
26+
chart
27+
k8s
28+
mkdocs.yaml

.env.example

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Environment Configuration Example
2+
# Copy this to .env and customize values
3+
4+
PORT=8080
5+
APP_VERSION=1.0.0
6+
APP_COMMIT_SHA=unknown

.gitignore

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# Python
2+
__pycache__/
3+
*.py[cod]
4+
*$py.class
5+
*.so
6+
.Python
7+
build/
8+
develop-eggs/
9+
dist/
10+
downloads/
11+
eggs/
12+
.eggs/
13+
lib/
14+
lib64/
15+
parts/
16+
sdist/
17+
var/
18+
wheels/
19+
*.egg-info/
20+
.installed.cfg
21+
*.egg
22+
MANIFEST
23+
24+
# Virtual environments
25+
venv/
26+
ENV/
27+
env/
28+
.venv
29+
30+
# IDEs
31+
.vscode/
32+
.idea/
33+
*.swp
34+
*.swo
35+
*~
36+
.DS_Store
37+
38+
# Environment
39+
.env
40+
.env.local
41+
.env.*.local
42+
43+
# Testing
44+
.pytest_cache/
45+
.coverage
46+
htmlcov/
47+
48+
# Logs
49+
*.log
50+
logs/
51+
52+
# OS
53+
.DS_Store
54+
Thumbs.db
55+
56+
# Poetry
57+
poetry.lock

Dockerfile

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
11
FROM python:3.10-alpine
22

3+
WORKDIR /app
4+
35
COPY ./requirements.txt .
46

5-
RUN pip install -r ./requirements.txt
7+
RUN pip install --no-cache-r ./requirements.txt
8+
9+
COPY ./src /app
10+
11+
ENV PORT=8080 \
12+
APP_VERSION=1.0.0
613

7-
COPY ./src /src
14+
EXPOSE 8080
815

9-
CMD python /src/app.py
16+
CMD ["gunicorn", "--bind", "0.0.0.0:8080", "--workers", "4", "--access-logfile", "-", "app:app"]
1017

README.md

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
# python-probe
2+
3+
Minimal Python Flask application used for deployment validation across any environment (local, Docker, Kubernetes, ECS, etc.).
4+
5+
This is the Python counterpart to the [node-express-probe](https://github.com/tyrelof/node-express-probe) and validates deployment across different stacks.
6+
7+
## Use Cases
8+
9+
- Validate Docker builds and images
10+
- Test Kubernetes / ECS deployments
11+
- Verify CI/CD smoke tests
12+
- Experiment with runtime behavior across different platforms
13+
- Backstage integration testing
14+
15+
---
16+
17+
## Endpoints
18+
19+
| Endpoint | Method | Purpose |
20+
|----------|--------|---------|
21+
| `/` | GET | Root - basic service info |
22+
| `/health` | GET | Health check (returns JSON) |
23+
| `/healthz` | GET | Kubernetes-style health check |
24+
| `/ready` | GET | Readiness probe |
25+
| `/live` | GET | Liveness probe |
26+
| `/api/v1/info` | GET | Detailed app info (time, hostname, version) |
27+
| `/api/v1/version` | GET | Version and commit info |
28+
29+
---
30+
31+
## Local Development
32+
33+
### Quick Start
34+
35+
```bash
36+
# Install dependencies
37+
pip install -r requirements.txt
38+
39+
# Run the app
40+
python src/app.py
41+
```
42+
43+
The app will start on `http://localhost:8080`
44+
45+
### With Environment Variables
46+
47+
```bash
48+
# Set custom version and commit
49+
APP_VERSION=2.0.0 APP_COMMIT_SHA=abc123 python src/app.py
50+
```
51+
52+
### Docker Local
53+
54+
```bash
55+
# Build image
56+
docker build -t python-probe:latest .
57+
58+
# Run container
59+
docker run -p 8080:8080 python-probe:latest
60+
61+
# With environment variables
62+
docker run -p 8080:8080 \
63+
-e APP_VERSION=2.0.0 \
64+
-e APP_COMMIT_SHA=abc123 \
65+
python-probe:latest
66+
```
67+
68+
---
69+
70+
## Kubernetes Deployment
71+
72+
The app includes proper probe endpoints for Kubernetes:
73+
74+
```yaml
75+
livenessProbe:
76+
httpGet:
77+
path: /live
78+
port: 8080
79+
initialDelaySeconds: 5
80+
periodSeconds: 10
81+
82+
readinessProbe:
83+
httpGet:
84+
path: /ready
85+
port: 8080
86+
initialDelaySeconds: 5
87+
periodSeconds: 5
88+
```
89+
90+
See [k8s/deploy.yaml](k8s/deploy.yaml) for full deployment example.
91+
92+
---
93+
94+
## ECS / EC2 Deployment
95+
96+
The app works on any environment. Set environment variables via:
97+
98+
- EC2: User data script or SSM Parameter Store
99+
- ECS: Task definition environment variables
100+
- Docker: `-e` flag or `.env` file
101+
102+
```bash
103+
# Example EC2 user data
104+
#!/bin/bash
105+
export APP_VERSION=1.0.0
106+
export APP_COMMIT_SHA=${GIT_COMMIT}
107+
python /app/src/app.py
108+
```
109+
110+
---
111+
112+
## Configuration
113+
114+
| Variable | Default | Purpose |
115+
|----------|---------|---------|
116+
| `PORT` | `8080` | Port to listen on |
117+
| `APP_VERSION` | `1.0.0` | Application version |
118+
| `APP_COMMIT_SHA` | `unknown` | Git commit SHA (for tracking) |
119+
120+
---
121+
122+
## Production
123+
124+
For production, the Docker image uses **Gunicorn** (4 workers) instead of Flask's development server:
125+
126+
```bash
127+
# Manual production run
128+
gunicorn --bind 0.0.0.0:8080 --workers 4 --access-logfile - app:app
129+
```
130+
131+
---
132+
133+
## Development
134+
135+
### Project Structure
136+
137+
```
138+
src/
139+
app.py # Flask application
140+
requirements.txt # Python dependencies
141+
Dockerfile # Docker image definition
142+
k8s/ # Kubernetes manifests
143+
chart/ # Helm chart (optional)
144+
```
145+
146+
### Testing Endpoints
147+
148+
```bash
149+
# Health checks
150+
curl http://localhost:8080/health
151+
curl http://localhost:8080/live
152+
curl http://localhost:8080/ready
153+
154+
# App info
155+
curl http://localhost:8080/api/v1/info
156+
curl http://localhost:8080/api/v1/version
157+
```
158+
159+
---
160+
161+
## License
162+
163+
MIT

requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
flask==3.0.3
1+
flask==3.0.3
2+
gunicorn==22.0.0

run.sh

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#!/bin/bash
2+
# Local development run script
3+
4+
set -e
5+
6+
echo "🚀 Starting python-probe..."
7+
8+
# Check if venv exists, create if not
9+
if [ ! -d "venv" ]; then
10+
echo "📦 Creating virtual environment..."
11+
python -m venv venv
12+
fi
13+
14+
# Activate venv
15+
echo "🔄 Activating virtual environment..."
16+
source venv/bin/activate
17+
18+
# Install dependencies
19+
echo "📥 Installing dependencies..."
20+
pip install -q -r requirements.txt
21+
22+
# Load environment variables if .env exists
23+
if [ -f ".env" ]; then
24+
echo "⚙️ Loading environment variables from .env"
25+
set -a
26+
source .env
27+
set +a
28+
fi
29+
30+
# Run the app
31+
echo "✅ Starting Flask app on http://localhost:${PORT:-8080}"
32+
python src/app.py

0 commit comments

Comments
 (0)