Templates
Dockflow renders files with Jinja2 templating before deployment, injecting environment-specific values into your configuration.
Automatic Rendering
All files inside .dockflow/ are automatically rendered with Jinja2 during deployment. No configuration needed.
# .dockflow/docker/docker-compose.yml — automatically rendered
services:
app:
environment:
DOMAIN: {{ current.env.domain_name }}
ports:
- {{ current.env.app_port }}:3000Custom Templates
For files outside .dockflow/, declare them in .dockflow/config.yml. Paths are relative to the project root:
# .dockflow/config.yml
templates:
- "config/application.yml"
- "nginx/nginx.conf"
- "scripts/init.sh"These files are rendered in-place. To output to a different location, use the extended format:
# .dockflow/config.yml
templates:
- "scripts/init.sh" # Rendered in-place
- src: "config/app.yml.j2" # Source → different destination
dest: "config/app.yml"Available Variables
Basic Variables
| Variable | Description | Example |
|---|---|---|
{{ env }} | Target environment | production |
{{ version }} | Deployment version | 1.2.3 |
{{ branch_name }} | Git branch name | main |
{{ server_name }} | Current server name | manager_1 |
{{ config.project_name }} | Project name from config | my-app |
Current Server ({{ current }})
The current object contains information about the server being deployed to:
| Variable | Description | Example |
|---|---|---|
{{ current.name }} | Server name from servers.yml | manager_1 |
{{ current.host }} | Server IP or hostname | 192.168.1.10 |
{{ current.port }} | SSH port | 22 |
{{ current.user }} | SSH user | dockflow |
{{ current.role }} | Server role | manager or worker |
{{ current.tags }} | Server tags | ['production'] |
{{ current.env.my_var }} | Environment variable (lowercase key) | my-value |
All environment variable keys must be lowercase in templates. Even if you define DB_HOST in servers.yml, you must reference it as {{ current.env.db_host }}.
Config ({{ config }})
All values from your config.yml:
database: {{ config.project_name }}-dbAll Servers ({{ servers }})
All servers in the current environment, keyed by name. Each server has the same properties as current.
Cluster Metadata ({{ cluster }})
| Variable | Description | Example |
|---|---|---|
{{ cluster.size }} | Total number of nodes | 5 |
{{ cluster.manager_count }} | Number of managers | 1 |
{{ cluster.worker_count }} | Number of workers | 4 |
{{ cluster.managers }} | List of manager IPs | ['192.168.1.10'] |
{{ cluster.workers }} | List of worker IPs | ['192.168.1.11', '192.168.1.12'] |
Jinja2 Syntax
Conditionals
logging:
{% if env == 'production' %}
level: "warn"
format: "json"
{% else %}
level: "debug"
format: "pretty"
{% endif %}
features:
debug_toolbar: {{ 'true' if env != 'production' else 'false' }}Default values
database:
pool_size: {{ current.env.db_pool_size | default(10) }}
timeout: {{ current.env.db_timeout | default(30) }}Loops
upstream backend {
{% for name, srv in servers.items() %}
{% if 'app' in srv.tags %}
server {{ srv.host }}:{{ srv.env.app_port | default(3000) }};
{% endif %}
{% endfor %}
}Execution Order
Templates are rendered early in the deployment process:
- Load configuration (
config.yml,servers.yml) - Render all files in
.dockflow/(docker-compose, Dockerfiles, etc.) - Render custom templates from
config.yml - Auto-tag Docker images in
docker-compose.yml(ifimage_auto_tagis enabled) - Build Docker images
- Deploy to swarm
Templates are rendered before the Docker build, so the rendered files will be included in your Docker images if they are in the build context.
Examples
These are example template files you could create in your project.
Application config (e.g. config/application.yml)
database:
host: "{{ current.env.db_host }}"
port: {{ current.env.db_port | default(5432) }}
name: "{{ current.env.db_name }}"
password: "{{ current.env.db_password }}"
server:
environment: "{{ env }}"
version: "{{ version }}"Nginx reverse proxy (e.g. nginx/myapp.conf.j2)
server {
listen 80;
server_name {{ current.env.domain_name }};
location / {
proxy_pass http://127.0.0.1:{{ current.env.app_port }};
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}Init script (e.g. scripts/init.sh)
#!/bin/bash
echo "Initializing {{ config.project_name }} v{{ version }}"
echo "Environment: {{ env }}"
{% if env == 'production' %}
echo "Running production optimizations..."
{% else %}
echo "Running in development mode"
{% endif %}PostgreSQL access control (e.g. config/pg_hba.conf.j2)
{% for name, srv in servers.items() %}
{% if srv.role == 'worker' or 'app' in srv.tags %}
host all all {{ srv.host }}/32 md5
{% endif %}
{% endfor %}