Deploying a modern VPN/proxy service inside Docker containers is an efficient way to provide secure, reproducible, and scalable networking for websites, applications, and remote teams. This guide walks through deploying Trojan (trojan-go) inside Docker: from DNS and TLS prerequisites to container configuration, orchestration with Docker Compose, automated certificate renewal, logging, and basic hardening. The target audience includes webmasters, enterprise operators, and developers who want a production-ready, maintainable deployment.

Why choose Trojan in Docker?

Trojan is a TLS-based proxy designed to blend in with regular HTTPS traffic, offering strong obfuscation and performance. When combined with Docker, you gain:

  • Reproducible deployments and easy rollback
  • Isolated runtime with minimal host footprint
  • Fast scaling using container orchestration
  • Clear separation of concerns: certificate management, proxy service, and logging

Key considerations include proper TLS handling (real certificates), correct networking mode, secure config management (avoid embedding secrets in images), and robust logging & monitoring.

Overview of the architecture

This guide uses a small, production-appropriate architecture:

  • A public domain name pointing to your server (A/AAAA record)
  • Let’s Encrypt TLS certificates (automated via Certbot or Caddy)
  • trojan-go container running the proxy
  • Optional reverse proxy (Caddy or Nginx) when needed for certificate management or port sharing
  • Docker Compose to orchestrate containers and persistent volumes

Prerequisites

  • A Linux server with Docker & Docker Compose installed (Ubuntu, Debian, CentOS, etc.)
  • A registered domain name and control over DNS to set an A/AAAA record
  • Ports 443 (mandatory for Trojan) and optionally 80 (for HTTP-to-HTTPS ACME challenges) open in firewall
  • Basic familiarity with TLS and Linux administration

Recommended host setup

  • Keep Docker up to date and run containers as non-root where possible
  • Use a dedicated user for the project files (e.g., /opt/trojan)
  • Store secrets in files on disk with restrictive permissions or use Docker secrets in swarm/k8s

DNS and TLS: first steps

Before starting containers, set an A record for your domain/subdomain (for example trojan.example.com) pointed to your server’s public IP. Trojan relies on legitimate TLS certificates to mimic HTTPS; therefore, a valid certificate is essential.

You have two straightforward options for managing certificates:

  • Certbot (standalone or webroot): Runs on the host to fetch certs into a shared volume for containers to use.
  • Caddy: Acts as an automatic TLS reverse proxy; it can obtain and renew certs and reverse proxy traffic to the trojan container (useful if you need ports 80/443 on host and want automation).

Sample Docker Compose deployment

Below is a minimal, practical Docker Compose example using trojan-go with TLS certificates mounted from the host. This structure separates certs, config, and logs into persistent volumes.

version: "3.7"
services:
  trojan:
    image: p4gefau1t/trojan-go:latest
    container_name: trojan
    restart: always
    volumes:
      - ./config:/etc/trojan
      - ./certs:/etc/ssl/private    # contains fullchain.pem and privkey.pem
      - ./logs:/var/log/trojan
    ports:
      - "443:443/tcp"
      - "443:443/udp"
    environment:
      - TZ=UTC
    networks:
      - trojan-net

networks:
  trojan-net:
    driver: bridge

Notes:

  • The image p4gefau1t/trojan-go is widely used; you may choose another maintained image. Always verify image provenance and tags.
  • Mount the TLS certificate files as /etc/ssl/private/fullchain.pem and /etc/ssl/private/privkey.pem to match trojan-go config paths.
  • Map ports explicitly; Trojan uses TCP 443. UDP mapping may be useful for alternate transports (if your build supports it).

trojan-go configuration essentials

Create a JSON configuration file at ./config/config.json. A compact example with mandatory fields:

{
  "run_type": "server",
  "local_addr": "0.0.0.0",
  "local_port": 443,
  "remote_addr": "127.0.0.1",
  "remote_port": 80,
  "password": ["your-strong-password-or-uuid"],
  "ssl": {
    "cert": "/etc/ssl/private/fullchain.pem",
    "key": "/etc/ssl/private/privkey.pem",
    "sni": "trojan.example.com",
    "fallback_addr": "127.0.0.1",
    "fallback_port": 80
  },
  "websocket": {
    "enabled": false
  },
  "log": {
    "level": "info",
    "output": "/var/log/trojan/trojan.log"
  }
}

Important fields explained:

  • password: use a long random password or UUID. For multiple users supply an array.
  • ssl.sni: must match your certificate’s domain.
  • fallback_addr/fallback_port: used to serve a valid HTTP response for non-Trojan HTTPS clients; helpful to avoid detection.
  • log.output: store logs on a mounted volume for persistence and analysis.

Certificate automation strategies

Automating certificate issuance and renewal is essential. Two common approaches:

1) Certbot on the host with shared volumes

  • Install certbot and request a certificate: certbot certonly –standalone -d trojan.example.com
  • Copy or bind-mount the generated fullchain.pem and privkey.pem into the container’s certs directory.
  • Set up a cron job or systemd timer to run certbot renew and then reload/restart the trojan container after renewal to pick up the new certs: docker-compose restart trojan.

2) Use Caddy as a TLS terminator and reverse proxy

Caddy supports automatic Let’s Encrypt certificates and can reverse proxy to trojan-go via a specific TCP proxy configuration or via passthrough. Typical pattern:

  • Run Caddy to obtain certs for trojan.example.com, and configure it to proxy TCP to the trojan container.
  • Alternatively, run trojan on a non-privileged internal port (e.g., 8443) and let Caddy forward TCP 443 to trojan.

Benefits of Caddy: full automation, automatic reloading, and clean integration with Docker Compose. Downsides: adds another service to maintain.

Security hardening and best practices

  • Limit privileges: run containers with the least privileges needed; avoid –privileged. Use user namespaces if possible.
  • Protect secrets: never bake passwords or private keys into images. Use mounted files with strict filesystem permissions or Docker secrets in production clusters.
  • Firewall rules: allow port 443 from the Internet; restrict SSH and management ports with IP allowlists.
  • Monitoring & alerts: forward logs to a central syslog, ELK/EFK stack, or third-party log service. Monitor connection counts, CPU, and memory to detect abuse.
  • Rate limiting: consider upstream rate limiting to prevent resource exhaustion from abusive clients.
  • Regular updates: schedule regular updates for the trojan-go image and the host OS to pick up security fixes.

Logging, metrics and troubleshooting

Maintain clear logs and expose metrics for observability:

  • Configure trojan-go log level to info or warn in production. Keep logs in a mounted volume for retention.
  • Use container stdout/stderr for integration with Docker logging drivers (json-file, journald, splunk, etc.).
  • For troubleshooting TLS issues, verify certificates with openssl: openssl s_client -connect trojan.example.com:443 -servername trojan.example.com
  • Check that DNS resolves correctly and that firewall/NAT rules forward external traffic to the server.

Scaling and high availability

For enterprise deployments, consider these advanced strategies:

  • Multiple trojan instances: run multiple trojan containers across VMs, terminate TLS at a load balancer, or use DNS-based load balancing.
  • Kubernetes: run trojan-go as a Deployment with a Service of type LoadBalancer, and use cert-manager for ACME certificates.
  • Health checks: implement probe endpoints or use synthetic checks to ensure availability.
  • Session persistence: if you terminate TLS at a proxy and forward to trojan, ensure you preserve client TLS session semantics so Trojan can operate correctly.

Operational checklist before going live

  • Verify DNS A/AAAA records are correct and propagate.
  • Confirm valid TLS certificate is in place and paths in config.json point to correct files.
  • Test connections locally using a Trojan client configured with the same password and SNI.
  • Ensure container restarts automatically on failure and updates are planned.
  • Implement monitoring and alerting for uptime, error rates, and certificate expiration.

Summary

Containerizing Trojan provides a flexible, secure, and maintainable deployment model. The essential elements are correct TLS certificate management, secure configuration and secrets handling, persistent logging, and automation for renewal and restarts. For small-to-medium deployments, Docker Compose offers a simple orchestration method; for larger or mission-critical systems, leverage Kubernetes, external load balancers, and centralized certificate management like cert-manager.

For additional guides, templates, and tested Compose files tailored to common hosting environments, visit Dedicated-IP-VPN at https://dedicated-ip-vpn.com/. This site provides deeper resources for dedicated IP, VPN configuration patterns, and operational best practices to run secure proxy services reliably.