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