A tool to wrap Python projects as Docker services.
- Takes an existing Python project and creates a Docker image
- Interactive prompts for missing configuration
- Uses pre-built base images with Python and common libraries pre-installed
- Customizable base image and entrypoint
- Optional image push to Docker registry
- Optional creation of tar.gz archive with project files and virtual environment changes
Build the project:
cargo build --releaseThe binary will be available at target/release/servicemaker.
servicemaker \
--name myproject \
--project-home /path/to/python/project \
--base-image arangodb/py13base:latest \
--port 8080 \
--image-name myregistry/myproject:latest \
--entrypoint main.py \
--pushservicemaker--name- Name of the project (optional, will prompt if not provided)--project-home- Path to the folder containing the Python project (optional, will prompt if not provided)--base-image- Base Docker image (default:arangodb/py13base:latest)--port- Exposed port number (optional, will prompt if not provided)--image-name- Docker image name to push (optional, will prompt if not provided). Can include registry prefix (e.g.,myregistry.com/myproject:latest)--push- Whether to push the image (default:false)--entrypoint- Name of the Python script to run relative to project home (optional, will prompt if not provided)--make-tar-gz- Whether to create a tar.gz archive with project files and virtual environment changes (default:false). See The--make-tar-gzOption section for details.
- Reads command-line arguments or prompts for missing values
- Validates that the project home directory exists
- Creates a temporary directory in the current directory (e.g.,
./servicemaker-<projectname>-<pid>) - Modifies the Dockerfile template with:
- Custom base image
- EXPOSE directive for the specified port
- Custom entrypoint script
- Copies the Dockerfile to the temporary directory
- Recursively copies the Python project to
project/subdirectory - Runs
docker buildto create the image - Optionally runs
docker pushif--pushis specified - Optionally creates a tar.gz archive if
--make-tar-gzis specified - Generates a Helm chart for Kubernetes deployment
ServiceMaker uses pre-built base images that provide a robust foundation for Python services. These base images:
- Start with
debian:trixie-slimfor a minimal, secure base - Include a non-root
useruser withuvpackage manager pre-installed - Have a specific Python version (e.g., Python 3.13) pre-installed via
uv - Create a virtual environment called
the_venvin the user's home directory (/home/user/the_venv) - Pre-install common libraries into the virtual environment
- Include a SHA256 checksum file (
sums_sha256) of all files in the virtual environment for change tracking
The base image setup ensures that:
- Common dependencies are pre-installed and cached in the base image
- Only new dependencies added by your project need to be installed during build
- The base image can be pre-scanned for security vulnerabilities
- Build times are faster due to layer caching
The following base images are available in the baseimages/ directory:
-
arangodb/py13base:latest(default)- Python 3.13
- Pre-installed packages:
python-arango,phenolrs,networkx
-
arangodb/py12base:latest- Python 3.12
- Pre-installed packages:
python-arango,phenolrs,networkx
-
arangodb/py13cugraph:latest- Python 3.13
- Pre-installed packages:
python-arango,phenolrs,networkx,cugraph-cu12 - Uses NVIDIA PyPI index for CUDA-accelerated graph libraries
Base images are defined in the baseimages/ directory. Each base image has its own Dockerfile (e.g., Dockerfile.py13base). To build all base images:
cd baseimages
make buildThis will build all images listed in imagelist.txt. To build a specific base image:
cd baseimages
docker build -f Dockerfile.py13base -t arangodb/py13base .To push base images to a registry:
cd baseimages
make pushYou can create additional base images for different Python versions or with different pre-installed libraries by:
- Creating a new Dockerfile in the
baseimages/directory (e.g.,Dockerfile.py14base) - Adding the image name to
imagelist.txt - Building with
make build
The tool uses the Dockerfile template in the project root. The template:
- Uses the specified base image (which already has
uvand Python installed) - Copies the project to
/home/user/project - Activates the existing virtual environment (
the_venv) from the base image - Runs
uv sync --activeto install only additional dependencies not already in the base image - Executes the specified entrypoint script
This approach ensures that:
- Dependencies are installed efficiently (only new ones are added)
- The final image shares layers with the base image (faster builds and smaller images)
- Base images can be pre-scanned for security vulnerabilities
- The virtual environment works seamlessly with modern Python tooling
The Python version is determined by the base image you select. The default base image (arangodb/py13base:latest) includes Python 3.13.
You should declare the Python version in your project's pyproject.toml file to match the base image's Python version. The uv package manager will use the Python version from the base image's virtual environment.
For example, to use Python 3.13 (matching the default base image):
requires-python = "==3.13.*"When using uv sync --active, the tool installs dependencies into the existing virtual environment from the base image, ensuring compatibility with the pre-installed Python version.
The --make-tar-gz option creates a portable archive (project.tar.gz) containing your project files and any virtual environment changes made during the Docker build process.
When --make-tar-gz is enabled, ServiceMaker:
- After building the Docker image, runs a container using that image
- Executes the
zipper.shscript inside the container - Creates a tar.gz archive containing:
the_venv/- All new files added to the virtual environment during the build (dependencies installed by your project)entrypoint- A symlink to your entrypoint script- Your project directory - All your project files
The archive is saved to the temporary directory (e.g., ./servicemaker-<projectname>-<pid>/project.tar.gz).
- Portable deployment: Deploy your project without needing Docker
- Development environments: Extract and run the project in a non-containerized environment
- Backup: Archive your project with all its dependencies
- CI/CD pipelines: Use the archive in environments where Docker images aren't available
servicemaker \
--name myproject \
--project-home /path/to/python/project \
--base-image arangodb/py13base:latest \
--port 8080 \
--image-name myregistry/myproject:latest \
--entrypoint main.py \
--make-tar-gzThe project.tar.gz file will be created in the temporary directory after the Docker image is built.
After ServiceMaker builds your Docker image, you can run it using standard Docker commands.
docker run -p <host-port>:<container-port> <image-name>For example, if your image exposes port 8080:
docker run -p 8080:8080 myregistry/myproject:latestdocker run -p 8080:8080 \
-e ENV_VAR1=value1 \
-e ENV_VAR2=value2 \
myregistry/myproject:latestdocker run -d -p 8080:8080 --name myproject myregistry/myproject:latestdocker logs myproject
# or for detached containers
docker logs -f myprojectdocker stop myproject
docker rm myprojectThe project.tar.gz archive created with --make-tar-gz can be extracted and run on any system with Python installed (matching the Python version from your base image).
# Extract the archive
tar -xzf project.tar.gz
# This will create:
# - the_venv/ (virtual environment with dependencies)
# - entrypoint (symlink to your entrypoint script)
# - <project-directory>/ (your project files)The archive contains a virtual environment with all dependencies. To run your project:
# Activate the virtual environment
source the_venv/bin/activate
# Set PYTHONPATH to include the virtual environment's site-packages
export PYTHONPATH=$(pwd)/the_venv/lib/python3.13/site-packages:$PYTHONPATH
# Run your entrypoint script
python entrypoint
# or directly
python <project-directory>/main.pyIf uv is installed on the host system:
# Extract the archive
tar -xzf project.tar.gz
# Navigate to your project directory
cd <project-directory>
# Run with uv (it will use the existing virtual environment)
uv run --active main.py- The Python version must match the base image version (e.g., Python 3.13 for
py13base) - The archive includes only the dependencies added by your project, not the base image's pre-installed packages
- For full functionality, ensure the base image's pre-installed packages are available or install them separately
- The
entrypointsymlink points to your entrypoint script relative to the project directory
- The temporary directory is left behind after execution for inspection
- The project directory must contain a valid Python project with a
pyproject.tomlorrequirements.txtfor uv to work properly - Docker must be installed and accessible for this tool to work
- Base images must be available locally or pulled from a registry before building
- The base image's Python version should match the Python version requirement in your
pyproject.toml