Bringing pixi to production#
You can bring pixi projects into production by either containerizing it using tools like Docker or by using quantco/pixi-pack
.
Docker#
We provide a simple docker image at pixi-docker
that contains the pixi executable on top of different base images.
The images are available on ghcr.io/prefix-dev/pixi.
There are different tags for different base images available:
latest
- based onubuntu:jammy
focal
- based onubuntu:focal
bullseye
- based ondebian:bullseye
jammy-cuda-12.2.2
- based onnvidia/cuda:12.2.2-jammy
- ... and more
All tags
For all tags, take a look at the build script.
Example usage#
The following example uses the pixi docker image as a base image for a multi-stage build.
It also makes use of pixi shell-hook
to not rely on pixi being installed in the production container.
More examples
For more examples, take a look at pavelzw/pixi-docker-example.
FROM ghcr.io/prefix-dev/pixi:0.42.1 AS build
# copy source code, pixi.toml and pixi.lock to the container
WORKDIR /app
COPY . .
# install dependencies to `/app/.pixi/envs/prod`
# use `--locked` to ensure the lockfile is up to date with pixi.toml
RUN pixi install --locked -e prod
# create the shell-hook bash script to activate the environment
RUN pixi shell-hook -e prod -s bash > /shell-hook
RUN echo "#!/bin/bash" > /app/entrypoint.sh
RUN cat /shell-hook >> /app/entrypoint.sh
# extend the shell-hook script to run the command passed to the container
RUN echo 'exec "$@"' >> /app/entrypoint.sh
FROM ubuntu:24.04 AS production
WORKDIR /app
# only copy the production environment into prod container
# please note that the "prefix" (path) needs to stay the same as in the build container
COPY --from=build /app/.pixi/envs/prod /app/.pixi/envs/prod
COPY --from=build --chmod=0755 /app/entrypoint.sh /app/entrypoint.sh
# copy your project code into the container as well
COPY ./my_project /app/my_project
EXPOSE 8000
ENTRYPOINT [ "/app/entrypoint.sh" ]
# run your app inside the pixi environment
CMD [ "uvicorn", "my_project:app", "--host", "0.0.0.0" ]
pixi-pack#
pixi-pack
is a simple tool that takes a pixi environment and packs it into a compressed archive that can be shipped to the target machine.
It can be installed via
Or by downloading our pre-built binaries from the releases page.
Instead of installing pixi-pack globally, you can also use pixi exec to run pixi-pack
in a temporary environment:
You can pack an environment with
This will create a environment.tar
file that contains all conda packages required to create the environment.
# environment.tar
| pixi-pack.json
| environment.yml
| channel
| ├── noarch
| | ├── tzdata-2024a-h0c530f3_0.conda
| | ├── ...
| | └── repodata.json
| └── linux-64
| ├── ca-certificates-2024.2.2-hbcca054_0.conda
| ├── ...
| └── repodata.json
Unpacking an environment#
With pixi-pack unpack environment.tar
, you can unpack the environment on your target system. This will create a new conda environment in ./env
that contains all packages specified in your pixi.toml
. It also creates an activate.sh
(or activate.bat
on Windows) file that lets you activate the environment without needing to have conda
or micromamba
installed.
Cross-platform packs#
Since pixi-pack
just downloads the .conda
and .tar.bz2
files from the conda repositories, you can trivially create packs for different platforms.
You can only unpack a pack on a system that has the same platform as the pack was created for.
Inject additional packages#
You can inject additional packages into the environment that are not specified in pixi.lock
by using the --inject
flag:
This can be particularly useful if you build the project itself and want to include the built package in the environment but still want to use pixi.lock
from the project.
Cache downloaded packages#
You can cache downloaded packages to speed up subsequent pack operations by using the --use-cache
flag:
This will store all downloaded packages in the specified directory and reuse them in future pack operations. The cache follows the same structure as conda channels, organizing packages by platform subdirectories (e.g., linux-64, win-64, etc.).
Using a cache is particularly useful when:
- Creating multiple packs with overlapping dependencies
- Working with large packages that take time to download
- Operating in environments with limited bandwidth
- Running CI/CD pipelines where package caching can significantly improve build times
Unpacking without pixi-pack#
If you don't have pixi-pack
available on your target system, you can still install the environment if you have conda
or micromamba
available.
Just unarchive the environment.tar
, then you have a local channel on your system where all necessary packages are available.
Next to this local channel, you will find an environment.yml
file that contains the environment specification.
You can then install the environment using conda
or micromamba
:
tar -xvf environment.tar
micromamba create -p ./env --file environment.yml
# or
conda env create -p ./env --file environment.yml
The environment.yml
and repodata.json
files are only for this use case, pixi-pack unpack
does not use them.
Both conda
and mamba
are always installing pip as a side effect when they install python, see conda
's documentation.
This is not different from how pixi
works and can lead to solver errors when using pixi-pack
's compatibility mode since pixi-pack
doesn't include pip
by default.
You can fix this issue in two ways:
- Add
pip
to yourpixi.lock
file usingpixi add pip
. - Configuring
conda
(ormamba
) to not installpip
by default by runningconda config --set add_pip_as_python_dependency false
(or by addingadd_pip_as_python_dependency: False
to your~/.condarc
)