Summary of "Run Your Project Anywhere"
Main idea
The speaker explains how to make a Python project deterministic and portable—so it runs the same way on a laptop, CI, server, or other machines months later. The approach is a three-layer workflow.
1) Reproducible Python dependencies with UV
The problem
Cloning a project years later can fail due to:
- wrong Python interpreter version
- missing modules
- missing/changed library versions
- unknown historical dependency state (no reproducible build)
The tool: UV
UV is a Python project manager written in Rust (intended to replace older pip/virtualenv workflows).
Key feature: commit uv.lock
UV generates and commits uv.lock, which:
- locks exact versions of direct and transitive dependencies
- includes hashes for verification
- ensures anyone cloning the repo can install the same dependency set consistently
Pinning the Python interpreter version
The project pins the Python interpreter version via project configuration files, and UV uses that exact version—avoiding reliance on:
- “system Python”
- version managers like ASDF/PM/etc.
Dev tools excluded from production
Testing/linting tools (e.g., pytest-like and ruff-like tools) are placed in a dependency group.
- Normal installs skip those groups
- They can be enabled explicitly (e.g., a
--dev/--no-devconcept)
2) A repo-local Makefile as the single command interface
Purpose
Avoid long forgotten command lines and hidden CI scripts by making one reliable interface for common tasks.
Makefile concept
- Define targets like
install,run,test,check,build - Map those targets to the “one command” interface used by both developers and CI
CI automation benefit
- CI should call Make targets (e.g., “run
make check”) - Switching platforms later doesn’t require rewriting command logic
Target composition
- Targets can depend on other targets (e.g.,
checkdepends onlintandtest) - Supports running individual parts or everything together
Demonstrated usage
make start check run
The goal is to make execution reliable for “future me.”
3) Portable runtime packaging with containers (OCI image)
The problem addressed
Some environments (CI runners, coworkers’ machines, Windows, etc.) may not have Python/UV installed.
The solution: containerize everything
A container image includes:
- the Python interpreter
- locked dependencies
- the project code
- producing a portable OCI image runnable anywhere
Multi-stage Dockerfile approach (two stages)
-
Builder stage (fat image)
- uses an official UV image
- copies dependency files first
- installs dependencies
- caches dependency layers so they’re reused when code changes
-
Runtime stage (slim image)
- uses a slim Python base image
- copies the pre-built virtual environment from the builder
- copies project scripts/code afterward
- runs as non-root
Important container build choices
- Use
uv syncwith--lockso the container installs exactly what’s inuv.lock- prevents re-resolving dependencies to different “latest compatible” versions
- if
uv.lockand project files are out of sync, the build fails loudly
- Avoid “frozen” behavior that might skip consistency checks (speaker recommends
lockby default) - Disable cache usage for smaller images
- Precompile Python bytecode (
pyc) at build time for faster startup (especially helpful for production services)
Secrets and ignores
- Use
.dockerignoreto avoid baking in:- credentials
- host artifacts
- local virtualenvs
- Treat changing environment-specific values as environment variables (e.g., via a
.envfile) - Use
.gitignore-like principles so secrets don’t get committed - Production should use a secret manager; dev/demos can use env-file + ignore rules
Walkthrough of the combined workflow
make buildbuilds the container image.make upruns it.- The container runs with dependencies installed according to
uv.lock, and runtime environment variables can be passed in.
The benefit: “push anywhere” (CI/server/other laptops) without needing Python or UV installed locally.
Comparison / takeaway
- Builder image: fat
- Runtime image: slim
Size differences may be modest for small projects, but grow with larger dependency graphs—so keeping runtime slim is recommended.
Final message
- UV +
uv.lock→ reproducible dependencies - Makefile → consistent documented command interface
- Container → portable runtime
Together, the project runs “anywhere” reliably.
Main speakers / sources
- Speaker: “Jesus, Developer Advocate with Cisco DevNet” (as stated in the subtitles)
- Tools referenced: UV (Astral) and containers/Docker (multi-stage OCI image concept)
Category
Technology
Share this summary
Is the summary off?
If you think the summary is inaccurate, you can reprocess it with the latest model.