Servers Configuration
The servers.yml file defines your server topology (roles, tags) and environment variables. Connection credentials are provided separately via connection strings generated by dockflow setup.
Architecture
Dockflow uses Docker Swarm for orchestration. Each environment has one manager that receives deployments and optional workers that run distributed containers.
Basic Structure
# .dockflow/servers.yml
servers:
main_server:
role: manager
tags: [production]
defaults:
user: dockflow
port: 22
env:
all:
LOG_LEVEL: "info"
production:
LOG_LEVEL: "warn"This defines a single server named main_server with the manager role. Connection details (host, SSH key) come from secrets — not from this file.
Secrets
Dockflow needs SSH credentials to connect to your servers. The recommended approach is connection strings, generated automatically by dockflow setup.
Connection String (Recommended)
A connection string is a base64-encoded JSON containing all credentials for one server:
{
"host": "192.168.1.10",
"port": 22,
"user": "dockflow",
"privateKey": "-----BEGIN OPENSSH PRIVATE KEY-----\n...",
"password": "optional-sudo-password"
}Store it as [ENV]_[SERVERNAME]_CONNECTION:
.env.dockflow (local CLI)
# .env.dockflow (at project root — do not commit)
PRODUCTION_MAIN_SERVER_CONNECTION=eyJob3N0Ijoi...Do not share connection strings — they contain SSH private keys.
Server names use underscores in secret names. A server named worker_1 uses PRODUCTION_WORKER_1_CONNECTION.
Variable Overrides
Override any environment variable via secrets:
# Global override (all servers in production)
PRODUCTION_DATABASE_URL=postgres://secret:5432/db
# Server-specific override
PRODUCTION_MAIN_SERVER_DATABASE_URL=postgres://primary:5432/dbServer Fields
| Field | Required | Default | Description |
|---|---|---|---|
role | No | manager | Node role: manager or worker |
tags | Yes | - | Environment tags (e.g., [production]) |
env | No | - | Server-specific environment variables |
host | No | From connection string | Override host (rarely needed) |
user | No | defaults.user | Override SSH user |
port | No | defaults.port | Override SSH port |
Examples
Single-Node
For simple deployments, a single manager is sufficient:
servers:
production_server:
role: manager
tags: [production]Cluster Setup
Before your first multi-node deployment, initialize the Swarm cluster:
Configure secrets
Add connection strings for all nodes (manager + workers) in .env.dockflow or your CI/CD platform.
Initialize Swarm
dockflow setup swarm productionThis command will:
- Open firewall ports (2377, 7946, 4789) on all nodes
- Initialize Swarm on the manager
- Join workers to the cluster
Deploy
dockflow deploy productionSwarm automatically distributes containers to workers based on resource availability and placement constraints.
You only need to run setup swarm once per environment. After that, just use dockflow deploy.
Environment Variables
Define variables that are inherited based on tags:
env:
# Applied to ALL environments
all:
APP_NAME: "{{ project_name }}"
LOG_LEVEL: "info"
TZ: "UTC"
# Override for production
production:
LOG_LEVEL: "warn"
DATABASE_URL: "postgres://prod-db:5432/app"
# Override for staging
staging:
LOG_LEVEL: "debug"Variable Priority
Variables are resolved from lowest to highest priority. A higher-priority source always overrides a lower one:
Jinja2 Templating
Values in servers.yml support Jinja2 templating:
env:
all:
APP_NAME: "{{ project_name }}"
STACK_NAME: "{{ project_name }}-{{ env }}"Available variables:
| Variable | Description |
|---|---|
{{ project_name }} | From config.yml |
{{ env }} | Current environment being deployed |
{{ version }} | Deployment version |
{{ current.name }} | Current server name |
{{ current.host }} | Current server host |
{{ current.role }} | Current server role (manager/worker) |
Next: Docker Compose — define your application services, networks, and volumes.