Skip to content

Secure File Transfer On-Premises with Docker — Xferity Deployment Guide

Secure File Transfer On-Premises with Docker

Section titled “Secure File Transfer On-Premises with Docker”

This guide covers deploying Xferity as a secure, self-hosted MFT platform using Docker or Docker Compose on your own infrastructure.

Teams choose self-hosted Docker deployment when they need:

  • Direct control over where transfer runtime and data live
  • No mandatory cloud dependencies or SaaS transfer service
  • Consistent deployment across environments (staging, production)
  • Integration with existing container infrastructure
  • Air-gapped or restricted-network operation

Option A: Single container (file-backed, no database)

Section titled “Option A: Single container (file-backed, no database)”

Use this for simple deployments without a database dependency.

The repository includes a multi-stage Dockerfile.

Terminal window
docker build -t xferity:latest .
/app/config/ # global config and partner YAML files
/app/flows/ # flow YAML files
/app/state/ # local state files
/app/logs/ # application logs
/app/audit/ # audit JSONL file
/app/storage/ # staging and landing paths
/app/keys/ # PGP keys and certificates
Terminal window
docker run -d \
-v /host/config:/app/config \
-v /host/flows:/app/flows \
-v /host/state:/app/state \
-v /host/logs:/app/logs \
-v /host/audit:/app/audit \
-v /host/storage:/app/storage \
-v /host/keys:/app/keys \
-e SFTP_PASSWORD=your-secret \
-p 8080:8080 \
xferity:latest run-service my-flow --interval-seconds 300

Option B: Docker Compose with PostgreSQL (full feature set)

Section titled “Option B: Docker Compose with PostgreSQL (full feature set)”

Use this for production deployments with the full control plane.

The repository includes docker-compose.yml with the xferity service and mounts for all runtime paths.

Terminal window
docker compose up xferity
services:
postgres:
image: postgres:15
environment:
POSTGRES_DB: xferity
POSTGRES_USER: xferity
POSTGRES_PASSWORD_FILE: /run/secrets/pg_password
volumes:
- pgdata:/var/lib/postgresql/data
secrets:
- pg_password
xferity:
image: xferity:latest
depends_on:
- postgres
volumes:
- ./config:/app/config
- ./flows:/app/flows
- ./state:/app/state
- ./logs:/app/logs
- ./audit:/app/audit
- ./storage:/app/storage
- ./keys:/app/keys
environment:
STATE_BACKEND: postgres
POSTGRES_DSN: "postgres://xferity:${PG_PASSWORD}@postgres:5432/xferity?sslmode=require"
secrets:
- pg_password
ports:
- "8080:8080"

Use secret references — never plaintext environment variables in production

Section titled “Use secret references — never plaintext environment variables in production”

Instead of SFTP_PASSWORD=mypassword, use Docker secrets:

Terminal window
echo "mypassword" | docker secret create sftp_password -

Reference in config:

auth:
password: file:/run/secrets/sftp_password

Add to global config:

security:
hardened_mode: true

With hardened mode enabled, Xferity refuses to start if:

  • Plaintext credentials are found in sensitive config fields
  • Postgres sslmode is set to disable
  • SFTP hosts have allow_insecure_host_key: true
  • FTPS partners have skip_verify: true
  • The UI is exposed without authentication configuration
volumes:
- /persistent/audit:/app/audit

Audit logs should persist on the host — not inside the container. For evidence retention, export or ship to an external system.

The Xferity Dockerfile creates a non-root user. Do not override this. Do not run as root.


The fingerprint approach works cleanly in Docker — no file mounting needed:

host_key_fingerprint: "SHA256:abc123..."

Or mount a known_hosts file:

known_hosts: file:/app/keys/partners/acme_known_hosts
server_cert_fingerprint: "SHA256:xyz789..."

Xferity requires no mandatory outbound internet connections:

  • License validation is local by default
  • No phone-home or telemetry
  • HashiCorp Vault, AWS SM, Azure KV are all optional
  • env: and file: secret providers work fully offline
  • Local AES-256 vault works in Postgres-backed mode without external services

For fully offline installations:

  1. Build the Docker image in a connected environment
  2. Export: docker save xferity:latest > xferity.tar
  3. Transfer to air-gapped host
  4. Import: docker load < xferity.tar

healthcheck:
test: ["CMD", "wget", "-q", "-O-", "http://localhost:8080/health/worker"]
interval: 30s
timeout: 5s
retries: 3

/health/worker is unauthenticated — safe for container orchestration probes.

Add Prometheus scraper to your monitoring stack pointing to /metrics (authenticated admin access).


  • AS2 (with MDN)
  • SFTP / FTPS
  • OpenPGP + CMS
  • Durable job execution
  • Retry and resume
  • Air-gapped deployment