obsidian/wiki/concepts/python-service-deployment-dotenv.md
2026-04-18 22:04:01 +01:00

107 lines
4.4 KiB
Markdown

---
title: "Python Service Deployment — venv and .env Checklist"
aliases: [python-deploy-checklist, python-venv-deploy, dotenv-deployment, service-deploy-python]
tags: [python, deployment, venv, dotenv, bash, linux, systemd]
sources:
- "daily/2026-04-16.md"
created: 2026-04-16
updated: 2026-04-16
---
# Python Service Deployment — venv and .env Checklist
Deploying a new version of a Python service that adds dependencies or switches to `.env`-based configuration requires manual steps on the server that are easily missed. The service may fail to start silently (if the systemd unit is already running), or start with `ModuleNotFoundError` or `ConfigurationError` that only appears in `journalctl`.
## Key Points
- After `git pull`, **always check if new packages were added to requirements.txt** — the venv on the server doesn't update automatically
- Install into the **correct venv**: use `/path/to/venv/bin/pip install`, not the system pip
- When a service transitions from hardcoded config to `utils/config.py + .env`, the `.env` file must be created on every server — the service won't start without it
- **`.env.example` with sensible defaults** is sufficient for production when actual secrets come from other mechanisms (e.g., Box config JSON, environment-specific config files)
- Multi-environment servers (dev + prod side by side) require the checklist run once per environment
## Details
### Deployment Checklist for Python Service Updates
```bash
# 1. Pull the latest code
cd /home/box-cli/FORD_SCRIPTS/ford_qc_git_dev/ford_qc
git pull
# 2. Check for new dependencies
diff requirements.txt <(path/to/venv/bin/pip freeze)
# Or just reinstall — pip is idempotent for existing packages
/path/to/venv/bin/pip install -r requirements.txt
# 3. Create .env if it doesn't exist
if [ ! -f .env ]; then
cp .env.example .env
echo "Created .env from .env.example — review before production"
fi
# 4. Restart the service
sudo systemctl restart ford-qc-hotfolder
# 5. Verify it's running
sudo systemctl status ford-qc-hotfolder
sudo journalctl -u ford-qc-hotfolder -n 50 --no-pager
```
### Finding the Correct venv Path
```bash
# The venv is typically next to the service code
ls /path/to/service/
# Look for: venv/, .venv/, env/, or a virtualenv/ directory
# Confirm it's the right one
/path/to/venv/bin/python --version
/path/to/venv/bin/pip list | grep python-dotenv
```
### Common Failure Sequence
1. `git pull` succeeds
2. `systemctl restart` succeeds (systemd starts the new process)
3. Process crashes immediately — systemd restarts it a few times then gives up
4. `systemctl status` shows `Active: failed`
5. `journalctl -u service-name -n 20` reveals the actual error:
- `ModuleNotFoundError: No module named 'dotenv'` → pip install missing
- `ConfigurationError: Missing required configuration variables` → .env not created
### .env.example Strategy
Keep `.env.example` committed to the repo with all variables and reasonable defaults. Actual secrets go in `.env` (gitignored). For services where secrets come from a separate mechanism:
```ini
# .env.example — safe to commit, reasonable defaults for most deployments
LOG_LEVEL=INFO
BOX_CONFIG_PATH=/etc/service/box_config.json
POLL_INTERVAL_SECONDS=30
MAX_RETRIES=3
```
The `.env.example` approach means `cp .env.example .env` is always a valid starting point — no manual env var hunting needed on new servers.
### Multi-Environment Server Layout (Ford QC Pattern)
```
/home/box-cli/FORD_SCRIPTS/
├── ford_qc_git_dev/
│ └── ford_qc/ # dev environment — deploy and test here first
└── ford_qc_git_prod/
└── ford_qc/ # prod — apply after team approval
```
Both environments need the same checklist run independently. Dev first, prod only after team sign-off.
## Related Concepts
- [[wiki/concepts/monorepo-deploy-script-pitfall]] — another deploy script failure mode found in the same codebase
- [[wiki/concepts/shell-static-deploy-patterns]] — shell deploy patterns for static frontends (complementary)
- [[wiki/client-knowledge/_index]] — Ford project context including ford-qc-hotfolder service
## Sources
- [[daily/2026-04-16.md]] — Ford QC hotfolder service failed on `box-cli-01` after git pull; `ModuleNotFoundError: No module named 'dotenv'` (new dependency); then `ConfigurationError` (new `.env` requirement from config.py refactor); resolved with pip install + cp .env.example .env