107 lines
4.4 KiB
Markdown
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
|