This commit is contained in:
V-LiuShuang
2026-08-14 13:52:09 +08:00
commit 609e3bf66e
29 changed files with 3793 additions and 0 deletions
+22
View File
@@ -0,0 +1,22 @@
## docker-compose.yaml
```yaml
version: '3.8'
services:
code-server:
image: linuxserver/code-server:latest
container_name: code-server
environment:
- PUID=1000
- PGID=1001
- TZ=Asia/Shanghai
- PASSWORD=Abc.123
- SUDO_PASSWORD=Abc.123
volumes:
- ./conf:/config
- ./workspace:/projects
ports:
- "48331:8443"
restart: on-failure:3
```
+11
View File
@@ -0,0 +1,11 @@
```
docker run \
-d \
-p 端口号:8080 \
-e APP_NAME=dpanel \
--name dpanel \
--restart=always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v 替换成DPanel的存储目录:/dpanel \
registry.cn-hangzhou.aliyuncs.com/dpanel/dpanel:lite
```
+10
View File
@@ -0,0 +1,10 @@
```
docker run \
-d \
--name grafana-12.1.1 \
-p 宿主机端口号:3000 \
-v 替换成数据存储目录:/var/lib/grafana \
-v 替换成日志存储目录:/var/log/grafana \
-v 替换成插件存储目录:/var/lib/grafana/plugins \
swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/grafana/grafana-oss:12.1.1
```
+168
View File
@@ -0,0 +1,168 @@
## 为什么要写这一篇
因为当时 vLLM 部署的 gpt-oss-120b 的模型,总是造成 vLLM 宕机,分析宕机时的崩溃日志是由于 vLLM 根据模型的回复内容调用结构化输出的工具,然后模型回复的内容跟结构后输出函数不兼容所以抛了 ValueError 导致 vLLM 的引擎进程退出,APIServer 与引擎的进程有心跳机制,发现引擎宕机了,所以自杀了。但是没有请求参数日志,不知道啥样的请求参数触发了结构化输出的功能。在 Open AI API 层面是有校验 response_format 的参数合法性的,不合法会直接拒绝。所以当务之急是先捕获请求参数,结合 vLLM 的宕机时间,尝试复现宕机的参数。
## 踩了很多坑
- 第一反应是看看能不能调整 vLLM 有没有开启打印请求参数的能力,vLLM 的版本是 v0.11.0,查看源码发现是没有的。
- 第二种就是使用抓包工具去实时抓包,选择了 tshark 它是 wireshark 的命令行版本。
- 在服务器后台运行了一晚上,天塌了!这叼东西会一直写临时文件,存储路径:/tmp/*.pcap。
- 它是抓包网卡的流量,在服务器部署了好几个大模型和 OpenAI API 端点。
- 而且有其他同事在压测,一直在并发调用 Open AI API,所以一晚上写了 300G+ 的临时文件,服务器直接告警了,运维挨批了。
## 终极方案
不修改 vLLM 的源码,也不用抓包工具,针对 vLLM 部署的 gpt-oss-120b 的 Open AI API 加一层反向代理,把请求参数写到 access_log 并轮转。
## OpenResty
用这玩意儿是因为它可以在 nginx.conf 里面写 Lua 脚本,还提供了一系列的增强能力,比直接用 nginx 更省心。
### nginx.conf
```
worker_processes auto;
error_log stderr warn;
events {
worker_connections 4096;
use epoll;
multi_accept on;
}
http {
lua_need_request_body on;
log_escape_non_ascii off;
# 注意:这里不再使用 $time_local,而是用自定义变量 $log_time
log_format llm_audit '[$log_time] | $request_uri | $raw_body';
upstream llm_backend {
server 127.0.0.1:8080; # 修改成你的服务地址
keepalive 32;
}
server {
listen 8000;
server_name _;
client_max_body_size 100M;
client_body_buffer_size 128k;
client_body_in_single_buffer on;
location /v1/chat/completions {
set $log_time "";
set $raw_body "";
rewrite_by_lua_block {
local now = ngx.time()
local tm = os.date("*t", now)
ngx.var.log_time = string.format(
"%04d-%02d-%02d %02d:%02d:%02d",
tm.year, tm.month, tm.day,
tm.hour, tm.min, tm.sec
)
local body = ngx.var.request_body or ""
ngx.var.raw_body = body
-- 判断是否为流式请求
if body ~= "" then
local cjson = require "cjson.safe"
local ok, json = pcall(cjson.decode, body)
if ok and type(json) == "table" and json.stream == true then
ngx.exec("@stream")
return
end
end
ngx.exec("@normal")
}
}
# ========== 流式响应 ==========
location @stream {
internal;
access_log /hook/request.log llm_audit;
proxy_pass http://llm_backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_buffering off;
proxy_cache off;
send_timeout 600s;
proxy_connect_timeout 5s;
proxy_send_timeout 60s;
proxy_read_timeout 600s;
proxy_socket_keepalive on;
}
# ========== 非流式响应 ==========
location @normal {
internal;
access_log /hook/request.log llm_audit;
proxy_pass http://llm_backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_buffering on;
proxy_cache off;
send_timeout 600s;
proxy_connect_timeout 5s;
proxy_send_timeout 60s;
proxy_read_timeout 600s;
proxy_socket_keepalive on;
}
}
}
```
### /hook/request.log
```
/hook/request.log {
daily
rotate 5
size 20M
compress
delaycompress
missingok
notifempty
copytruncate
su root root # 如果 nginx 以非 root 用户运行,需匹配权限
}
```
### docker-compose.yml
```yml
version: "3.8"
services:
openresty:
image: docker.1ms.run/openresty/openresty:jammy
container_name: openresty
environment:
- TZ=Asia/Shanghai
- http_proxy=
- https_proxy=
- HTTP_PROXY=
- HTTPS_PROXY=
- no_proxy=
- NO_PROXY=
ports:
- "28000:8000"
volumes:
# 宿主机这个目录可以查看 request.log 也必须包含 nginx.conf
- ./hook:/hook
# 日志轮转配置文件
- ./hook/hook-nginx:/etc/logrotate.d/hook-nginx
command: ["/usr/local/openresty/bin/openresty", "-c", "/hook/nginx.conf", "-g", "daemon off;"]
restart: on-failure:3
```
+153
View File
@@ -0,0 +1,153 @@
## 目录结构
- pgsql-gis/
- docker-compose.yaml
```shell
mkdir pgsql-gis
```
## docker-compose.yaml
```yaml
version: '3.8'
services:
pgsql-gis-16:
# 支持全文检索的自编译镜像
image: pgsql-gis-fts:latest
container_name: pgsql-gis-16
ports:
- "35430:5432" # 替换
volumes:
- ./pgsql-gis:/var/lib/postgresql/data
environment:
POSTGRES_USER: # 替换
POSTGRES_PASSWORD: # 替换
POSTGRES_DB: # 替换
POSTGRES_INITDB_ARGS: --encoding=UTF8
restart: on-failure:3
```
## 添加全文索引支持
需要从 git 克隆 zhparser 添加中文分词支持,执行 docker build 命令的目录结构长这样:
- Dockerfile
- zhparser/
```bash
git clone https://github.com/amutu/zhparser.git
```
## Dockerfile
```bash
FROM swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/postgis/postgis:16-3.5
ENV DEBIAN_FRONTEND=noninteractive
RUN sed -i 's/deb.debian.org/mirrors.ustc.edu.cn/g' /etc/apt/sources.list && \
sed -i 's/security.debian.org/mirrors.ustc.edu.cn/g' /etc/apt/sources.list
RUN apt-get update && apt-get install -y \
build-essential \
git \
libcurl4-openssl-dev \
libxml2-dev \
wget \
postgresql-server-dev-16 \
&& rm -rf /var/lib/apt/lists/*
RUN pg_config --version
WORKDIR /tmp
RUN wget http://www.xunsearch.com/scws/down/scws-1.2.3.tar.bz2 \
&& tar xjf scws-1.2.3.tar.bz2 \
&& cd scws-1.2.3 \
&& ./configure \
&& make && make install \
&& cd ..
COPY zhparser zhparser
RUN cd zhparser \
&& export PG_CONFIG=$(which pg_config) \
&& echo "Using pg_config: $PG_CONFIG" \
&& make USE_PGXS=1 \
&& make USE_PGXS=1 install \
&& cd ..
RUN rm -rf /tmp/*
WORKDIR /
```
## 编译
```bash
docker build -t pgsql-gis-fts .
```
## 启用中文分词扩展
```sql
CREATE EXTENSION IF NOT EXISTS zhparser;
```
```sql
CREATE TEXT SEARCH CONFIGURATION chinese_mix (PARSER = zhparser);
-- DROP TEXT SEARCH CONFIGURATION IF EXISTS chinese_mix;
```
```sql
ALTER TEXT SEARCH CONFIGURATION chinese_mix ADD MAPPING FOR n,v,a,i,e,l,d,j,m,q,r,t,u,w,x,z WITH simple;
```
## 测试
```sql
CREATE TABLE articles (
id SERIAL PRIMARY KEY,
title TEXT,
content TEXT,
-- 生成列:自动维护 tsvector,避免每次查询都计算,提高性能
content_tsvector TSVECTOR GENERATED ALWAYS AS (to_tsvector('chinese_mix', content)) STORED
);
```
```sql
-- 插入一些混合数据
INSERT INTO articles (title, content) VALUES
('AI 技术展望', '人工智能 (AI) 正在改变世界,PostgreSQL 是存储这些数据的首选数据库。'),
('PostgreSQL 16 新特性', 'PostgreSQL 16 带来了更好的性能,支持 JSON 增强和中文分词优化。'),
('日常开发笔记', 'Today I learned about zhparser. 它让中文搜索变得很简单。');
```
```sql
-- 搜索包含 "人工智能" 的文章
SELECT title, content
FROM articles
WHERE content_tsvector @@ to_tsquery('chinese_mix', '人工智能');
```
```sql
-- 搜索包含 "PostgreSQL" 的文章
SELECT title, content
FROM articles
WHERE content_tsvector @@ to_tsquery('chinese_mix', 'PostgreSQL');
```
```sql
-- 搜索既包含 "数据库" 又包含 "PostgreSQL" 的文章
SELECT title, content
FROM articles
WHERE content_tsvector @@ to_tsquery('chinese_mix', '数据库 & PostgreSQL');
```
```sql
-- 搜索包含 "AI" 或者 "改变" 的文章
SELECT title, content
FROM articles
WHERE content_tsvector @@ to_tsquery('chinese_mix', 'AI | 改变');
```
+51
View File
@@ -0,0 +1,51 @@
## 目录结构
- docker-compose.yaml
- redis.conf
- data/
## docker-compose.yaml
```yaml
services:
redis:
image: redis:8.6 # 替换
container_name: redis
ports:
- "52358:6379" # 替换
volumes:
- ./redis.conf:/usr/local/etc/redis/redis.conf
- ./data:/data
command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
restart: on-failure:3
```
## redis.conf
```text
bind 0.0.0.0
port 6379
requirepass 1965589280@Jkw!
protected-mode no
dir /data
save 900 1
save 300 10
save 60 10000
dbfilename dump.rdb
rdbcompression yes
rdbchecksum yes
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
timeout 0
tcp-keepalive 300
loglevel notice
databases 16
daemonize no
supervised no
always-show-logo no
```
File diff suppressed because it is too large Load Diff
+74
View File
@@ -0,0 +1,74 @@
## JDK21
```
FROM docker.1ms.run/eclipse-temurin:21-jdk
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN echo "deb https://mirrors.aliyun.com/debian/ bullseye main contrib non-free" > /etc/apt/sources.list && \
echo "deb https://mirrors.aliyun.com/debian-security/ bullseye-security main contrib non-free" >> /etc/apt/sources.list && \
echo "deb https://mirrors.aliyun.com/debian/ bullseye-updates main contrib non-free" >> /etc/apt/sources.list && \
apt-get update && \
apt-get install -y git maven && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
```
## JDK8
```
FROM docker.1ms.run/maven:3.8.6-jdk-8
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN echo "deb https://mirrors.aliyun.com/debian/ bullseye main contrib non-free" > /etc/apt/sources.list && \
echo "deb https://mirrors.aliyun.com/debian-security/ bullseye-security main contrib non-free" >> /etc/apt/sources.list && \
echo "deb https://mirrors.aliyun.com/debian/ bullseye-updates main contrib non-free" >> /etc/apt/sources.list && \
apt-get update && \
apt-get install -y git && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
```
## 使用本地 JDK 与 Maven 构建
要先下载 OpenJDK 和 Maven,与 Dockerfile 同级目录,分别命名为 jdk-21 和 mvn-3,目录结构:
- Dockerfile
- jdk-21/
- mvn-3/
```shell
FROM ubuntu:22.04
ENV DEBIAN_FRONTEND=noninteractive \
TZ=Asia/Shanghai
RUN apt-get update && \
apt-get install -y --no-install-recommends \
locales \
tzdata \
ca-certificates \
git && \
rm -rf /var/lib/apt/lists/*
RUN locale-gen zh_CN.UTF-8 en_US.UTF-8
ENV LANG=zh_CN.UTF-8 \
LANGUAGE=zh_CN:zh \
LC_ALL=zh_CN.UTF-8
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
dpkg-reconfigure -f noninteractive tzdata
WORKDIR /opt
COPY jdk-21 jdk21
COPY mvn-3 mvn
ENV JAVA_HOME=/opt/jdk21 \
MAVEN_HOME=/opt/mvn \
PATH="/opt/jdk21/bin:/opt/mvn/bin:${PATH}"
```
执行命令开始构建
```shell
docker build -t ubuntu-jdk-21 .
```
+19
View File
@@ -0,0 +1,19 @@
```
FROM docker.1ms.run/library/mvn-java-8:latest
ENV PROJECT_ACTIVE=根据实际情况激活 application-xxx.yaml 配置文件,比如:prod
WORKDIR /app
EXPOSE springboot 内嵌的 servlet 容器端口号
# 配置容器启动命令
RUN << 'EOF' cat > /entrypoint.sh
#!/bin/bash
set -e
cd /app && rm -rf 源码目录
git clone "http://用户名:密码@远程仓库地址.git"
cd /app/源码目录 && mvn clean package
exec java -jar target/jar包名称.jar --spring.profiles.active=$PROJECT_ACTIVE
EOF
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
```
+19
View File
@@ -0,0 +1,19 @@
```
FROM docker.1ms.run/library/mvn-java-21:latest
ENV PROJECT_ACTIVE=根据实际情况激活 application-xxx.yaml 配置文件,比如:prod
WORKDIR /app
EXPOSE springboot 内嵌的 servlet 容器端口号
# 配置容器启动命令
RUN << 'EOF' cat > /entrypoint.sh
#!/bin/bash
set -e
cd /app && rm -rf 源码目录
git clone "http://用户名:密码@远程仓库地址.git"
cd /app/源码目录 && mvn clean package
exec java -jar target/jar包名称.jar --spring.profiles.active=$PROJECT_ACTIVE
EOF
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
```
+5
View File
@@ -0,0 +1,5 @@
```
FROM docker.1ms.run/node:16-alpine
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
RUN apk add --no-cache git nginx
```
+114
View File
@@ -0,0 +1,114 @@
# 前提条件
- 系统:Ubuntu 22.04
- 架构:x86_x64
## 安装必要工具
```bash
sudo apt update && sudo apt install -y ca-certificates curl gnupg lsb-release
```
## 添加 Docker 的官方 GPG 密钥
先检查是否包含相关目录
```bash
ls /etc/apt/keyrings
```
如果没有则创建
```bash
sudo install -m 0755 -d /etc/apt/keyrings
```
下载并保存
```bash
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
```
## 设置 Docker 仓库
```bash
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
```
## 更新并安装
```bash
sudo apt update
```
```bash
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
```
```bash
docker -v
```
## 配置 Docker 代理服务(可选)
```bash
sudo mkdir -p /etc/systemd/system/docker.service.d
```
```bash
sudo nano /etc/systemd/system/docker.service.d/http-proxy.conf
```
```
[Service]
Environment="HTTP_PROXY=http://192.168.31.9:7890"
Environment="HTTPS_PROXY=http://192.168.31.9:7890"
Environment="NO_PROXY=localhost,127.0.0.1,::1,docker-registry.somecorporation.com"
```
```bash
sudo systemctl daemon-reload
```
```bash
sudo systemctl restart docker
```
验证代理配置是否生效
```bash
sudo systemctl show --property=Environment docker
```
## 配置 NVIDIA 容器环境(可选)
添加 NVIDIA 包仓库
```bash
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit.gpg
```
```bash
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit.gpg] https://#g' | sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
```
```bash
sudo apt update
```
安装 NVIDIA 容器工具包
```bash
sudo apt install -y nvidia-container-toolkit
```
配置 NVIDIA 运行时
```bash
sudo nvidia-ctk runtime configure --runtime=docker
```
```bash
sudo systemctl restart docker
```
测试是否能识别
```bash
docker run --rm --gpus all nvidia/cuda:12.4.1-base-ubuntu22.04 nvidia-smi
```
+18
View File
@@ -0,0 +1,18 @@
## Ubuntu 24.04
```bash
# 备份原文件(可选)
sudo cp /etc/apt/sources.list.d/ubuntu.sources /etc/apt/sources.list.d/ubuntu.sources.bak
```
```bash
sudo sed -i 's|http://archive.ubuntu.com|http://mirrors.ustc.edu.cn|g' /etc/apt/sources.list.d/ubuntu.sources
```
```bash
sudo sed -i 's|http://security.ubuntu.com|http://mirrors.ustc.edu.cn|g' /etc/apt/sources.list.d/ubuntu.sources
```
```bash
sudo apt update
```
+11
View File
@@ -0,0 +1,11 @@
# 安装相关工具
```bash
sudo apt update && sudo apt install -y pciutils util-linux
```
# 打印系统详情
```bash
echo "=== 系统核心信息 ===" && lsb_release -a && echo -e "\n=== 内核版本 ===" && uname -r && echo -e "\n=== 硬件架构 ===" && uname -m && echo -e "\n=== CPU 信息 ===" && lscpu | grep -E "架构|CPU:|型号名称" && echo -e "\n=== 内存使用情况 ===" && free -h && echo -e "\n=== 磁盘空间 (根分区) ===" && df -h / && echo -e "\n=== 显卡信息 ===" && lspci -k | grep -A 2 -i vga && echo -e "\n=== 当前运行内核引导参数 ===" && cat /proc/cmdline
```
+44
View File
@@ -0,0 +1,44 @@
## 用户级别
```bash
nano ~/.bashrc
```
```
# Proxy Configuration
export HTTP_PROXY="http://192.168.31.9:7890"
export HTTPS_PROXY="http://192.168.31.9:7890"
export http_proxy="http://192.168.31.9:7890"
export https_proxy="http://192.168.31.9:7890"
# 可选:设置不走代理的地址 (本地地址和内部域名)
export NO_PROXY="localhost,127.0.0.1,::1,192.168.*,10.*"
export no_proxy="localhost,127.0.0.1,::1,192.168.*,10.*"
```
保存并退出(`Ctrl + O` `Enter` `Ctrl + X`
```bash
source ~/.bashrc
```
## 对所有用户生效(需重启系统)
```bash
sudo nano /etc/environment
```
```
HTTP_PROXY="http://192.168.31.9:7890"
HTTPS_PROXY="http://192.168.31.9:7890"
http_proxy="http://192.168.31.9:7890"
https_proxy="http://192.168.31.9:7890"
NO_PROXY="localhost,127.0.0.1,::1"
no_proxy="localhost,127.0.0.1,::1"
```
保存并退出(`Ctrl + O` `Enter` `Ctrl + X`
```bash
sudo reboot
```
+136
View File
@@ -0,0 +1,136 @@
# 文档
- 原作者:https://ehang-io.github.io/nps
- 维护者:https://my.feishu.cn/wiki/FmVVwDcEGiTZxekYJl5ccuFanlg
- Githubhttps://github.com/yisier/nps/releases
## 服务端
下载`linux_amd64_server.tar.gz`压缩包并解压,然后执行`sudo ./nps install`安装。修改配置文件:
```
nano /etc/nps/conf/nps.conf
```
```
# 自定义,英文+数字,不超过16位
public_vkey=
# 自定义,英文+数字,不超过16位
auth_key=
# 自定义,英文+数字,固定16位
auth_crypt_key=
# 网页端管理员用户名
web_username=admin
# 网页端管理员账号的密码,英文+数字+特殊符号(.@!)
web_password=
appname = nps
#Boot mode(dev|pro)
runmode = pro
#HTTP(S) proxy port, no startup if empty
http_proxy_ip=0.0.0.0
http_proxy_port=26666
https_proxy_port=36666
https_just_proxy=true
#default https certificate setting
https_default_cert_file=conf/server.pem
https_default_key_file=conf/server.key
##bridge
bridge_type=tcp
bridge_port=28888
bridge_ip=0.0.0.0
#Traffic data persistence interval(minute)
#Ignorance means no persistence
flow_store_interval=1
# log level LevelEmergency->0 LevelAlert->1 LevelCritical->2 LevelError->3 LevelWarning->4 LevelNotice->5 LevelInformational->6 LevelDebug->7
log_level=6
log_path=nps.log
#p2p
#p2p_ip=127.0.0.1
#p2p_port=6000
#web
web_host=a.o.com
web_port = 38888
web_ip=0.0.0.0
web_base_url=
web_open_ssl=false
web_cert_file=conf/server.pem
web_key_file=conf/server.key
# if web under proxy use sub path. like http://host/nps need this.
#web_base_url=/nps
#allow_ports=9001-9009,10001,11000-12000
#Web management multi-user login
allow_user_login=false
allow_user_register=false
allow_user_change_username=false
#extension
#流量限制
allow_flow_limit=true
#带宽限制
allow_rate_limit=true
#客户端最大隧道数限制
allow_tunnel_num_limit=true
allow_local_proxy=false
#客户端最大连接数
allow_connection_num_limit=true
#每个隧道监听不同的服务端端口
allow_multi_ip=true
system_info_display=true
#获取用户真实ip
http_add_origin_header=true
#cache
http_cache=false
http_cache_length=10
#get origin ip
#http_add_origin_header=false
#pprof debug options
#pprof_ip=0.0.0.0
#pprof_port=9999
#client disconnect timeout
disconnect_timeout=60
#管理面板开启验证码校验
open_captcha=false
# 是否开启tls
tls_enable=true
tls_bridge_port=48888
```
修改完成后,执行`sudo nps start`启动服务端。
| 端口号 | 用途 |
|:-----|:-----|
| 26666 | http代理端口 |
| 36666 | https代理端口 |
| 28888 | TCP隧道端口 |
| 38888 | WebUI的端口 |
| 48888 | TCP隧道 TLS 端口 |
## 客户端
下载`linux_amd64_client.tar.gz`压缩包并解压
```
# 安装
sudo ./npc install -server=服务端IP:28888 -vkey=<vkey>
# 启动
sudo npc start
# 停止
sudo npc stop
```
+13
View File
@@ -0,0 +1,13 @@
## 关键字搜索并排序
```bash
grep -h '关键字' *.log | sort
```
## 打印一个时间范围的片段
按分钟级匹配,按秒的话结束时间不存在日志,会导致一直输出到文件末尾
```bash
sed -n '/2026-03-26 10:15/, /2026-03-26 10:20/p' xxx.log
```
@@ -0,0 +1,87 @@
# Intro
本文介绍如何把 NAS 主机目录挂载到 Linux 主机,并通过 Volume 挂载到 Docker 容器,借助 NAS 的阵列盘实现高可靠数据存储。
- NAS"/vol1/workspace"
- Linux"/mnt/nas/vol1/workspace"
- Docker"/workspace"
假设 NAS 的用户名密码是"admin/123456"IP为"192.168.1.100",目录映射目标:"/vol1/workspace" -> "/mnt/nas/vol1/workspace" -> "/workspace"。
## 基于 NFS 协议挂载
1. 在 Linux 安装相关工具
Debian/Ubuntu
```bash
sudo apt update && sudo apt install nfs-common -y
```
CentOS/RHEL
```bash
sudo yum install nfs-utils
```
2. 创建目录
NAS
```bash
sudo /vol1/workspace
```
Linux
```bash
sudo mkdir -p /mnt/nas/vol1/workspace
```
3. 授权(UID=1000GID=1000
NAS
```bash
sudo chown -R 1000:1000 /vol1/workspace
```
Linux
```bash
sudo chown -R 1000:1000 /mnt/nas/vol1/workspace
```
4. 在 Linux 执行挂载
```bash
sudo mount -t nfs -o rw,vers=4.2,noatime,rsize=1048576,wsize=1048576,timeo=1200,retrans=2,_netdev 192.168.1.100:/vol1/workspace /mnt/nas/vol1/workspace
```
| 参数名称 | 说明 |
| --- | --- |
| rw | 拥有读写权限 |
| vers | 使用 nfs 4.2 版本 |
| noatime | 不更新文件的访问时间戳,能显著减少磁盘 I/O 和网络开销,提升性能 |
| rsize/wsize | 读写块大小,1MB 是 NFS v4.2 推荐的尺寸,适合高速内网传输文件,有效利用网络带宽 |
| timeo | 客户端等待重传前的超时时间,给网络波动留的容忍度,单位是厘秒,1200=120秒 |
| retrans | 连接彻底失败之前,仅重传 2 次。配合长超时,客户端会很有耐心地等待,不会因短暂网络抖动而频繁报错|
| _netdev | 告诉系统等网络可用后再挂载,防止在启动初期,网络未就绪时挂载失败 |
5. 在 Linux 设置开机自动挂载(可选但强烈推荐)
```bash
sudo nano /etc/fstab
```
在文件末尾追加一行:
```text
192.168.1.100:/vol1/workspace /mnt/nas/vol1/workspace nfs rw,vers=4.2,noatime,rsize=1048576,wsize=1048576,timeo=1200,retrans=2,_netdev 0 0
```
6. 在 Linux 运行 Docker 容器并挂载
```bash
docker run -v /mnt/nas/vol1/workspace:/workspace --user 1000:1000 <镜像名>
```
+39
View File
@@ -0,0 +1,39 @@
# 客户端下载
| 系统 | 点击下载 |
|:-----|:-----|
| Windows |[x86](https://stf.jkwlstv.cn/app/cfw_x86.exe) [Arm](https://stf.jkwlstv.cn/app/cfw_arm.exe)|
| Mac |[Intel](https://stf.jkwlstv.cn/app/cfm_intel.dmg) [Arm](https://stf.jkwlstv.cn/app/cfm_arm.dmg)|
| Android |[通用](https://stf.jkwlstv.cn/app/cmfa.apk)|
## Android
<div style="display: flex; flex-wrap: wrap; gap: 10px;">
<img src="./img/cfa-1.png" width="48%">
<img src="./img/cfa-2.png" width="48%">
<img src="./img/cfa-3.png" width="48%">
<img src="./img/cfa-4.png" width="48%">
<img src="./img/cfa-5.png" width="48%">
</div>
## iOS
需要切换到美区 App Store 下载安装 **Potatso** 这款 APP,所以需要先注册一个美区的 Apple ID。
- 注册美区 Apple ID 教程:https://clashxpro.net/apple-id
- APP下载链接:https://apps.apple.com/us/app/potatso/id1239860606
- 使用教程:https://potatso.net **订阅链接见公告**
Potatso 是**免费**的,不差钱可以用 Shadowrocket。
## Mac/Win
### 添加订阅
<img src="./img/clash-pc-1.png" width="70%">
<img src="./img/clash-pc-2.png" width="70%">
### 配置文件链接见公告
<img src="./img/clash-pc-3.png" width="70%">
### 开启局域网代理(可选)
<img src="./img/clash-pc-4.png" width="70%">
<img src="./img/clash-pc-5.png" width="70%">
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 166 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 193 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 KiB