Migration Guide
Moving to Volt from existing container platforms is straightforward. Volt can import OCI images directly, convert Dockerfiles to Voltfiles, and translate Compose stacks into Constellations. This guide covers migration paths from Docker, Docker Compose, LXC/LXD, and Podman.
Migrating from Docker
Volt can import Docker images directly from registries or local archives. Your existing images work — you just manage them with volt instead of the Docker daemon.
Step 1: Import Docker Images
# Import directly from a Docker registry
sudo volt import docker://nginx:latest
sudo volt import docker://postgres:16-alpine
sudo volt import docker://registry.example.com/myapp:v2
# Import from a local Docker archive
docker save myapp:latest -o myapp.tar
sudo volt image import myapp.tar --name myapp
# Import from a running Docker container's filesystem
docker export my-container | sudo volt image import - --name my-container
Step 2: Convert Dockerfile → Voltfile
Voltfiles are Volt's native build format. While you can run imported Docker images directly, converting to Voltfiles gives you access to Volt-native features like Landlock profiles and CAS integration.
Dockerfile Voltfile
───────────── ────────
FROM ubuntu:22.04 base: ubuntu-22.04
RUN apt-get update && \ → build:
apt-get install -y nginx - apt: [nginx]
COPY ./site /var/www/html files:
EXPOSE 80 - src: ./site
CMD ["nginx", "-g", dst: /var/www/html
"daemon off;"] ports: ["80:80"]
command: nginx -g "daemon off;"
security:
landlock: webserver
seccomp: strict
# Auto-convert a Dockerfile to a Voltfile
volt convert Dockerfile --output Voltfile
# Build from a Voltfile
sudo volt build -f Voltfile -t myapp:v1
# Build and run in one step
sudo volt build -f Voltfile -t myapp:v1 --run
Step 3: Run with Volt
# Create and start the container
sudo volt container create myapp --image myapp:v1
sudo volt container start myapp
# Or the one-liner equivalent
sudo volt run myapp:v1 --name myapp
# Verify it's running
sudo volt ps
Docker named volumes can be migrated by copying their contents. Find them in /var/lib/docker/volumes/, then import into Volt volumes with sudo volt volume create mydata --import /path/to/data.
Migrating from Docker Compose
Docker Compose stacks map directly to Volt Constellations. A Constellation is a multi-service deployment defined in a volt-compose.yaml file, managed as a single unit.
Concept Mapping
| Docker Compose | Volt Constellation | Notes |
|---|---|---|
docker-compose.yaml | volt-compose.yaml | Similar YAML structure |
docker compose up | volt constellation up | Deploys all services |
docker compose down | volt constellation down | Tears down stack |
docker compose ps | volt constellation ps | Service status |
docker compose logs | volt constellation logs | Unified via journald |
services: | services: | Same concept |
volumes: | volumes: | Same concept |
networks: | networks: | Uses volt-net bridges |
Convert a Compose File
# Auto-convert docker-compose.yaml to volt-compose.yaml
volt convert docker-compose.yaml --output volt-compose.yaml
# Review the converted file
cat volt-compose.yaml
# Deploy the constellation
sudo volt constellation up
Example Conversion
# docker-compose.yaml (before)
version: "3.8"
services:
web:
image: nginx:latest
ports:
- "80:80"
volumes:
- webdata:/usr/share/nginx/html
depends_on:
- api
api:
build: ./api
ports:
- "3000:3000"
environment:
- DB_HOST=db
depends_on:
- db
db:
image: postgres:16
volumes:
- pgdata:/var/lib/postgresql/data
environment:
- POSTGRES_PASSWORD=secret
volumes:
webdata:
pgdata:
# volt-compose.yaml (after conversion)
version: "1"
services:
web:
image: docker://nginx:latest
ports:
- "80:80"
volumes:
- webdata:/usr/share/nginx/html
depends_on:
- api
security:
landlock: webserver
seccomp: strict
api:
build: ./api
ports:
- "3000:3000"
environment:
- DB_HOST=db
depends_on:
- db
security:
seccomp: default-plus-networking
db:
image: docker://postgres:16
volumes:
- pgdata:/var/lib/postgresql/data
environment:
- POSTGRES_PASSWORD=secret
security:
landlock: database
seccomp: default-plus-networking
volumes:
webdata:
pgdata:
During conversion, Volt automatically suggests security profiles based on the service type. A PostgreSQL service gets the database Landlock profile; an Nginx service gets webserver. You can always customize these.
Migrating from LXC/LXD
LXC and LXD containers are the closest match to Voltainer — both use Linux namespaces and cgroups for isolation. Migration is a direct rootfs transfer.
Export and Import
# From LXD: export the container as a tarball
lxc export my-container my-container.tar.gz
# Import into Volt
sudo volt image import my-container.tar.gz --name my-container
# Create and start
sudo volt container create my-container --image my-container
sudo volt container start my-container
Direct Rootfs Copy
# For LXC (not LXD): copy the rootfs directly
sudo rsync -a /var/lib/lxc/my-container/rootfs/ \
/var/lib/volt/images/my-container/
# Create from the imported rootfs
sudo volt container create my-container --image my-container
Configuration Mapping
| LXC/LXD Config | Volt Equivalent |
|---|---|
limits.cpu | --cpu-limit |
limits.memory | --memory |
security.nesting | Not needed (systemd-nspawn handles nesting) |
security.privileged | --private-users=no (avoid in production) |
raw.lxc | Custom .nspawn drop-in files |
| LXD profiles | Volt security profiles |
Migrating from Podman
Podman uses OCI-compatible images, making migration straightforward. Export your Podman images and import them into Volt.
OCI Image Import
# Export from Podman as OCI archive
podman save myapp:latest -o myapp-oci.tar
# Import into Volt
sudo volt image import myapp-oci.tar --name myapp --format oci
# Or import directly from a registry (same as Docker)
sudo volt import docker://docker.io/library/myapp:latest
Podman Compose → Constellation
# If using podman-compose, the YAML is Docker Compose-compatible
# Use the same conversion tool
volt convert docker-compose.yaml --output volt-compose.yaml
sudo volt constellation up
If you're coming from rootless Podman, Volt's proot backend provides a similar rootless experience. Use volt container create --backend proot for development without root privileges.
Migration Assistant Coming Soon
The volt migrate analyze command will automatically scan your existing container infrastructure and generate a migration plan.
Planned Features
# Analyze existing Docker setup (planned)
volt migrate analyze --source docker
# Expected output:
# ┌─────────────────────────────────────────────────┐
# │ Migration Analysis Report │
# ├─────────────────────────────────────────────────┤
# │ Containers found: 12 │
# │ Images found: 8 │
# │ Compose stacks: 3 │
# │ Volumes: 15 │
# │ Networks: 4 │
# │ │
# │ Migration complexity: MODERATE │
# │ Estimated time: ~30 minutes │
# │ │
# │ Recommended security profiles will be │
# │ auto-generated based on image analysis. │
# └─────────────────────────────────────────────────┘
# Generate migration scripts (planned)
volt migrate generate --source docker --output ./migration/
# Execute migration (planned)
volt migrate execute --plan ./migration/plan.yaml
The migration assistant is under active development. In the meantime, use the manual import commands described above — they cover all the same functionality, just without the automated analysis.
Compatibility Mode
For teams transitioning gradually, Volt offers a Docker compatibility mode that aliases common Docker CLI commands to their Volt equivalents. This lets existing scripts and CI/CD pipelines work immediately while you migrate.
# Enable Docker CLI compatibility
sudo volt compat docker --enable
# Now Docker commands are translated to Volt equivalents:
docker ps # → volt ps
docker run # → volt run
docker build # → volt build
docker compose up # → volt constellation up
docker images # → volt image list
docker volume ls # → volt volume list
# Check compatibility status
volt compat docker --status
# Disable when migration is complete
sudo volt compat docker --disable
Compatibility mode is especially useful for CI/CD pipelines. Enable it on your build servers and existing docker build / docker push commands will work through Volt — no pipeline changes needed during the transition period.
What Changes vs What Stays the Same
| Aspect | What Stays the Same | What Changes |
|---|---|---|
| Images | OCI images work directly; existing images importable | Stored in Stellarium CAS with SHA256 integrity; Voltfile replaces Dockerfile |
| Containers | Same Linux namespace & cgroup isolation model | Voltainer uses systemd-nspawn (no daemon); containers are systemd services |
| Networking | Bridge networking, port mapping, DNS resolution | volt-net bridges with nftables; deny-by-default inter-container policy |
| Volumes | Named volumes, bind mounts | Managed under /var/lib/volt/volumes/; ext4 and directory backends |
| Compose | YAML-based multi-service definitions | Constellations use volt-compose.yaml; backed by systemd targets |
| CLI | Similar command structure (run, ps, exec, logs) |
volt replaces docker; some subcommands differ |
| Logging | Centralized log access per container | journald integration — journalctl instead of docker logs |
| Security | Namespace isolation, seccomp support | Landlock LSM profiles, stricter defaults, CAS integrity verification |
| Daemon | — | No daemon. systemd manages workloads directly. No single point of failure. |
| VMs | — | Voltvisor adds KVM VM management under the same CLI and tooling |
Command Quick Reference
| Docker Command | Volt Equivalent |
|---|---|
docker run | volt run |
docker ps | volt ps |
docker exec | volt container exec |
docker logs | volt logs |
docker build | volt build |
docker images | volt image list |
docker pull | volt import docker:// |
docker volume create | volt volume create |
docker network create | volt network create |
docker compose up | volt constellation up |
docker compose down | volt constellation down |
docker save | volt bundle create |
docker load | volt bundle import |