前言
将 Trojan-Go 服务制作成 Docker 镜像,方便快速部署和迁移。
实测将 Trojan-Go 容器化不会对速度造成影响,该跑满速的还是跑满速:

方案概述
目标是将 Trojan-Go 服务和伪装用的页面封装在镜像中,而证书申请和 Nginx 外置在宿主机上。
最终的启动命令类似:docker run -d \ --name trojan-go \ --restart=unless-stopped \ # 映射到宿主机的 8443 端口,之后通过 Nginx 分流 # 客户端侧依然配置为 443 端口 -p 8443:443 \ # Trojan-Go 的配置文件、证书和密钥存放的目录 -v /rab/docker/trojan-go/:/etc/trojan-go/ \ -e TROJAN_GO_SERVICE_PASSWORD="yourTrojanPassword" \ -e TROJAN_GO_SERVICE_DOMAIN="trojan.example.com" \ rabbir/trojan-go:latest实际启动命令请参考:Trojan-Go-Docker/README.md
- 确认下 Trojan-Go 作者提供的镜像
- 编辑 Dockerfile 构建镜像
- 实际部署
操作步骤
一、确认下 Trojan-Go 作者提供的镜像
Dockerfile:trojan-go/Dockerfile
镜像:p4gefau1t/trojan-go
FROM golang:alpine AS builder
WORKDIR /
ARG REF
RUN apk add git make &&\
git clone https://github.com/p4gefau1t/trojan-go.git
RUN if [[ -z "${REF}" ]]; then \
echo "No specific commit provided, use the latest one." \
;else \
echo "Use commit ${REF}" &&\
cd trojan-go &&\
git checkout ${REF} \
;fi
RUN cd trojan-go &&\
make &&\
wget https://github.com/v2fly/domain-list-community/raw/release/dlc.dat -O build/geosite.dat &&\
wget https://github.com/v2fly/geoip/raw/release/geoip.dat -O build/geoip.dat &&\
wget https://github.com/v2fly/geoip/raw/release/geoip-only-cn-private.dat -O build/geoip-only-cn-private.dat
FROM alpine
WORKDIR /
RUN apk add --no-cache tzdata ca-certificates
COPY --from=builder /trojan-go/build /usr/local/bin/
COPY --from=builder /trojan-go/example/server.json /etc/trojan-go/config.json
ENTRYPOINT ["/usr/local/bin/trojan-go", "-config"]
CMD ["/etc/trojan-go/config.json"]
-
系统镜像使用
alpine -
可执行文件位于
/usr/local/bin/trojan-go -
配置文件位于
/etc/trojan-go/config.json -
配置文件内容:
{ "run_type": "server", "local_addr": "0.0.0.0", "local_port": 443, "remote_addr": "127.0.0.1", "remote_port": 80, "password": [ "your_password" ], "ssl": { "cert": "your_cert.crt", "key": "your_key.key", "sni": "your-domain-name.com" }, "router": { "enabled": true, "block": [ "geoip:private" ], "geoip": "/usr/share/trojan-go/geoip.dat", "geosite": "/usr/share/trojan-go/geosite.dat" } } -
配置文件中的
password、cert、key和sni需要替换。 -
后续可以将证书和配置文件放在一起,映射给容器。
二、编辑 Dockerfile 构建镜像
1、Trojan-Go 服务相关
这里直接使用作者构建的 Docker 镜像作为基础镜像,因此不做配置。
# 镜像选择 p4gefau1t/trojan-go
FROM p4gefau1t/trojan-go:latest
2、伪装页面相关
Web 服务器使用更轻量化的 Caddy。
单页项目在 GitHub 搜一下就行,有一大堆。我这里挑了 YaninaTrekhleb/restaurant-website 这个项目,上完 AWS 的课程之后对咖啡店这个主题还蛮有好感的。
# 1. 安装 Caddy
WORKDIR /root/
RUN wget https://github.com/caddyserver/caddy/releases/download/v2.8.4/caddy_2.8.4_linux_amd64.tar.gz
RUN tar zxvf caddy_2.8.4_linux_amd64.tar.gz
RUN mv caddy /usr/local/bin/
# 2. 下载伪装页面
RUN mkdir -vp /var/www/html/
WORKDIR /var/www/html/
RUN wget https://github.com/YaninaTrekhleb/restaurant-website/archive/refs/heads/master.zip
RUN unzip master.zip
RUN mv /var/www/html/restaurant-website-master/* /var/www/html/
# 3. 编辑 Caddy 的配置文件
RUN mkdir -vp /etc/caddy/
RUN echo ":80 {" > /etc/caddy/Caddyfile
RUN echo " root * /var/www/html" >> /etc/caddy/Caddyfile
RUN echo " file_server browse" >> /etc/caddy/Caddyfile
RUN echo " try_files {path} /index.html" >> /etc/caddy/Caddyfile
RUN echo "}" >> /etc/caddy/Caddyfile
Caddy启动相关:# 前台运行 caddy run --config /etc/caddy/Caddyfile # 后台运行 caddy start --config /etc/caddy/Caddyfile
3、entrypoint.sh 启动脚本
entrypoint.sh 脚本核心内容:
# 3. 启动 Caddy
caddy start --config /etc/caddy/Caddyfile
# 4. 替换 Trojan-Go 配置文件内容
# 替换域名和密码
sed -i "s/your_password/$TROJAN_GO_SERVICE_PASSWORD/" /etc/trojan-go/config.json
sed -i "s/your-domain-name.com/$TROJAN_GO_SERVICE_DOMAIN/" /etc/trojan-go/config.json
# 将 your_cert.crt 替换为 /etc/trojan-go/certificate.crt
sed -i "s/your_cert.crt/\/etc\/trojan-go\/certificate.crt/" /etc/trojan-go/config.json
# 将 your_key.key 替换为 /etc/trojan-go/private.key
sed -i "s/your_key.key/\/etc\/trojan-go\/private.key/" /etc/trojan-go/config.json
# 5. 启动 Trojan-Go
/usr/local/bin/trojan-go -config /etc/trojan-go/config.json
4、托管 GitHub 并使用 GitHub Action 自动构建镜像
GitHub 仓库:senjianlu/Trojan-Go-Docker
Docker Hub:rabbir/trojan-go
三、实际部署
只记命令,详细的过程和解析我其他博文里都有。
1、安装 Docker 环境
参考:Ubuntu 20.04 从官方源安装最新的 Docker
sudo apt-get update
sudo apt-get install ca-certificates curl gnupg lsb-release
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin
docker -v
2、安装最新的 Nginx
参考:Installing Prebuilt Ubuntu Packages
sudo apt install curl gnupg2 ca-certificates lsb-release ubuntu-keyring
curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
gpg --dry-run --quiet --no-keyring --import --import-options import-show /usr/share/keyrings/nginx-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" \
| sudo tee /etc/apt/sources.list.d/nginx.list
echo -e "Package: *\nPin: origin nginx.org\nPin: release o=nginx\nPin-Priority: 900\n" \
| sudo tee /etc/apt/preferences.d/99nginx
sudo apt update
sudo apt install nginx
service nginx status
之后修改下默认的配置,使 acme.sh 能够通过 80 端口验证域名所有权:
mv /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf.bak
vi /etc/nginx/conf.d/default.conf
# 非域名访问返回 500 错误
server {
listen 80;
listen [::]:80;
server_name _;
location / {
return 500;
}
# 特殊的证书认证用的路径
location /.well-known/acme-challenge/ {
# acme.sh --webroot 模式,认证文件生成后放置的路径
root /var/acme/webroot/;
}
}
nginx -s reload
service nginx restart
3、创建证书申请用目录和临时容器
mkdir -vp /rab/docker/trojan-go/
docker run -d --name trojan-go alpine /bin/sh
4、安装 acme.sh 并申请证书
# 安装所需软件
apt-get install curl
apt-get install socat
# 安装 acme
cd /root
curl https://get.acme.sh | sh
# 添加软链接
ln -s /root/.acme.sh/acme.sh /usr/local/bin/acme.sh
# 切换 CA 机构
acme.sh --set-default-ca --server letsencrypt
# 申请证书
acme.sh --issue -d trojan.example.com --webroot /var/acme/webroot/ --force
# 安装证书
acme.sh --install-cert -d trojan.example.com \
--fullchain-file /rab/docker/trojan-go/certificate.crt \
--key-file /rab/docker/trojan-go/private.key \
--reloadcmd "docker restart trojan-go"
5、启动 Trojan-Go 容器
# 删除临时容器
docker stop trojan-go && docker rm trojan-go
# 启动 Trojan-Go 容器
docker run -d \
--name trojan-go \
--restart=unless-stopped \
-p 8443:443 \
-v /rab/docker/trojan-go/:/etc/trojan-go/ \
-e TROJAN_GO_SERVICE_PASSWORD="yourTrojanPassword" \
-e TROJAN_GO_SERVICE_DOMAIN="trojan.example.com" \
rabbir/trojan-go:latest
6、配置 Nginx 根据域名分流到 Trojan-Go 容器
vi /etc/nginx/nginx.conf
添加以下内容:
stream {
# SNI 识别,将一个个域名映射成一个配置名
map $ssl_preread_server_name $stream_map {
trojan.example.com trojan;
}
upstream trojan {
server 127.0.0.1:8443;
}
# 端口复用
server {
listen 443 reuseport;
proxy_pass $stream_map;
ssl_preread on;
}
}
nginx -s reload
service nginx restart
7、连接测试
Surge 下可以连接:

伪装页面也可以正常访问:

8、BBR 加速
确保内核版本大于 4.9:
uname -r
我这边是 5.13,直接开启 BBR 加速:
echo "net.core.default_qdisc=fq" | sudo tee -a /etc/sysctl.conf
echo "net.ipv4.tcp_congestion_control=bbr" | sudo tee -a /etc/sysctl.conf
使其生效:
sysctl -p
确认是否开启成功:
sysctl net.ipv4.tcp_congestion_control

保险起见可以 reboot 重启一下,顺便测试 Nginx 和 Docker 的 trojan-go 容器在开机时是否自启。
结束。
参考资料: