初版功能完成
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
REMLINK_WG_ENDPOINT=vpn.example.com:51820
|
||||
REMLINK_WG_PORT=51820
|
||||
REMLINK_HTTP_BIND=127.0.0.1
|
||||
REMLINK_ADMIN_TOKEN=replace-with-a-long-random-value
|
||||
REMLINK_APT_FORCE_IPV4=1
|
||||
REMLINK_APT_DEBIAN_MIRROR=http://mirrors.tuna.tsinghua.edu.cn/debian
|
||||
REMLINK_APT_SECURITY_MIRROR=http://mirrors.tuna.tsinghua.edu.cn/debian-security
|
||||
@@ -0,0 +1,7 @@
|
||||
REMLINK_WG_ENDPOINT=vpn.example.com:51820
|
||||
REMLINK_WG_PORT=51820
|
||||
REMLINK_HTTP_BIND=127.0.0.1
|
||||
REMLINK_ADMIN_TOKEN=replace-with-a-long-random-value
|
||||
REMLINK_APT_FORCE_IPV4=1
|
||||
REMLINK_APT_DEBIAN_MIRROR=
|
||||
REMLINK_APT_SECURITY_MIRROR=
|
||||
@@ -0,0 +1,47 @@
|
||||
# syntax=docker/dockerfile:1.7
|
||||
FROM node:24.14.0-bookworm-slim AS frontend
|
||||
WORKDIR /src
|
||||
COPY frontend/package.json frontend/package-lock.json ./frontend/
|
||||
RUN npm ci --prefix frontend
|
||||
COPY frontend ./frontend
|
||||
RUN npm run typecheck --prefix frontend && npm run build --prefix frontend
|
||||
|
||||
FROM golang:1.26.7-bookworm AS builder
|
||||
WORKDIR /src
|
||||
COPY go.mod go.sum ./
|
||||
RUN go mod download
|
||||
COPY . .
|
||||
COPY --from=frontend /src/frontend/engineer/dist ./frontend/engineer/dist
|
||||
COPY --from=frontend /src/frontend/server/dist ./frontend/server/dist
|
||||
ARG REMLINK_VERSION=1.0.0
|
||||
ARG REMLINK_COMMIT=container
|
||||
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -trimpath \
|
||||
-ldflags "-s -w -X remlink/internal/version.Version=${REMLINK_VERSION} -X remlink/internal/version.Commit=${REMLINK_COMMIT}" \
|
||||
-o /out/remlink-server ./cmd/server
|
||||
|
||||
FROM debian:bookworm-slim
|
||||
ARG APT_FORCE_IPV4=1
|
||||
ARG APT_DEBIAN_MIRROR=
|
||||
ARG APT_SECURITY_MIRROR=
|
||||
RUN apt_options="-o Acquire::Retries=5 -o Acquire::http::Timeout=30 -o Acquire::https::Timeout=30"; \
|
||||
if [ -n "$APT_SECURITY_MIRROR" ]; then sed -i "s|http://deb.debian.org/debian-security|$APT_SECURITY_MIRROR|g" /etc/apt/sources.list.d/debian.sources; fi; \
|
||||
if [ -n "$APT_DEBIAN_MIRROR" ]; then sed -i "s|http://deb.debian.org/debian|$APT_DEBIAN_MIRROR|g" /etc/apt/sources.list.d/debian.sources; fi; \
|
||||
if [ -n "$APT_DEBIAN_MIRROR" ] || [ -n "$APT_SECURITY_MIRROR" ]; then \
|
||||
apt_options="$apt_options -o Acquire::http::Pipeline-Depth=0"; \
|
||||
fi; \
|
||||
if [ "$APT_FORCE_IPV4" = "1" ]; then apt_options="$apt_options -o Acquire::ForceIPv4=true"; fi; \
|
||||
apt-get $apt_options update \
|
||||
&& apt-get $apt_options install -y --no-install-recommends \
|
||||
ca-certificates curl iproute2 iptables wireguard-tools \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
COPY --from=builder /out/remlink-server /usr/local/bin/remlink-server
|
||||
COPY deploy/docker/preflight.sh /usr/local/bin/remlink-preflight
|
||||
COPY THIRD_PARTY_NOTICES.md /usr/share/doc/remlink/THIRD_PARTY_NOTICES.md
|
||||
RUN chmod 0755 /usr/local/bin/remlink-server /usr/local/bin/remlink-preflight \
|
||||
&& mkdir -p /app/data
|
||||
VOLUME ["/app/data"]
|
||||
EXPOSE 8080/tcp 51820/udp
|
||||
HEALTHCHECK --interval=15s --timeout=3s --start-period=10s --retries=4 \
|
||||
CMD curl --fail --silent --show-error http://127.0.0.1:8080/api/v1/server/info >/dev/null || exit 1
|
||||
ENTRYPOINT ["/usr/local/bin/remlink-preflight"]
|
||||
CMD ["/usr/local/bin/remlink-server", "-config", "/etc/remlink/server.yaml"]
|
||||
@@ -0,0 +1,31 @@
|
||||
# syntax=docker/dockerfile:1.7
|
||||
FROM debian:bookworm-slim
|
||||
|
||||
ARG APT_FORCE_IPV4=1
|
||||
ARG APT_DEBIAN_MIRROR=
|
||||
ARG APT_SECURITY_MIRROR=
|
||||
RUN apt_options="-o Acquire::Retries=5 -o Acquire::http::Timeout=30 -o Acquire::https::Timeout=30"; \
|
||||
if [ -n "$APT_SECURITY_MIRROR" ]; then sed -i "s|http://deb.debian.org/debian-security|$APT_SECURITY_MIRROR|g" /etc/apt/sources.list.d/debian.sources; fi; \
|
||||
if [ -n "$APT_DEBIAN_MIRROR" ]; then sed -i "s|http://deb.debian.org/debian|$APT_DEBIAN_MIRROR|g" /etc/apt/sources.list.d/debian.sources; fi; \
|
||||
if [ -n "$APT_DEBIAN_MIRROR" ] || [ -n "$APT_SECURITY_MIRROR" ]; then \
|
||||
apt_options="$apt_options -o Acquire::http::Pipeline-Depth=0"; \
|
||||
fi; \
|
||||
if [ "$APT_FORCE_IPV4" = "1" ]; then apt_options="$apt_options -o Acquire::ForceIPv4=true"; fi; \
|
||||
apt-get $apt_options update \
|
||||
&& apt-get $apt_options install -y --no-install-recommends \
|
||||
ca-certificates curl iproute2 iptables wireguard-tools \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
COPY linux-amd64/remlink-server /usr/local/bin/remlink-server
|
||||
COPY docker/preflight.sh /usr/local/bin/remlink-preflight
|
||||
COPY linux-amd64/THIRD_PARTY_NOTICES.md /usr/share/doc/remlink/THIRD_PARTY_NOTICES.md
|
||||
|
||||
RUN chmod 0755 /usr/local/bin/remlink-server /usr/local/bin/remlink-preflight \
|
||||
&& mkdir -p /app/data
|
||||
|
||||
VOLUME ["/app/data"]
|
||||
EXPOSE 8080/tcp 51820/udp
|
||||
HEALTHCHECK --interval=15s --timeout=3s --start-period=10s --retries=4 \
|
||||
CMD curl --fail --silent --show-error http://127.0.0.1:8080/api/v1/server/info >/dev/null || exit 1
|
||||
ENTRYPOINT ["/usr/local/bin/remlink-preflight"]
|
||||
CMD ["/usr/local/bin/remlink-server", "-config", "/etc/remlink/server.yaml"]
|
||||
@@ -0,0 +1,43 @@
|
||||
# Server Docker 部署
|
||||
|
||||
完整生产流程见 `docs/deployment-and-usage.md`;在源码仓库中该文件位于 `../../docs/deployment-and-usage.md`,在发布包中位于 `../docs/deployment-and-usage.md`。
|
||||
|
||||
Compose 基线删除全部 Linux capability 后只增加 `NET_ADMIN`,映射 `/dev/net/tun`,从不启用 privileged。入口预检会在启动 Server 前检查 TUN、内核 WireGuard、capability 和 IPv4 forwarding。
|
||||
|
||||
## 从发布包部署
|
||||
|
||||
在解压后的 `RemLink-Server-v1.0.0-linux-amd64/docker` 目录:
|
||||
|
||||
~~~bash
|
||||
cp .env.example .env
|
||||
chmod 600 .env
|
||||
# 编辑 .env 与 server.yaml
|
||||
mkdir -p data
|
||||
docker compose --env-file .env -f compose.release.yaml config --quiet
|
||||
docker compose --env-file .env -f compose.release.yaml up --build -d
|
||||
docker compose --env-file .env -f compose.release.yaml exec server remlink-server -config /etc/remlink/server.yaml -print-join-token
|
||||
~~~
|
||||
|
||||
`compose.release.yaml` 使用发布包中的 `linux-amd64/remlink-server`,不会要求完整源码。
|
||||
|
||||
中国大陆网络建议改为 `cp .env.china.example .env`。该模板把 Debian 主仓库和安全仓库切换到清华 TUNA,同时强制 IPv4、关闭 apt HTTP pipelining,并保留超时/重试。Debian 12 容器使用 `/etc/apt/sources.list.d/debian.sources` 的 DEB822 格式,Dockerfile 会通过构建参数替换其中 URI。TUNA 也提示安全镜像可能有同步延迟;网络允许时可把 `REMLINK_APT_SECURITY_MIRROR` 留空以继续使用 Debian 官方安全源。详情见 [TUNA Debian 帮助](https://mirrors.tuna.tsinghua.edu.cn/help/debian/) 和 [TUNA Debian Security 帮助](https://mirrors.tuna.tsinghua.edu.cn/help/debian-security/)。
|
||||
|
||||
## 从源码仓库构建
|
||||
|
||||
在仓库 `deploy/docker` 目录:
|
||||
|
||||
~~~bash
|
||||
cp .env.example .env
|
||||
chmod 600 .env
|
||||
docker compose --env-file .env -f compose.yaml up --build -d
|
||||
~~~
|
||||
|
||||
源码 Compose 会构建前端和 Go Server。
|
||||
|
||||
若构建停在 Debian `apt-get`,先用 `docker run --rm debian:bookworm-slim sh -c "apt-get -o Acquire::ForceIPv4=true -o Acquire::Retries=2 -o Acquire::http::Timeout=30 update"` 验证容器网络。Dockerfile 默认强制 IPv4,并为 apt 配置 30 秒超时和 5 次重试;确认环境只有 IPv6 时才把 `REMLINK_APT_FORCE_IPV4` 改为 `0`。中国大陆环境优先使用 `.env.china.example`;测试命令仍超时时,应修复 Docker daemon 的 DNS/代理或在 Ubuntu 上用 `docker build --network=host`,而不是扩大容器权限。
|
||||
|
||||
只映射 `8080/tcp` 和配置的 WireGuard UDP 端口。Control `7001/tcp` 与 Session `6200/udp` 只绑定 Overlay,不发布。数据库、密钥和日志写入 `/app/data`,由宿主机 `./data` 持久化。
|
||||
|
||||
v1.0 的 `8080/tcp` 不内置 TLS。将 `REMLINK_HTTP_BIND` 设为 `127.0.0.1` 并使用外部 HTTPS 反向代理,或绑定到可信管理接口;不要把未加密 Bootstrap/Admin 直接暴露到 Internet。
|
||||
|
||||
管理页修改 WireGuard 端口后,必须同步更新 `REMLINK_WG_PORT` 和 `REMLINK_WG_ENDPOINT`,再强制重建服务,使宿主机与容器映射跟随数据库中的新端口。`./data` 不会因容器重建丢失。
|
||||
@@ -0,0 +1,30 @@
|
||||
services:
|
||||
server:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: docker/Dockerfile.release
|
||||
args:
|
||||
APT_FORCE_IPV4: "${REMLINK_APT_FORCE_IPV4:-1}"
|
||||
APT_DEBIAN_MIRROR: "${REMLINK_APT_DEBIAN_MIRROR:-}"
|
||||
APT_SECURITY_MIRROR: "${REMLINK_APT_SECURITY_MIRROR:-}"
|
||||
image: remlink/server:1.0.0
|
||||
restart: unless-stopped
|
||||
cap_drop:
|
||||
- ALL
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
devices:
|
||||
- /dev/net/tun:/dev/net/tun
|
||||
sysctls:
|
||||
net.ipv4.ip_forward: "1"
|
||||
ports:
|
||||
- "${REMLINK_HTTP_BIND:-0.0.0.0}:8080:8080/tcp"
|
||||
- "${REMLINK_WG_PORT:-51820}:${REMLINK_WG_PORT:-51820}/udp"
|
||||
environment:
|
||||
REMLINK_WG_ENDPOINT: ${REMLINK_WG_ENDPOINT:?set REMLINK_WG_ENDPOINT to the public host and published UDP port}
|
||||
REMLINK_ADMIN_TOKEN: ${REMLINK_ADMIN_TOKEN:-}
|
||||
volumes:
|
||||
- ./server.yaml:/etc/remlink/server.yaml:ro
|
||||
- ./data:/app/data
|
||||
@@ -0,0 +1,31 @@
|
||||
services:
|
||||
server:
|
||||
build:
|
||||
context: ../..
|
||||
dockerfile: deploy/docker/Dockerfile
|
||||
args:
|
||||
REMLINK_VERSION: "1.0.0"
|
||||
APT_FORCE_IPV4: "${REMLINK_APT_FORCE_IPV4:-1}"
|
||||
APT_DEBIAN_MIRROR: "${REMLINK_APT_DEBIAN_MIRROR:-}"
|
||||
APT_SECURITY_MIRROR: "${REMLINK_APT_SECURITY_MIRROR:-}"
|
||||
image: remlink/server:1.0.0
|
||||
restart: unless-stopped
|
||||
cap_drop:
|
||||
- ALL
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
devices:
|
||||
- /dev/net/tun:/dev/net/tun
|
||||
sysctls:
|
||||
net.ipv4.ip_forward: "1"
|
||||
ports:
|
||||
- "${REMLINK_HTTP_BIND:-0.0.0.0}:8080:8080/tcp"
|
||||
- "${REMLINK_WG_PORT:-51820}:${REMLINK_WG_PORT:-51820}/udp"
|
||||
environment:
|
||||
REMLINK_WG_ENDPOINT: ${REMLINK_WG_ENDPOINT:?set REMLINK_WG_ENDPOINT to the public host and published UDP port}
|
||||
REMLINK_ADMIN_TOKEN: ${REMLINK_ADMIN_TOKEN:-}
|
||||
volumes:
|
||||
- ./server.yaml:/etc/remlink/server.yaml:ro
|
||||
- ./data:/app/data
|
||||
@@ -0,0 +1,32 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
if [ ! -c /dev/net/tun ]; then
|
||||
echo "RemLink preflight: /dev/net/tun is missing; map the TUN device into the container" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
probe_interface="rl-wg-probe"
|
||||
cleanup() {
|
||||
ip link delete dev "$probe_interface" >/dev/null 2>&1 || true
|
||||
}
|
||||
trap cleanup EXIT INT TERM
|
||||
|
||||
if probe_error="$(ip link add dev "$probe_interface" type wireguard 2>&1)"; then
|
||||
:
|
||||
else
|
||||
echo "RemLink preflight: kernel WireGuard or CAP_NET_ADMIN is unavailable" >&2
|
||||
if [ -n "$probe_error" ]; then
|
||||
echo "RemLink preflight: ip link error: $probe_error" >&2
|
||||
fi
|
||||
exit 1
|
||||
fi
|
||||
cleanup
|
||||
trap - EXIT INT TERM
|
||||
|
||||
if [ "$(cat /proc/sys/net/ipv4/ip_forward)" != "1" ]; then
|
||||
echo "RemLink preflight: net.ipv4.ip_forward must be 1" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exec "$@"
|
||||
@@ -0,0 +1,13 @@
|
||||
server:
|
||||
http_listen: "0.0.0.0:8080"
|
||||
control_listen: "10.88.0.1:7001"
|
||||
wireguard_port: 51820
|
||||
|
||||
data:
|
||||
directory: "/app/data"
|
||||
|
||||
network:
|
||||
overlay_cidr: "10.88.0.0/16"
|
||||
server_overlay_ip: "10.88.0.1"
|
||||
session_udp_port: 6200
|
||||
mtu: 1280
|
||||
Reference in New Issue
Block a user