协议打包docker
看日志已正常启动,端口 8061 对外服务可用。接下来把机器人 config.json 的 wx861_base_url 指到 http://43.134.111.229:8061,扫码即可用。
一次性完整脚本(下次直接复制)
把整个 ipad861 源码目录放到 /root/wx861/ipad861 后,执行:
#!/usr/bin/env bash
set -euo pipefail
# 固定端口/镜像/容器名
PORT="${PORT:-8061}"
IMAGE_NAME="wx861"
CONTAINER_NAME="wx861"
cd "$(dirname "$0")"
mkdir -p conf data ipad861
# 0) 如有部署包内 swagger,先同步到宿主映射目录,确保根路径可打开
if [ -d "wechatReal08/linux部署/linux部署包/home/server/ipad861/wechatReal08/bin/swagger" ]; then
mkdir -p wechatReal08/swagger
cp -rf wechatReal08/linux部署/linux部署包/home/server/ipad861/wechatReal08/bin/swagger/* wechatReal08/swagger/ 2>/dev/null || true
fi
# 1) conf/app.conf(确保 0.0.0.0 + copyrequestbody + 本地 Redis)
if [ ! -f conf/app.conf ]; then
cat > conf/app.conf <<'CONF'
appname = wxapi
httpaddr = "0.0.0.0"
httpport = 8061
runmode = prod
EnableDocs = true
copyrequestbody = true
redislink = 127.0.0.1:6379
redisdbnum = 2
syncmessage = true
msgpush = false
sessionon = true
longlinkenabled = true
longlinkconnecttimeout = "30m"
rabbitmq = false
rabbitmqurl = ""
CONF
else
sed -ri 's@^(httpaddr)\s*=.*@\1 = "0.0.0.0"@i' conf/app.conf || true
grep -qi '^copyrequestbody' conf/app.conf && sed -ri 's/^(copyrequestbody)\s*=.*/\1 = true/i' conf/app.conf || echo 'copyrequestbody = true' >> conf/app.conf
grep -qi '^redislink' conf/app.conf && sed -ri 's/^(redislink)\s*=.*/\1 = 127.0.0.1:6379/i' conf/app.conf || echo 'redislink = 127.0.0.1:6379' >> conf/app.conf
grep -qi '^redisdbnum' conf/app.conf && sed -ri 's/^(redisdbnum)\s*=.*/\1 = 2/i' conf/app.conf || echo 'redisdbnum = 2' >> conf/app.conf
fi
# 2) 入口脚本:装配协议文件 -> 启动 Redis -> 启动协议
cat > ipad861/entrypoint.sh <<'SH'
#!/bin/sh
set -e
copy_first_exist() {
dest="$1"; shift
for src in "$@"; do
if [ -f "$src" ] || [ -d "$src" ]; then
if [ -d "$src" ]; then cp -rf "$src" "$dest"; else cp -f "$src" "$dest"; fi
return 0
fi
done
return 1
}
cd /usr/wic-go
mkdir -p /data /usr/wic-go/lib /usr/local/lib
# start.sh
copy_first_exist ./start.sh \
/host/wechatReal08/start.sh \
/host/ipad861/wechatReal08/start.sh
# main 二进制(wechat_linux)
copy_first_exist ./main \
"/host/wechatReal08/linux部署/linux部署包/home/server/ipad861/wechatReal08/bin/wechat_linux" \
/host/wechatReal08/bin/wechat_linux
# dat
copy_first_exist ./08sae.dat /host/wechatReal08/08sae.dat "/host/wechatReal08/linux部署/linux部署包/home/server/ipad861/wechatReal08/bin/08sae.dat" || true
copy_first_exist ./rqtx.dat /host/wechatReal08/rqtx.dat "/host/wechatReal08/linux部署/linux部署包/home/server/ipad861/wechatReal08/bin/rqtx.dat" || true
# so 库
copy_first_exist /usr/local/lib/libv08.so /host/wechatReal08/lib/libv08.so "/host/wechatReal08/linux部署/linux部署包/home/server/ipad861/wechatReal08/bin/lib/libv08.so" || true
copy_first_exist /usr/local/lib/libz.so /host/wechatReal08/lib/libz.so "/host/wechatReal08/linux部署/linux部署包/home/server/ipad861/wechatReal08/bin/lib/libz.so" || true
copy_first_exist /usr/local/lib/libz.so.1.3.1 /host/wechatReal08/lib/libz.so.1.3.1 "/host/wechatReal08/linux部署/linux部署包/home/server/ipad861/wechatReal08/bin/lib/libz.so.1.3.1" || true
# key
mkdir -p /usr/wic-go/lib
copy_first_exist /usr/wic-go/lib/key /host/wechatReal08/lib/key "/host/wechatReal08/linux部署/linux部署包/home/server/ipad861/wechatReal08/bin/lib/key" || true
chmod -R 600 /usr/wic-go/lib/key 2>/dev/null || true
# swagger:如果容器目录不存在且宿主有 swagger,则复制(已挂载时会跳过)
if [ ! -d ./swagger ] && [ -d /host/wechatReal08/swagger ]; then
cp -rf /host/wechatReal08/swagger ./swagger
fi
# 校验
[ -x ./main ] || chmod +x ./main 2>/dev/null || true
[ -x ./start.sh ] || chmod +x ./start.sh 2>/dev/null || true
command -v ldconfig >/dev/null 2>&1 && ldconfig || true
if [ ! -f ./start.sh ] || [ ! -x ./main ]; then
echo "缺少 start.sh 或 wechat_linux(main),请确认已上传 wechatReal08 目录"
exit 1
fi
# 先启 Redis,再启协议
redis-server --appendonly yes --dir /data --bind 127.0.0.1 --port 6379 &
for i in $(seq 1 60); do
redis-cli -h 127.0.0.1 -p 6379 ping >/dev/null 2>&1 && break
sleep 0.5
done
redis-cli -h 127.0.0.1 -p 6379 ping >/dev/null 2>&1 || { echo "Redis failed to start in time"; exit 1; }
exec ./start.sh
SH
chmod +x ipad861/entrypoint.sh
# 3) 运行时 Dockerfile(不 COPY 业务文件)
cat > ipad861/Dockerfile.runtime <<'EOF'
FROM ubuntu:24.04
ENV DEBIAN_FRONTEND=noninteractive TZ=Asia/Shanghai \
LD_LIBRARY_PATH=/usr/local/lib:/usr/wic-go:$LD_LIBRARY_PATH
RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates tzdata libc6 libstdc++6 redis-server redis-tools && \
rm -rf /var/lib/apt/lists/*
WORKDIR /usr/wic-go
COPY ipad861/entrypoint.sh /usr/wic-go/entrypoint.sh
EXPOSE 8061
ENTRYPOINT ["/usr/wic-go/entrypoint.sh"]
EOF
# 4) docker-compose(映射 8061,挂载 swagger)
cat > docker-compose.yml <<YML
version: "3.8"
services:
${CONTAINER_NAME}:
image: ${IMAGE_NAME}:latest
build:
context: .
dockerfile: ipad861/Dockerfile.runtime
pull_policy: never
container_name: ${CONTAINER_NAME}
restart: unless-stopped
environment:
- TZ=Asia/Shanghai
- LD_LIBRARY_PATH=/usr/local/lib:/usr/wic-go
working_dir: /usr/wic-go
ports:
- "${PORT}:8061"
volumes:
- ./conf:/usr/wic-go/conf:ro
- ./data:/data
- ./wechatReal08/swagger:/usr/wic-go/swagger:ro
- ./:/host:ro
YML
# 5) 启动
docker compose down --remove-orphans || true
docker compose up -d --build
sleep 1
docker compose ps
docker logs -f "${CONTAINER_NAME}" | sed -n '1,200p'
机器人接入
-
config.json:
-
"channel_type": "wx861"
-
"wx861_base_url": "http://43.134.111.229:8061"
-
"wx861_token": ""(无鉴权留空)
-
"wx861_ws_url": ""(留空自动短轮询)
-
启动机器人,按日志里的 ASCII/PNG 二维码扫码。
常用
-
查看日志:docker logs -f ipad861
-
重启更新(变更源码/库后):docker compose up -d --build
-
仅改配置:docker compose up -d
-
验证服务:浏览器打开 http://43.134.111.229:8061/swagger/
-
安全组:只放行 TCP 8061;6379 无需对外开。
Thoughtfor 15s
安全组:只放行 TCP 8061;6379 无需对外开。快速自检(云服务器执行)
- 看容器状态
docker ps --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}'
本机探活(应返回 200/301/302)
curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:8061/swagger/
外网探活(本地电脑)
curl -s -o /dev/null -w "%{http_code}\n" http://43.134.111.229:8061/swagger/
机器人侧最后一步
-
在机器人 config.json 里:
-
"channel_type": "wx861"
-
"wx861_base_url": "http://43.134.111.229:8061"
-
"wx861_token": ""
-
"wx861_ws_url": ""
-
启动机器人后按日志二维码扫码。
日常运维
-
查看日志: docker logs -f ipad861
-
更新协议(有改动时): docker compose up -d --build
-
仅改配置: docker compose up -d
-
重启: docker compose restart ipad861
-
用途: wx861_ws_url 是 WebSocket 推送地址,用于消息实时推送(低延迟)。可与 HTTP 8061 同时使用;配置后优先走 WS,失败回退轮询。
-
端口: 默认 8099。外网地址写 ws://你的IP:8099/ws/{wxid}。
把下面完整脚本保存为 /root/ipad861/start_docker.sh,并执行:chmod +x /root/ipad861/start_docker.sh && bash /root/ipad861/start_docker.sh
#!/usr/bin/env bash
set -euo pipefail
# 外网端口(可用 PORT/WSPORT 覆盖)
PORT="${PORT:-8061}" # HTTP API 对外端口
WSPORT="${WSPORT:-8099}" # WebSocket 对外端口
# 镜像/容器名
IMAGE_NAME="wx861"
APP_NAME="wx861"
REDIS_NAME="wx861-redis"
WS_NAME="wx861-ws"
cd "$(dirname "$0")"
mkdir -p conf data ipad861
# 0) 若部署包内带 swagger,拷到宿主以便根路径可打开
if [ -d "wechatReal08/linux部署/linux部署包/home/server/ipad861/wechatReal08/bin/swagger" ]; then
mkdir -p wechatReal08/swagger
cp -rf wechatReal08/linux部署/linux部署包/home/server/ipad861/wechatReal08/bin/swagger/* wechatReal08/swagger/ 2>/dev/null || true
fi
# 1) 写 conf/app.conf(0.0.0.0 + copyrequestbody + redis 指向 docker 内服务名)
if [ ! -f conf/app.conf ]; then
cat > conf/app.conf <<'CONF'
appname = wxapi
httpaddr = "0.0.0.0"
httpport = 8061
runmode = prod
EnableDocs = true
copyrequestbody = true
redislink = redis:6379
redisdbnum = 2
syncmessage = true
msgpush = false
sessionon = true
longlinkenabled = true
longlinkconnecttimeout = "30m"
rabbitmq = false
rabbitmqurl = ""
CONF
else
sed -ri 's@^(httpaddr)\s*=.*@\1 = "0.0.0.0"@i' conf/app.conf || true
grep -qi '^copyrequestbody' conf/app.conf && sed -ri 's/^(copyrequestbody)\s*=.*/\1 = true/i' conf/app.conf || echo 'copyrequestbody = true' >> conf/app.conf
grep -qi '^redislink' conf/app.conf && sed -ri 's@^(redislink)\s*=.*@\1 = redis:6379@i' conf/app.conf || echo 'redislink = redis:6379' >> conf/app.conf
grep -qi '^redisdbnum' conf/app.conf && sed -ri 's/^(redisdbnum)\s*=.*/\1 = 2/i' conf/app.conf || echo 'redisdbnum = 2' >> conf/app.conf
fi
# 2) 协议容器入口:从 /host 装配 -> 等待 redis:6379 -> 启动协议
cat > ipad861/entrypoint.sh <<'SH'
#!/bin/sh
set -e
copy_first_exist() {
dest="$1"; shift
for src in "$@"; do
if [ -f "$src" ] || [ -d "$src" ]; then
if [ -d "$src" ]; then cp -rf "$src" "$dest"; else cp -f "$src" "$dest"; fi
return 0
fi
done
return 1
}
cd /usr/wic-go
mkdir -p /usr/wic-go/lib /usr/local/lib
copy_first_exist ./start.sh /host/wechatReal08/start.sh /host/ipad861/wechatReal08/start.sh
copy_first_exist ./main "/host/wechatReal08/linux部署/linux部署包/home/server/ipad861/wechatReal08/bin/wechat_linux" /host/wechatReal08/bin/wechat_linux
copy_first_exist ./08sae.dat /host/wechatReal08/08sae.dat "/host/wechatReal08/linux部署/linux部署包/home/server/ipad861/wechatReal08/bin/08sae.dat" || true
copy_first_exist ./rqtx.dat /host/wechatReal08/rqtx.dat "/host/wechatReal08/linux部署/linux部署包/home/server/ipad861/wechatReal08/bin/rqtx.dat" || true
copy_first_exist /usr/local/lib/libv08.so /host/wechatReal08/lib/libv08.so "/host/wechatReal08/linux部署/linux部署包/home/server/ipad861/wechatReal08/bin/lib/libv08.so" || true
copy_first_exist /usr/local/lib/libz.so /host/wechatReal08/lib/libz.so "/host/wechatReal08/linux部署/linux部署包/home/server/ipad861/wechatReal08/bin/lib/libz.so" || true
copy_first_exist /usr/local/lib/libz.so.1.3.1 /host/wechatReal08/lib/libz.so.1.3.1 "/host/wechatReal08/linux部署/linux部署包/home/server/ipad861/wechatReal08/bin/lib/libz.so.1.3.1" || true
mkdir -p /usr/wic-go/lib
copy_first_exist /usr/wic-go/lib/key /host/wechatReal08/lib/key "/host/wechatReal08/linux部署/linux部署包/home/server/ipad861/wechatReal08/bin/lib/key" || true
chmod -R 600 /usr/wic-go/lib/key 2>/dev/null || true
if [ ! -d ./swagger ] && [ -d /host/wechatReal08/swagger ]; then
cp -rf /host/wechatReal08/swagger ./swagger
fi
[ -x ./main ] || chmod +x ./main 2>/dev/null || true
[ -x ./start.sh ] || chmod +x ./start.sh 2>/dev/null || true
command -v ldconfig >/dev/null 2>&1 && ldconfig || true
if [ ! -f ./start.sh ] || [ ! -x ./main ]; then
echo "缺少 start.sh 或 wechat_linux(main),请确认 wechatReal08 目录完整"
exit 1
fi
# 等待 docker 内的 redis 服务(服务名: redis)
for i in $(seq 1 60); do
if redis-cli -h redis -p 6379 ping >/dev/null 2>&1; then
break
fi
sleep 0.5
done
redis-cli -h redis -p 6379 ping >/dev/null 2>&1 || { echo "Redis (redis:6379) not ready"; exit 1; }
exec ./start.sh
SH
chmod +x ipad861/entrypoint.sh
# 3) 协议运行镜像(不打业务文件)
cat > ipad861/Dockerfile.runtime <<'EOF'
FROM ubuntu:24.04
ENV DEBIAN_FRONTEND=noninteractive TZ=Asia/Shanghai \
LD_LIBRARY_PATH=/usr/local/lib:/usr/wic-go:$LD_LIBRARY_PATH
RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates tzdata libc6 libstdc++6 redis-tools && \
rm -rf /var/lib/apt/lists/*
WORKDIR /usr/wic-go
COPY ipad861/entrypoint.sh /usr/wic-go/entrypoint.sh
EXPOSE 8061
ENTRYPOINT ["/usr/wic-go/entrypoint.sh"]
EOF
# 4) 写 ws/application.yml(若不存在)保持默认端口 8099
if [ ! -f ws/application.yml ]; then
mkdir -p ws
cat > ws/application.yml <<'YML'
server:
port: 8099
api:
url: http://127.0.0.1:8061
YML
fi
# 5) docker-compose(三服务:redis -> wx861 -> wx861-ws)
cat > docker-compose.yml <<EOF
version: "3.8"
services:
redis:
image: redis:7-alpine
container_name: ${REDIS_NAME}
restart: unless-stopped
command: ["redis-server","--appendonly","yes"]
volumes:
- redis-data:/data
${APP_NAME}:
image: ${IMAGE_NAME}:latest
build:
context: .
dockerfile: ipad861/Dockerfile.runtime
pull_policy: never
container_name: ${APP_NAME}
restart: unless-stopped
depends_on:
- redis
environment:
- TZ=Asia/Shanghai
- LD_LIBRARY_PATH=/usr/local/lib:/usr/wic-go
working_dir: /usr/wic-go
ports:
- "${PORT}:8061"
volumes:
- ./conf:/usr/wic-go/conf:ro
- ./wechatReal08/swagger:/usr/wic-go/swagger:ro
- ./:/host:ro
${WS_NAME}:
image: eclipse-temurin:17-jre
container_name: ${WS_NAME}
depends_on:
- ${APP_NAME}
restart: unless-stopped
working_dir: /app/ws
environment:
- TZ=Asia/Shanghai
- SERVER_PORT=${WSPORT}
- API_URL=http://${APP_NAME}:8061
volumes:
- ./ws:/app/ws:ro
command: >
sh -c "java
-Dserver.port=\${SERVER_PORT}
-Dapi.url=\${API_URL}
-Dspring.config.additional-location=file:/app/ws/application.yml
-jar /app/ws/ipadWs.jar"
ports:
- "${WSPORT}:${WSPORT}"
volumes:
redis-data:
EOF
# 6) 启动
docker compose down --remove-orphans || true
docker compose up -d --build
sleep 1
docker compose ps
docker logs -f "${APP_NAME}" | sed -n '1,160p'
-
kbot-on-wechat/config.json 这样配
-
"wx861_base_url": "http://你的公网IP:8061"
-
"wx861_ws_url": "ws://你的公网IP:8099/ws/{wxid}"
-
说明
-
Redis 在 compose 内服务名为 redis,协议通过 redis:6379 连接(已在 app.conf 固定)。
-
WS 与 HTTP 可同时使用;WS 走 8099,HTTP 走 8061。