| name | flox-containers |
| description | Containerizing Flox environments with Docker/Podman. Use for creating container images, OCI exports, multi-stage builds, and deployment workflows. |
For the human maintainer of this environment. Do not run these commands
on the user's behalf — relay them.
DEPRECATED: this skill is frozen and has moved to
flox/flox-skills.
flox/flox-agentic receives no further updates and will be archived on
2026-09-30.
The seven skills here were consolidated into flox (reproducible
environments, with reference guides for services, builds, containers,
publishing, sharing, and CUDA). The maintained plugin also ships floxify
for onboarding an existing repo to Flox.
To migrate, a person should run claude plugin marketplace add flox/flox-skills and claude plugin install flox@flox-skills, then remove
this one with claude plugin uninstall flox@flox-agentic and claude plugin marketplace remove flox-agentic.
Flox Containerization Guide
Core Commands
flox containerize
flox containerize -f ./mycontainer.tar
flox containerize --runtime docker
flox containerize --runtime podman
flox containerize -f - | docker load
flox containerize --tag v1.0
flox containerize -r owner/env
Basic Usage
Export to File
flox containerize -f ./mycontainer.tar
docker load -i ./mycontainer.tar
flox containerize
docker load -i myenv-container.tar
Export Directly to Runtime
flox containerize --runtime docker
flox containerize --runtime podman
Pipe to Stdout
flox containerize -f - | docker load
flox containerize --tag v1.0 -f - | docker load
How Containers Behave
Containers activate the Flox environment on startup (like flox activate):
- Interactive:
docker run -it <image> → Bash shell with environment activated
- Non-interactive:
docker run <image> <cmd> → Runs command with environment activated (like flox activate -- <cmd>)
- All packages, variables, and hooks are available inside the container
Note: Flox sets an entrypoint that activates the environment, then runs cmd inside that activation.
Command Options
flox containerize
[-f <file>]
[--runtime <runtime>]
[--tag <tag>]
[-d <path>]
[-r <owner/name>]
Manifest Configuration
Configure container in [containerize.config] (experimental):
[containerize.config]
user = "appuser"
exposed-ports = ["8080/tcp"]
cmd = ["python", "app.py"]
volumes = ["/data", "/config"]
working-dir = "/app"
labels = { version = "1.0" }
stop-signal = "SIGTERM"
Configuration Options Explained
user: Run container as specific user
- Username:
user = "appuser"
- UID:GID:
user = "1000:1000"
exposed-ports: Network ports to expose
- TCP:
["8080/tcp"]
- UDP:
["8125/udp"]
- Default protocol is tcp:
["8080"] = ["8080/tcp"]
cmd: Command to run in container
- Array form:
cmd = ["python", "app.py"]
- Empty for service-based:
cmd = []
volumes: Mount points for persistent data
- List paths:
volumes = ["/data", "/config", "/logs"]
working-dir: Initial working directory
- Absolute path:
working-dir = "/app"
labels: Arbitrary metadata
- Key-value pairs:
labels = { version = "1.0", env = "production" }
stop-signal: Signal to stop container
- Common:
"SIGTERM", "SIGINT", "SIGKILL"
Complete Workflow Examples
Flask Web Application
flox init
flox install python311 flask
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
flox containerize -f - | docker load
docker run -p 5000:5000 -v $(pwd):/app <container-id>
Node.js Application
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:latest
Database Container
flox init
flox install postgresql
flox edit
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 = []
EOF
flox containerize -f - | docker load
docker run -p 5432:5432 -v pgdata:/data <container-id>
Common Patterns
Service Containers
Services start automatically when cmd is empty:
[services.web]
command = "python -m http.server 8000"
[containerize.config]
exposed-ports = ["8000/tcp"]
cmd = []
Multi-Stage Pattern
Build in one environment, run in another:
cd build-env
flox activate -- flox build myapp
cd ../runtime-env
flox install myapp
flox containerize --tag production -f - | docker load
docker run production
Remote Environment Containers
Containerize shared team environments:
flox containerize -r team/python-ml --tag latest --runtime docker
docker run -it team-python-ml:latest
Multi-Service Container
[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 = []
Platform-Specific Notes
macOS
- Requires docker/podman runtime (uses proxy container for builds)
- May prompt for file sharing permissions
- Creates
flox-nix volume for caching
- Safe to remove when not building:
docker volume rm flox-nix
Linux
- Direct image creation without proxy
- No intermediate volumes needed
- Native container support
Advanced Use Cases
Custom Entrypoint with Wrapper Script
[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"]
Health Check Support
[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 \
myimage
Multi-Architecture Builds
Build for different architectures:
flox containerize --tag myapp:amd64 --runtime docker
flox containerize --tag myapp:arm64 --runtime docker
docker manifest create myapp:latest \
myapp:amd64 \
myapp:arm64
Minimal Container Size
Create minimal runtime environment:
[install]
python.pkg-path = "python311"
[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"]
Container Registry Workflows
Push to Registry
flox containerize --tag myapp:v1.0 --runtime docker
docker tag myapp:v1.0 registry.company.com/myapp:v1.0
docker push registry.company.com/myapp:v1.0
GitLab CI/CD
containerize:
stage: build
script:
- flox containerize --tag $CI_REGISTRY_IMAGE:$CI_COMMIT_TAG --runtime docker
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_TAG
GitHub Actions
- 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 }}
Kubernetes Deployment
Basic Deployment
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-data
Service Definition
apiVersion: v1
kind: Service
metadata:
name: myapp
spec:
selector:
app: myapp
ports:
- port: 80
targetPort: 8000
type: LoadBalancer
Debugging Container Issues
Inspect Container
docker run -it --entrypoint /bin/bash <image-id>
docker run <image-id> env
docker run <image-id> ls -la /
View Container Logs
docker logs -f <container-id>
docker logs --tail 100 <container-id>
Execute Commands in Running Container
docker exec -it <container-id> /bin/bash
docker exec <container-id> flox list
Best Practices
- Use specific tags: Avoid
latest, use semantic versioning
- Minimize layers: Combine related operations in manifests
- Use .dockerignore equivalent: Only include necessary files in build context
- Health checks: Implement health check endpoints for services
- Security: Run as non-root user when possible
- Volumes: Use volumes for persistent data, not container filesystem
- Environment variables: Make configuration overridable via env vars
- Logging: Log to stdout/stderr, not files
Related Skills
- flox-environments - Creating environments to containerize
- flox-services - Running services in containers
- flox-builds - Building artifacts before containerizing
- flox-sharing - Containerizing remote environments