This directory contains the Docker configuration for building a containerized version of the Torrust Tracker Deployer.
This container only supports CLOUD PROVIDERS (e.g., Hetzner).
The LXD provider is NOT supported when running from a container because:
- LXD manages local virtual machines through system-level APIs
- Requires access to host virtualization features (KVM, QEMU)
- Running LXD inside Docker requires privileged containers with full device access
- This defeats the purpose of containerization and introduces security risks
For LXD deployments: Install the deployer directly on the host using the native installation method.
docker pull torrust/tracker-deployer:latest# From repository root
docker build --target release --tag torrust/tracker-deployer:release --file docker/deployer/Dockerfile .docker run --rm \
-v $(pwd)/data:/var/lib/torrust/deployer/data \
-v $(pwd)/build:/var/lib/torrust/deployer/build \
-v $(pwd)/envs:/var/lib/torrust/deployer/envs \
-v ~/.ssh:/home/deployer/.ssh:ro \
torrust/tracker-deployer:latest \
--helpThe container requires several volume mounts for proper operation:
| Host Path | Container Path | Purpose | Required |
|---|---|---|---|
./data/ |
/var/lib/torrust/deployer/data |
Environment state and persistence | Yes |
./build/ |
/var/lib/torrust/deployer/build |
Generated configuration files | Yes |
./envs/ |
/var/lib/torrust/deployer/envs |
User environment configuration files | Yes |
~/.ssh/ |
/home/deployer/.ssh |
SSH keys for remote access | Yes |
The safest way to create a valid configuration is to generate a template:
# Generate a Hetzner configuration template
docker run --rm \
-v $(pwd)/envs:/var/lib/torrust/deployer/envs \
torrust/tracker-deployer:latest \
create template --provider hetzner envs/my-hetzner-env.jsonThen edit the generated file to replace placeholder values with your actual configuration.
A JSON schema is available at schemas/environment-config.json for validating configuration files before deployment:
IDE Integration (VS Code):
The repository includes VS Code settings (.vscode/settings.json) that automatically validate files in the envs/ directory against the schema. Open any envs/*.json file and the editor will highlight validation errors.
AI Agent Integration:
If using an AI coding agent, point it to the JSON schema at schemas/environment-config.json. The schema contains:
- All required and optional fields
- Field types and constraints
- Enum values for provider types
- Documentation for each field
Command Line Validation:
# Using ajv-cli (npm install -g ajv-cli)
ajv validate -s schemas/environment-config.json -d envs/your-config.json
# Using check-jsonschema (pip install check-jsonschema)
check-jsonschema --schemafile schemas/environment-config.json envs/your-config.json# First, create your environment config in ./envs/my-hetzner-env.json
# Then run:
docker run --rm \
-v $(pwd)/data:/var/lib/torrust/deployer/data \
-v $(pwd)/build:/var/lib/torrust/deployer/build \
-v $(pwd)/envs:/var/lib/torrust/deployer/envs \
-v ~/.ssh:/home/deployer/.ssh:ro \
torrust/tracker-deployer:latest \
create environment --env-file /var/lib/torrust/deployer/envs/my-hetzner-env.jsondocker run --rm \
-v $(pwd)/data:/var/lib/torrust/deployer/data \
-v $(pwd)/build:/var/lib/torrust/deployer/build \
-v $(pwd)/envs:/var/lib/torrust/deployer/envs \
-v ~/.ssh:/home/deployer/.ssh:ro \
torrust/tracker-deployer:latest \
provision my-hetzner-envNote: The Hetzner API token must be included in your environment configuration JSON file (
envs/my-hetzner-env.json). See the Configuration Validation section for how to create valid configuration files.
docker run --rm \
-v $(pwd)/data:/var/lib/torrust/deployer/data \
torrust/tracker-deployer:latest \
listdocker run --rm \
-v $(pwd)/data:/var/lib/torrust/deployer/data \
torrust/tracker-deployer:latest \
show my-hetzner-envThe following build arguments can be used when building the image:
| Argument | Description | Example |
|---|---|---|
USER_ID |
User ID for file ownership (default: 1000) | --build-arg USER_ID=1001 |
All configuration files and generated directories should be treated as secrets:
envs/- Contains API tokens and credentials in JSON configuration filesdata/- Contains persisted environment state with sensitive informationbuild/- Contains generated configuration files
Recommendations:
-
Set restrictive permissions on these directories:
chmod 700 ./envs ./data ./build chmod 600 ./envs/*.json -
Never commit these directories to version control (they are gitignored by default)
-
Use volume mounts carefully - avoid exposing these directories unnecessarily
This follows the same security model as other infrastructure tools like Prometheus and Ansible, where configuration files are considered sensitive.
⚠️ If you use cloud-based AI coding agents (GitHub Copilot, Cursor, etc.), any secret the agent can see is potentially transmitted to the AI provider.
This includes configuration files, terminal output, and environment variables. Consider:
- Using local AI models for sensitive work
- Excluding
envs/,data/,build/from AI context (.copilotignore) - Not opening secret-containing directories in AI-enabled editors
See the ADR on Configuration as Secrets for details.
The Dockerfile supports multiple build targets:
Production-ready image with minimal footprint:
docker build --target release --tag torrust/tracker-deployer:release --file docker/deployer/Dockerfile .Includes additional debugging tools (vim, less, procps):
docker build --target debug --tag torrust/tracker-deployer:debug --file docker/deployer/Dockerfile .The container includes the following tools:
- torrust-tracker-deployer - The main deployer binary
- OpenTofu - Infrastructure as Code tool (Terraform fork)
- Ansible - Configuration management and automation
- SSH Client - For secure remote connections
- Git - Version control
- Non-root user: The container runs as the
deployeruser (UID 1000 by default) - Read-only SSH: SSH keys are mounted read-only (
:ro) - No privileged mode: The container does not require privileged access
- Minimal base image: Uses
debian:bookworm-slimfor reduced attack surface
If you encounter permission issues with mounted volumes, ensure the host directories exist and have correct permissions:
mkdir -p ./data ./build ./envs
chmod 755 ./data ./build ./envsEnsure your SSH keys have the correct permissions:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_rsa # or id_ed25519The container uses ./data relative to /var/lib/torrust/deployer inside the container. Make sure you're mounting to the correct paths:
# Correct mount paths
-v $(pwd)/data:/var/lib/torrust/deployer/data
-v $(pwd)/build:/var/lib/torrust/deployer/buildIf you created an environment but list shows nothing:
- Verify the data directory is mounted correctly
- Check the data directory on the host:
ls -la ./data/ - Ensure you're using the same volume mounts consistently
This is expected behavior. The Docker image only supports cloud providers (Hetzner). LXD requires system-level virtualization access that cannot be provided inside a container.
Solution: For LXD deployments, install the deployer directly on your host:
cargo run --bin dependency-installer install
cargo build --releaseIf provisioning fails with authentication errors:
-
Verify your API token is valid in the Hetzner Console
-
Ensure the token is correctly set in your environment configuration JSON file:
{ "provider": { "provider": "hetzner", "api_token": "your-actual-token-here", ... } } -
Validate the configuration before running:
- Use VS Code with the JSON schema validation
- Or use
create template --provider hetznerto generate a valid template
Run the debug image to troubleshoot issues:
docker run --rm -it \
-v $(pwd)/data:/var/lib/torrust/deployer/data \
-v $(pwd)/build:/var/lib/torrust/deployer/build \
-v $(pwd)/envs:/var/lib/torrust/deployer/envs \
-v ~/.ssh:/home/deployer/.ssh:ro \
torrust/tracker-deployer:debugdocker/deployer/
├── Dockerfile # Multi-stage Dockerfile
├── entry_script_sh # Container entrypoint script
└── README.md # This file