Containerizing Flox environments with Docker/Podman. Use for creating container images, OCI exports, multi-stage builds, and deployment workflows.
Scanned 9/6/2026
Install to Claude Code
npx -y skills add plurigrid/asi --skill flox-containers --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Flox Containers?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/plurigrid-flox-containers)More formats (shields.io, HTML) on the badges page.
---
name: flox-containers
description: Containerizing Flox environments with Docker/Podman. Use for creating container images, OCI exports, multi-stage builds, and deployment workflows.
---
# Flox Containerization Guide
## Core Commands
```bash
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
```
## Basic Usage
### Export to File
```bash
# 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
```
### Export Directly to Runtime
```bash
# Auto-detects docker or podman
flox containerize --runtime docker
# Explicit runtime selection
flox containerize --runtime podman
```
### Pipe to Stdout
```bash
# Pipe directly to Docker
flox containerize -f - | docker load
# With tagging
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
```bash
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 FloxHub
```
## Manifest Configuration
Configure container in `[containerize.config]` (experimental):
```toml
[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 container
```
### 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
```bash
# 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>
```
### Node.js Application
```bash
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
```bash
flox 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>
```
## Common Patterns
### Service Containers
Services start automatically when cmd is empty:
```toml
[services.web]
command = "python -m http.server 8000"
[containerize.config]
exposed-ports = ["8000/tcp"]
cmd = [] # Service starts automatically
```
### Multi-Stage Pattern
Build in one environment, run in another:
```bash
# 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 production
```
### Remote Environment Containers
Containerize shared team environments:
```bash
# Containerize remote environment
flox containerize -r team/python-ml --tag latest --runtime docker
# Run it
docker run -it team-python-ml:latest
```
### Multi-Service Container
```toml
[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 automatically
```
## 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
```toml
[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
```toml
[containerize.config]
cmd = ["python", "app.py"]
labels = {
"healthcheck" = "curl -f http://localhost:8000/health || exit 1"
}
```
Then in Docker:
```bash
docker run --health-cmd="curl -f http://localhost:8000/health || exit 1" \
--health-interval=30s \
myimage
```
### Multi-Architecture Builds
Build for different architectures:
```bash
# 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:arm64
```
### Minimal Container Size
Create minimal runtime environment:
```toml
[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"]
```
## Container Registry Workflows
### Push to Registry
```bash
# 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.0
```
### GitLab CI/CD
```yaml
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
```yaml
- 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
```yaml
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
```yaml
apiVersion: v1
kind: Service
metadata:
name: myapp
spec:
selector:
app: myapp
ports:
- port: 80
targetPort: 8000
type: LoadBalancer
```
## Debugging Container Issues
### Inspect Container
```bash
# 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 /
```
### View Container Logs
```bash
# Follow logs
docker logs -f <container-id>
# Last 100 lines
docker logs --tail 100 <container-id>
```
### Execute Commands in Running Container
```bash
# Get a shell
docker exec -it <container-id> /bin/bash
# Run specific command
docker exec <container-id> flox list
```
## Best Practices
1. **Use specific tags**: Avoid `latest`, use semantic versioning
2. **Minimize layers**: Combine related operations in manifests
3. **Use .dockerignore equivalent**: Only include necessary files in build context
4. **Health checks**: Implement health check endpoints for services
5. **Security**: Run as non-root user when possible
6. **Volumes**: Use volumes for persistent data, not container filesystem
7. **Environment variables**: Make configuration overridable via env vars
8. **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
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!