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.