A ready-to-code Python template. Open in VS Code, click Reopen in Container, and you have a fully configured Python environment — no local Python installation required.
Everything is pre-wired: testing, linting, type checking, debugging, and CI that runs on every pull request.
Prerequisites: VS Code · Docker Desktop · Dev Containers extension
- Click Use this template → Create a new repository on GitHub
- Clone your new repository and open the folder in VS Code
- VS Code will prompt "Reopen in Container" — click it
- (Or: Command Palette →
Dev Containers: Reopen in Container)
- (Or: Command Palette →
- The container builds on first open (~1–2 min). Dependencies install automatically.
- Open a terminal inside VS Code and run the tests to confirm everything works:
uv run pytestYou should see all tests pass. The environment is ready.
# Run tests
uv run pytest
# Run tests with a coverage report
uv run pytest --cov=src --cov-report=term-missingThe VS Code Testing panel (flask icon in the sidebar) also discovers and runs tests with a click.
Put your code in src/app/ and tests in tests/. The editor is pre-configured to:
- Format on save — Ruff fixes style automatically when you save a file
- Highlight type errors — Mypy flags type problems as you type
- Run tests — from the Testing panel or the terminal
- Debug — F5 launches the debugger (see the pre-configured launch profiles in the Run panel)
Inside the container terminal:
# Add a runtime dependency
uv add requests
# Add a dev-only dependency (testing tools, linters, etc.)
uv add --group dev pytest-asyncio
# Always commit the lock file after changing dependencies
git add uv.lock && git commit -m "Add requests"The uv.lock file pins every dependency to an exact version so CI and other developers get identical environments.
-
Rename the package — move
src/app/tosrc/<your-package>/and updatepyproject.toml:[project] name = "your-project" [tool.hatch.build.targets.wheel] packages = ["src/your-package"]
-
Replace the example code in
src/<your-package>/main.pywith your own -
Write tests in
tests/test_<module>.pymirroring your source layout -
Push — CI runs automatically on every pull request
| Check | What it does |
|---|---|
| Lint & Format | Ruff checks code style |
| Type check | Mypy strict mode |
| Tests | pytest with coverage |
| Security | pip-audit scans dependencies for known vulnerabilities |
| Docker build | Builds both the dev and production images |
| CodeQL | GitHub's security analysis (also runs weekly) |
Set up branch protection rules on main (GitHub → Settings → Branches) to require all checks to pass before a PR can be merged.
The Dockerfile has two targets:
dev— used by the dev container anddocker compose run --rm testprod— a minimal image with only runtime dependencies, running as a non-root user
# Run the test suite in Docker (no local setup needed)
docker compose run --rm test
# Build and run the production image
docker build --target prod -t myapp:latest .
docker run myapp:latestsrc/app/ ← application source code (rename app/ to your package name)
tests/ ← tests (mirror src/ structure)
.devcontainer/ ← VS Code dev container config
.github/workflows/ ← CI pipelines (ci.yml, codeql.yml)
.vscode/ ← editor settings, extensions, debug configs
Dockerfile ← dev and production images
docker-compose.yml ← test and app services
pyproject.toml ← all project config (uv, ruff, mypy, pytest)
uv.lock ← locked dependencies — always commit this