--- 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