Containerizing Flox environments with Docker/Podman. Use for creating container images, OCI exports, multi-stage builds, and deployment workflows.
84
81%
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Passed
No known issues
flox containerize # Export to default tar file
flox containerize -f ./mycontainer.tar # Export to specific file
flox containerize --runtime docker # Export directly to Docker
flox containerize --runtime podman # Export directly to Podman
flox containerize -f - | docker load # Pipe to Docker
flox containerize --tag v1.0 # Tag container image
flox containerize -r owner/env # Containerize remote environment# Export to file
flox containerize -f ./mycontainer.tar
docker load -i ./mycontainer.tar
# Or use default filename: {name}-container.tar
flox containerize
docker load -i myenv-container.tar# Auto-detects docker or podman
flox containerize --runtime docker
# Explicit runtime selection
flox containerize --runtime podman# Pipe directly to Docker
flox containerize -f - | docker load
# With tagging
flox containerize --tag v1.0 -f - | docker loadContainers activate the Flox environment on startup (like flox activate):
docker run -it <image> → Bash shell with environment activateddocker run <image> <cmd> → Runs command with environment activated (like flox activate -- <cmd>)Note: Flox sets an entrypoint that activates the environment, then runs cmd inside that activation.
flox containerize
[-f <file>] # Output file (- for stdout); defaults to {name}-container.tar
[--runtime <runtime>] # docker/podman (auto-detects if not specified)
[--tag <tag>] # Container tag (e.g., v1.0, latest)
[-d <path>] # Path to .flox/ directory
[-r <owner/name>] # Remote environment from FloxHubConfigure container in [containerize.config] (experimental):
[containerize.config]
user = "appuser" # Username or uid:gid format
exposed-ports = ["8080/tcp"] # Ports to expose (tcp/udp/default:tcp)
cmd = ["python", "app.py"] # Command to run (receives activated env)
volumes = ["/data", "/config"] # Mount points for persistent data
working-dir = "/app" # Working directory
labels = { version = "1.0" } # Arbitrary metadata
stop-signal = "SIGTERM" # Signal to stop containeruser: Run container as specific user
user = "appuser"user = "1000:1000"exposed-ports: Network ports to expose
["8080/tcp"]["8125/udp"]["8080"] = ["8080/tcp"]cmd: Command to run in container
cmd = ["python", "app.py"]cmd = []volumes: Mount points for persistent data
volumes = ["/data", "/config", "/logs"]working-dir: Initial working directory
working-dir = "/app"labels: Arbitrary metadata
labels = { version = "1.0", env = "production" }stop-signal: Signal to stop container
"SIGTERM", "SIGINT", "SIGKILL"# Create environment
flox init
flox install python311 flask
# Configure for container
cat >> .flox/env/manifest.toml << 'EOF'
[containerize.config]
exposed-ports = ["5000/tcp"]
cmd = ["python", "-m", "flask", "run", "--host=0.0.0.0"]
working-dir = "/app"
user = "flask"
EOF
# Build and run
flox containerize -f - | docker load
docker run -p 5000:5000 -v $(pwd):/app <container-id>flox init
flox install nodejs
cat >> .flox/env/manifest.toml << 'EOF'
[containerize.config]
exposed-ports = ["3000/tcp"]
cmd = ["npm", "start"]
working-dir = "/app"
EOF
flox containerize --tag myapp:latest --runtime docker
docker run -p 3000:3000 -v $(pwd):/app myapp:latestflox init
flox install postgresql
# Set up service in manifest
flox edit
# Add service and container config
cat >> .flox/env/manifest.toml << 'EOF'
[services.postgres]
command = '''
mkdir -p /data/postgres
if [ ! -d "/data/postgres/pgdata" ]; then
initdb -D /data/postgres/pgdata
fi
exec postgres -D /data/postgres/pgdata -h 0.0.0.0
'''
is-daemon = true
[containerize.config]
exposed-ports = ["5432/tcp"]
volumes = ["/data"]
cmd = [] # Service starts automatically
EOF
flox containerize -f - | docker load
docker run -p 5432:5432 -v pgdata:/data <container-id>Services start automatically when cmd is empty:
[services.web]
command = "python -m http.server 8000"
[containerize.config]
exposed-ports = ["8000/tcp"]
cmd = [] # Service starts automaticallyBuild in one environment, run in another:
# Build environment with all dev tools
cd build-env
flox activate -- flox build myapp
# Runtime environment with minimal deps
cd ../runtime-env
flox install myapp
flox containerize --tag production -f - | docker load
# Run
docker run productionContainerize shared team environments:
# Containerize remote environment
flox containerize -r team/python-ml --tag latest --runtime docker
# Run it
docker run -it team-python-ml:latest[services.db]
command = '''exec postgres -D "$FLOX_ENV_CACHE/postgres"'''
is-daemon = true
[services.cache]
command = '''exec redis-server'''
is-daemon = true
[services.api]
command = '''exec python -m uvicorn main:app --host 0.0.0.0'''
[containerize.config]
exposed-ports = ["8000/tcp", "5432/tcp", "6379/tcp"]
cmd = [] # All services start automaticallyflox-nix volume for cachingdocker volume rm flox-nix[build.entrypoint]
command = '''
cat > $out/bin/entrypoint.sh << 'EOF'
#!/usr/bin/env bash
set -e
# Custom initialization
echo "Initializing application..."
setup_app
# Run whatever command was passed
exec "$@"
EOF
chmod +x $out/bin/entrypoint.sh
'''
[containerize.config]
cmd = ["entrypoint.sh", "python", "app.py"][containerize.config]
cmd = ["python", "app.py"]
labels = {
"healthcheck" = "curl -f http://localhost:8000/health || exit 1"
}Then in Docker:
docker run --health-cmd="curl -f http://localhost:8000/health || exit 1" \
--health-interval=30s \
myimageBuild for different architectures:
# On x86_64 Linux
flox containerize --tag myapp:amd64 --runtime docker
# On ARM64 (aarch64) Linux
flox containerize --tag myapp:arm64 --runtime docker
# Create manifest
docker manifest create myapp:latest \
myapp:amd64 \
myapp:arm64Create minimal runtime environment:
[install]
# Only runtime dependencies
python.pkg-path = "python311"
# No dev tools, no build tools
[build.app]
command = '''
# Build in build environment
python -m pip install --target=$out/lib/python -r requirements.txt
cp -r src $out/lib/python/
'''
runtime-packages = ["python"]
[containerize.config]
cmd = ["python", "-m", "myapp"]# Build container
flox containerize --tag myapp:v1.0 --runtime docker
# Tag for registry
docker tag myapp:v1.0 registry.company.com/myapp:v1.0
# Push
docker push registry.company.com/myapp:v1.0containerize:
stage: build
script:
- flox containerize --tag $CI_REGISTRY_IMAGE:$CI_COMMIT_TAG --runtime docker
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_TAG- name: Build container
run: |
flox containerize --tag ghcr.io/${{ github.repository }}:${{ github.sha }} --runtime docker
- name: Push to GHCR
run: |
echo ${{ secrets.GITHUB_TOKEN }} | docker login ghcr.io -u ${{ github.actor }} --password-stdin
docker push ghcr.io/${{ github.repository }}:${{ github.sha }}apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: registry.company.com/myapp:v1.0
ports:
- containerPort: 8000
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
persistentVolumeClaim:
claimName: myapp-dataapiVersion: v1
kind: Service
metadata:
name: myapp
spec:
selector:
app: myapp
ports:
- port: 80
targetPort: 8000
type: LoadBalancer# Run interactively
docker run -it --entrypoint /bin/bash <image-id>
# Check environment
docker run <image-id> env
# Check what's in the image
docker run <image-id> ls -la /# Follow logs
docker logs -f <container-id>
# Last 100 lines
docker logs --tail 100 <container-id># Get a shell
docker exec -it <container-id> /bin/bash
# Run specific command
docker exec <container-id> flox listlatest, use semantic versioning32d3e1e
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.