MTProxyHub
All posts
9 min

Running MTProxy in Docker: A Complete Guide

A step-by-step guide to running MTProxy via Docker on a Linux server: secret generation, Fake TLS, configuring WORKERS, container hardening, and monitoring.

Running MTProxy in Docker: A Complete Guide

Public proxies are unstable, overloaded, and require trusting strangers. Your own MTProxy on a VPS costs $3–5 per month, can be set up in a few minutes, and guarantees that only you control access. In this guide, we will go through the entire process: from ordering a server to a working Fake TLS proxy.

What you will need

  • A VPS on Linux (Ubuntu 22.04 or Debian 12 — recommended)
  • Minimum specs: 1 CPU, 512 MB RAM, 10 GB SSD
  • Server location: outside the blocked region (Netherlands, Finland, Germany — popular choices)
  • Cost: starting from $3–5/mo at Hetzner, DigitalOcean, Vultr

Step 1: Server Preparation

Connect via SSH and run a package update:

sudo apt update && sudo apt upgrade -y

Install Docker using the official script:

curl -fsSL https://get.docker.com | sudo sh
sudo usermod -aG docker $USER
newgrp docker

Verify the installation:

docker --version

Open port 443 in the firewall:

sudo ufw allow 443/tcp
sudo ufw enable

Step 2: Generating a Secret

Never use SECRET=000... from internet examples — it is insecure and easily identifiable. Always generate a random key:

openssl rand -hex 16

Example output: a3f7c2e1d5b8904f6a2c1e3d7b9f4a2e

For Fake TLS, a special secret format is required: a hex-encoded camouflage domain is appended to the key. You can generate it manually:

# Generate the base key
KEY=$(openssl rand -hex 16)

# Encode SNI-domain to hex
DOMAIN="google.com"
DOMAIN_HEX=$(echo -n "$DOMAIN" | xxd -p)

# Final Fake TLS secret
echo "ee${KEY}${DOMAIN_HEX}"

Or you can use a ready-made generator: https://mtproto.co/ — an open tool for generating Fake TLS secrets.

Step 3: Running the Container

Run the official container:

docker run -d \
  --name mtproxy \
  --restart always \
  -p 443:443 \
  -e SECRET="YOUR_SECRET_HERE" \
  -e WORKERS=1 \
  -v proxy-config:/data \
  telegrammessenger/proxy:latest

Parameters:

  • --restart always — auto-start after server reboot
  • -p 443:443 — map port 443
  • SECRET — your generated secret (with ee prefix for Fake TLS)
  • WORKERS — number of worker processes (usually 1 per CPU core)

Step 4: Getting the Connection Link

docker logs mtproxy 2>&1 | grep "tg://"

You will see a link like:

tg://proxy?server=1.2.3.4&port=443&secret=ee...

Open it on your device — Telegram will automatically prompt you to add the proxy.

Step 5: Container Hardening

The basic setup works, but several security improvements are recommended for production:

docker run -d \
  --name mtproxy \
  --restart always \
  -p 443:443 \
  --read-only \
  --tmpfs /tmp \
  --cap-drop ALL \
  --security-opt no-new-privileges \
  -e SECRET="YOUR_SECRET_HERE" \
  -e WORKERS=1 \
  -v proxy-config:/data \
  telegrammessenger/proxy:latest

Added flags:

  • --read-only — read-only container file system
  • --tmpfs /tmp — temporary RAM-disk for /tmp
  • --cap-drop ALL — drop all Linux capabilities
  • --security-opt no-new-privileges — prevent privilege escalation

Adjusting WORKERS

The WORKERS parameter defines the number of worker processes. Official rule: 1 worker ≈ 60,000 concurrent connections.

Server SizeRecommended WORKERS
1 CPU, up to 500 users1
2 CPU, up to 2000 users2
4+ CPU, public proxy4+
Weak server with unstable load2–4 (distributes connections better)

Alternative: mtg (Go implementation)

9seconds/mtg is a popular alternative in Go featuring Prometheus metrics and lower memory consumption:

docker run -d \
  --name mtg \
  --restart always \
  -p 443:443 \
  nineseconds/mtg:latest \
  run "YOUR_SECRET"

The official image is more stable and better documented; mtg is faster under heavy loads. The choice depends on your priorities.

Monitoring and Logs

# Current logs
docker logs -f mtproxy

# Number of active connections
docker exec mtproxy cat /proc/net/tcp | wc -l

# Resource usage
docker stats mtproxy

If you see Too many open files in the logs, you need to increase the file descriptor limits. Add to the run command:

--ulimit nofile=65536:65536

Updating the Container

docker pull telegrammessenger/proxy:latest
docker stop mtproxy && docker rm mtproxy
# Repeat the run command from Step 3

FAQ

Which port is best to use? Port 443 is recommended. Open everywhere, standard for HTTPS.

Do I need to open ports in the firewall? Yes: sudo ufw allow 443/tcp on Ubuntu/Debian.

How many users can it handle? 1 CPU, 1 GB RAM → 1000–3000 concurrent users with WORKERS=1.

What is the difference between mtg and the official image? mtg is written in Go, consumes less memory, and has Prometheus metrics. The official image is in C, more stable, and more widespread.

How do I verify the proxy is working? Telegram → Settings → Data and Storage → Proxy → enter details → green indicator.


Set up your own server? Read how to optimize it for high loads and how to monetize it via Promoted Channels.

Prefer not to mess with servers? Check out the list of ready working proxies. Updated every 60 seconds.