Volume Configuration
Haloy supports both Docker named volumes and filesystem bind mounts for persistent data storage.
Named Volumes (Recommended)
Named volumes are managed by Docker and work consistently across environments:
name: "my-app"
volumes:
- "app-data:/app/data"
- "app-logs:/var/log/app"
- "postgres-data:/var/lib/postgresql/data"
name: "my-app"
volumes:
- "app-data:/app/data"
- "app-logs:/var/log/app"
- "postgres-data:/var/lib/postgresql/data"
Benefits
- Managed by Docker
- Portable across environments
- Better performance on some systems
- Automatic cleanup with
docker volume prune
Filesystem Bind Mounts
Mount directories from the host filesystem into containers:
name: "my-app"
volumes:
- "/var/app/data:/app/data"
- "/home/user/logs:/app/logs:ro"
- "/etc/ssl/certs:/app/certs:ro"
name: "my-app"
volumes:
- "/var/app/data:/app/data"
- "/home/user/logs:/app/logs:ro"
- "/etc/ssl/certs:/app/certs:ro"
Mount Options
Add options after the second colon:
ro- Read-only mountrw- Read-write mount (default)z- SELinux label (shared content)Z- SELinux label (private content)
Volume Format
# Named volume
volume-name:/container/path
# Bind mount (requires absolute path)
/absolute/host/path:/container/path[:options]
# Named volume
volume-name:/container/path
# Bind mount (requires absolute path)
/absolute/host/path:/container/path[:options]
Important Restrictions
Absolute Paths Required
Filesystem bind mounts must use absolute paths starting with /:
Valid:
volumes:
- "/var/log/myapp:/app/logs"
- "/etc/ssl/private:/app/ssl:ro"
volumes:
- "/var/log/myapp:/app/logs"
- "/etc/ssl/private:/app/ssl:ro"
Invalid (will be rejected):
volumes:
- "./data:/app/data" # Relative path
- "../config:/app/config" # Relative path
volumes:
- "./data:/app/data" # Relative path
- "../config:/app/config" # Relative path
Why No Relative Paths?
Since haloyd runs inside a Docker container, relative paths would be resolved relative to the daemon container’s filesystem, not your local machine. This causes:
- Unexpected directory creation inside the daemon container
- Data appearing lost or inaccessible
- Inconsistent behavior across deployments
Using absolute paths or named volumes ensures predictable, consistent behavior.
Multi-Target Volumes
Override volumes for different deployment targets:
name: "my-app"
# Base volumes
volumes:
- "app-data:/app/data"
targets:
production:
volumes:
- "prod-app-data:/app/data"
- "/var/log/prod-app:/app/logs"
staging:
volumes:
- "staging-app-data:/app/data"
- "/var/log/staging-app:/app/logs"
name: "my-app"
# Base volumes
volumes:
- "app-data:/app/data"
targets:
production:
volumes:
- "prod-app-data:/app/data"
- "/var/log/prod-app:/app/logs"
staging:
volumes:
- "staging-app-data:/app/data"
- "/var/log/staging-app:/app/logs"
Best Practices
- Use named volumes for data persistence: More portable and easier to manage
- Use bind mounts for configuration: When you need to edit files on the host
- Always use absolute paths for bind mounts: Prevents unexpected behavior
- Mount sensitive files as read-only: Add
:roto prevent accidental modification - Regular backups: Especially for named volumes containing critical data
- Document volume requirements: Keep a list of required volumes in your README