Beiyuan

A place where I share the things I want to share

个人管理大模型API工具UNI-API部署

Github 面板 配置生成 1 2 3 mkdir -p /opt/uniapi && cd /opt/uniapi nano api.yaml nano docker-compose.yaml 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 services: #主程序 uniapi: image: yym68686/uni-api:latest restart: unless-stopped ports: - "8001:8000" volumes: - ./api.yaml:/home/api.yaml - ./data:/home/data #面板服务 uniapi-frontend: image: ghcr.io/melosbot/uni-api-status:latest restart: unless-stopped ports: - "3000:3000" environment: - NODE_ENV=production - PORT=3000 # 以下为容器内的路径,与 volumes 挂载点对应 - API_YAML_PATH=/app/config/api.yaml - STATS_DB_PATH=/app/data/stats.db volumes: # 将宿主机的 api.yaml 挂载到容器内,需要【读写】权限 - ./api.yaml:/app/config/api.yaml # 将宿主机包含 stats.db 的目录挂载到容器内,建议只读【:ro】 - ./data:/app/data:ro 1 docker compose up -d 最小可启动配置模板 1 2 3 4 5 6 7 8 providers: - provider: provider_name # 服务提供商名称, 如 openai、anthropic、gemini、openrouter,随便取名字,必填 base_url: https://api.your.com/v1/chat/completions # 后端服务的API地址,必填 api: sk-YgS6GTi0b4bEabc4C # 提供商的API Key,必填,自动使用 base_url 和 api 通过 /v1/models 端点获取可用的所有模型。 # 这里可以配置多个提供商,每个提供商可以配置多个 API Key,每个提供商可以配置多个模型。 api_keys: - api: sk-Pkj60Yf8JFWxfgRmXQFWyGtWUddGZnmi3KlvowmRWpWpQxx # API Key,用户请求 uni-api 需要 API key,必填 # 该 API Key 可以使用所有模型,即可以使用 providers 下面设置的所有渠道里面的所有模型,不需要一个个添加可用渠道。

七月 6, 2025 · 1 分钟 · 409 字 · Beiyuan

Docker部署Openwebui加Ollama

Github Github 1 2 mkdir /opt/openwebui && cd /opt/openwebui nano docker-compose.yaml 单独安装 1 2 3 4 5 6 7 8 services: openwebui: image: ghcr.io/open-webui/open-webui:main ports: - "8080:8080" volumes: - ./data/open-webui:/app/backend/data restart: unless-stopped 搭配Ollama 这里同时安装了Ollama和Openwebui这样Openwebui能自动识别出来Ollama,直接使用即可 ...

六月 13, 2025 · 1 分钟 · 157 字 · Beiyuan

Linux安装qBittorrent-Enhanced-Edition

Github 下载可执行文件 1 2 3 4 5 6 7 8 9 10 11 12 #x86_64 download_url=$(curl -s https://api.github.com/repos/c0re100/qBittorrent-Enhanced-Edition/releases/latest | jq -r '.assets[] | select(.name | test("qbittorrent-enhanced-nox_x86_64-linux-musl_static.zip")) | .browser_download_url') && \ curl -L $download_url -o /usr/bin/qbittorrent-nox.zip && \ unzip /usr/bin/qbittorrent-nox.zip -d /usr/bin/ && \ chmod +x /usr/bin/qbittorrent-nox && \ rm /usr/bin/qbittorrent-nox.zip #arm64 download_url=$(curl -s https://api.github.com/repos/c0re100/qBittorrent-Enhanced-Edition/releases/latest | jq -r '.assets[] | select(.name | test("qbittorrent-enhanced-nox_aarch64-linux-musl_static.zip")) | .browser_download_url') && \ curl -L "$download_url" -o /usr/bin/qbittorrent-nox.zip && \ unzip /usr/bin/qbittorrent-nox.zip -d /usr/bin/ && \ chmod +x /usr/bin/qbittorrent-nox && \ rm /usr/bin/qbittorrent-nox.zip 创建system服务 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 cat > /etc/systemd/system/qbittorrent.service <<EOF [Unit] Description=qBittorrent Daemon Service After=network-online.target [Service] Type=simple User=root Group=root UMask=007 ExecStart=/usr/bin/qbittorrent-nox ExecStop=/bin/kill -s SIGTERM $MAINPID Restart=on-failure [Install] WantedBy=multi-user.target EOF 启动 1 2 3 systemctl enable qbittorrent systemctl start qbittorrent systemctl status qbittorrent # 查看登录密码,默认登录端口8080 下载完后上传网盘 1 2 3 4 #创建日志文件夹 mkdir -p /root/rclone_logs #下载完成后执行命令,bt:/bt自行修改为你设置rclone remote名和上传到网盘的路径 rclone move "%F" "bt:/bt/%N" --create-empty-src-dirs --transfers=4 --checkers=4 Nginx反代 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #安装所需程序 sudo apt install certbot python3-certbot-nginx python3-certbot-dns-cloudflare nginx #手动编辑 sudo nano /etc/nginx/sites-available/bt #这里是nginx配置路径为conf.d的配置,下面启用配置命令不用 sudo nano /etc/nginx/conf.d/bt.conf #启用配置 sudo ln -s /etc/nginx/sites-available/bt /etc/nginx/sites-enabled/ #从Cloudflare获取区域DNS API sudo nano /etc/letsencrypt/cloudflare.ini dns_cloudflare_api_token = 你的API #赋予权限 sudo chmod 600 /etc/letsencrypt/cloudflare.ini #使用CF-DNS申请证书,你不想关小黄云用这个,全程y就行 sudo certbot certonly --dns-cloudflare --dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini -d example.com #直接申请证书,上面的申请完后可以用这个命令自动配置HTTPS,选1 sudo certbot --nginx -d example.com 配置示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 server { listen 80; # 端口可以随意修改 listen [::]:80; # IPv6 监听,同样可修改 #server_name _; server_name example.com; # 也可以写多个域名,用空格分隔 location / { proxy_pass http://127.0.0.1:8080; # 代理到本地 8080 端口 proxy_set_header Host $host; # 保留原始 Host 头 proxy_set_header X-Real-IP $remote_addr; # 真实客户端 IP proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # 协议(http/https) } } 内存占用解决办法 在设置高级中将磁盘 IO 类型设置为遵循 POSIX ...

六月 8, 2025 · 2 分钟 · 606 字 · Beiyuan

手搓Nginx反代开启HTTPS

Nginx Documents 安装Nginx 1. 安装依赖项 1 2 3 4 5 #我只用Debian和Ubuntu,需要centos的自行去nginx官网查找 #Debian sudo apt install curl gnupg2 ca-certificates lsb-release debian-archive-keyring -y #Ubuntu sudo apt install curl gnupg2 ca-certificates lsb-release ubuntu-keyring -y 2 . 导入 Nginx 官方签名密钥 1 2 curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \ | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null 3 . 验证密钥 1 gpg --dry-run --quiet --no-keyring --import --import-options import-show /usr/share/keyrings/nginx-archive-keyring.gpg 应看到如下输出中的指纹: ...

五月 30, 2025 · 2 分钟 · 686 字 · Beiyuan

Sing-box 1.11后配置示例

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 { "log": { "disabled": false, "level": "info", "output": "/root/box.log", "timestamp": true }, "inbounds": [ { "type": "socks", "tag": "socks-in", "listen": "::", "listen_port": 443, "tcp_fast_open": true, "tcp_multi_path": true, "sniff": true, "sniff_override_destination": true, "users": [ { "username": "fangxi", "password": "fangxi" } ] }, { "type": "shadowsocks", "tag": "ss-in", "listen": "::", "listen_port": 80, "method": "aes-128-gcm", "password": "", //sing-box generate rand 16 --base64 "tcp_multi_path": true, "tcp_fast_open": true, "sniff": true, "sniff_override_destination": true, "udp_disable_domain_unmapping": true, "multiplex": { "enabled": true, "padding": true } } ], "outbounds": [ { "type": "direct", "tag": "direct" } ], "route": { "rules": [ { "action": "sniff" }, { "protocol": [ "bittorrent" ], "action": "reject", "method": "default" }, { "inbound": [ "ss-in" ], "outbound": "direct" }, { "inbound": [ "ss-in" ], "outbound": "direct" }, { "rule_set": [ "geoip-cn", "geosite-geolocation-cn", "privateip", "ads" ], "action": "reject", "method": "default" }, { "domain": [ "www.gstatic.com" ], "outbound": "direct" } ], "rule_set": [ { "type": "remote", "tag": "privateip", "format": "binary", "url": "https://raw.githubusercontent.com/DustinWin/ruleset_geodata/sing-box-ruleset/privateip.srs", "download_detour": "direct" }, { "type": "remote", "tag": "geosite-geolocation-cn", "format": "binary", "url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-geolocation-cn.srs", "download_detour": "direct" }, { "type": "remote", "tag": "geoip-cn", "format": "binary", "url": "https://raw.githubusercontent.com/SagerNet/sing-geoip/rule-set/geoip-cn.srs", "download_detour": "direct" }, { "type": "remote", "tag": "geoip-jp", "format": "binary", "url": "https://cdn.jsdelivr.net/gh/Loyalsoldier/geoip@release/srs/jp.srs", "download_detour": "direct" }, { "type": "remote", "tag": "geosite-abema", "format": "binary", "url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-abema.srs", "download_detour": "direct" }, { "type": "remote", "tag": "geosite-dmm", "format": "binary", "url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-dmm.srs", "download_detour": "direct" }, { "type": "remote", "tag": "geosite-dmm-porn", "format": "binary", "url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-dmm-porn.srs", "download_detour": "direct" }, { "type": "remote", "tag": "ads", "format": "binary", "url": "https://raw.githubusercontent.com/DustinWin/ruleset_geodata/sing-box-ruleset/ads.srs", "download_detour": "direct" } ] } }

五月 15, 2025 · 1 分钟 · 393 字 · Beiyuan

Realm端口转发

获取执行文件 1 2 3 4 5 6 7 sudo mkdir -p /root/realm && \ curl -s https://api.github.com/repos/zhboner/realm/releases/latest | \ jq -r '.assets[] | select(.name | test("realm-x86_64-unknown-linux-gnu.tar.gz")) | .browser_download_url' | \ wget -O /root/realm/realm.tar.gz && \ sudo tar -xvf /root/realm/realm.tar.gz -C /root/realm && \ sudo chmod +x /root/realm/realm && \ sudo rm /root/realm/realm.tar.gz #可执行文件位于/root/realm 新建 config.toml 文件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 cat > /root/realm/config.toml <<EOF [network] no_tcp = false use_udp = true [[endpoints]] listen = "[::]:443" #监听v6,你的中转机,端口自行修改,以下类似 remote = "0.0.0.0:443 #监听v4,你的落地机 [[endpoints]] listen = "0.0.0.0:80" #监听v4,你的中转机 remote = "[::]:80#监听v6,你的落地机 EOF 写入Service 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 cat > /etc/systemd/system/realm.service <<EOF [Unit] Description=realm After=network-online.target Wants=network-online.target systemd-networkd-wait-online.service [Service] Type=simple User=root Restart=on-failure RestartSec=5s DynamicUser=true WorkingDirectory=/root ExecStart=/root/realm/realm -c /root/realm/config.toml [Install] WantedBy=multi-user.target EOF 启动服务 1 2 3 4 5 systemctl daemon-reload systemctl enable realm systemctl start realm systemctl restart realm systemctl status realm

五月 15, 2025 · 1 分钟 · 261 字 · Beiyuan

Rclone挂载Onedrive

获取 client_id 首先访问 Microsoft Azure应用注册,登录账号后点击应用注册 点击注册后可以看到你的应用的相关信息,复制好 应用程序 (客户端) ID,这个就是 client_id 获取 client_secret 依次点击证书和密码,新客户端密码,在截止期限中将时间选择为最长(即两年)然后就可以看见值和机密 ID,我们只需要记录下 值 就可以,这个就是client_secret 。 ...

五月 15, 2025 · 1 分钟 · 255 字 · Beiyuan

随机图片API部署

Github 准备 1 2 #安装所需程序 sudo apt install nginx php7.4-fpm php7.4-mysql php7.4-fpm php7.4-mysql php7.4-cli php7.4-opcache certbot python3-certbot-nginx python3-certbot-dns-cloudflare 创建Index.php文件 这里只需要修改路径 主路径 1 2 cd /var/www/html nano index.php 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 <?php $pcPath = '/landscape';#这里的路径自行修改 $mobilePath = '/portrait';#这里的路径自行修改 // 函数:从目录中获取图片列表 function getImagesFromDir($path) { $images = array(); if ($img_dir = @opendir($path)) { while (false !== ($img_file = readdir($img_dir))) { // 匹配 webp、jpg、jpeg、png、gif 格式的图片 if (preg_match("/\.(webp|jpg|jpeg|png|gif)$/i", $img_file)) { $images[] = $img_file; } } closedir($img_dir); } return $images; } // 函数:生成完整的图片路径 function generateImagePath($path, $img) { return $path . '/' . $img; } // 检测用户代理以区分手机和电脑访问 $userAgent = $_SERVER['HTTP_USER_AGENT']; $isMobile = preg_match('/(android|iphone|ipad|ipod|blackberry|windows phone)/i', $userAgent); // 根据访问设备设置图片路径 if ($isMobile) { $path = $mobilePath; } else { $path = $pcPath; } // 缓存图片列表 $imgList = getImagesFromDir($path); // 从列表中随机选择一张图片 shuffle($imgList); $img = reset($imgList); // 获取图片的格式 $img_extension = pathinfo($img, PATHINFO_EXTENSION); // 根据图片的格式设置 Content-Type switch ($img_extension) { case 'webp': header('Content-Type: image/webp'); break; case 'jpg': case 'jpeg': header('Content-Type: image/jpeg'); break; case 'png': header('Content-Type: image/png'); break; case 'gif': header('Content-Type: image/gif'); break; // 添加其他格式的处理方式 // case 'bmp': // header('Content-Type: image/bmp'); // break; } // 生成完整的图片路径 $img_path = generateImagePath($path, $img); // 直接输出所选的随机图片 readfile($img_path); ?> PC路径 1 2 mkdir /var/www/html/pc && cd /var/www/html/pc nano index.php 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 <?php $pcPath = '../landscape';#这里的路径自行修改 // 函数:从目录中获取图片列表 function getImagesFromDir($path) { $images = array(); if ($img_dir = @opendir($path)) { while (false !== ($img_file = readdir($img_dir))) { // 匹配 webp、jpg、jpeg、png、gif 格式的图片 if (preg_match("/\.(webp|jpg|jpeg|png|gif)$/i", $img_file)) { $images[] = $img_file; } } closedir($img_dir); } return $images; } // 函数:生成完整的图片路径 function generateImagePath($path, $img) { return $path . '/' . $img; } // 设置图片路径为 landscape $path = $pcPath; // 缓存图片列表 $imgList = getImagesFromDir($path); // 从列表中随机选择一张图片 shuffle($imgList); $img = reset($imgList); // 获取图片的格式 $img_extension = pathinfo($img, PATHINFO_EXTENSION); // 根据图片的格式设置 Content-Type switch ($img_extension) { case 'webp': header('Content-Type: image/webp'); break; case 'jpg': case 'jpeg': header('Content-Type: image/jpeg'); break; case 'png': header('Content-Type: image/png'); break; case 'gif': header('Content-Type: image/gif'); break; // 添加其他格式的处理方式 // case 'bmp': // header('Content-Type: image/bmp'); // break; } // 生成完整的图片路径 $img_path = generateImagePath($path, $img); // 直接输出所选的随机图片 readfile($img_path); ?> Mobile路径 1 2 mkdir /var/www/html/mobile && cd /var/www/html/mobile nano index.php 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 <?php $pcPath = '../portrait';#这里的路径自行修改 // 函数:从目录中获取图片列表 function getImagesFromDir($path) { $images = array(); if ($img_dir = @opendir($path)) { while (false !== ($img_file = readdir($img_dir))) { // 匹配 webp、jpg、jpeg、png、gif 格式的图片 if (preg_match("/\.(webp|jpg|jpeg|png|gif)$/i", $img_file)) { $images[] = $img_file; } } closedir($img_dir); } return $images; } // 函数:生成完整的图片路径 function generateImagePath($path, $img) { return $path . '/' . $img; } // 设置图片路径为 portrait $path = $pcPath; // 缓存图片列表 $imgList = getImagesFromDir($path); // 从列表中随机选择一张图片 shuffle($imgList); $img = reset($imgList); // 获取图片的格式 $img_extension = pathinfo($img, PATHINFO_EXTENSION); // 根据图片的格式设置 Content-Type switch ($img_extension) { case 'webp': header('Content-Type: image/webp'); break; case 'jpg': case 'jpeg': header('Content-Type: image/jpeg'); break; case 'png': header('Content-Type: image/png'); break; case 'gif': header('Content-Type: image/gif'); break; // 添加其他格式的处理方式 // case 'bmp': // header('Content-Type: image/bmp'); // break; } // 生成完整的图片路径 $img_path = generateImagePath($path, $img); // 直接输出所选的随机图片 readfile($img_path); ?> 反代开启HTTPS 1 2 3 4 #清空默认配置 > /etc/nginx/sites-available/default #手动编辑默认配置 sudo nano /etc/nginx/sites-available/default 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 server { listen [::]:8080; listen 8080; server_name example.com; # 替换为你的域名以便下面申请域名 root /var/www/html; # 设置网站根目录 # 默认首页是 index.php 或其他文件(根据你的需求) index index.php index.html index.htm; # 处理根目录请求,直接返回根目录下的文件(如果存在) location / { try_files $uri $uri/ /index.php?$query_string; } # 处理 PHP 文件 location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/var/run/php/php7.4-fpm.sock; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } # 防止访问 .ht 文件(如果有) location ~ /\.ht { deny all; } } 1 2 3 4 #测试Nginx配置 sudo nginx -t #重新加载Nginx配置 sudo systemctl reload nginx 现在可以访问ip:8080查看效果 ...

五月 15, 2025 · 5 分钟 · 2278 字 · Beiyuan

Linux修改DNS

方法一:Systemd-resolved 1 2 3 4 5 6 7 8 9 10 11 12 13 14 #查看是否安装 sudo systemctl status systemd-resolved #没有安装执行命令安装并启动 sudo apt update sudo apt install systemd-resolved -y sudo systemctl enable systemd-resolved && sudo systemctl start systemd-resolved #修改DNS sudo nano /etc/systemd/resolved.conf #示例 [Resolve] DNS=8.8.8.8 1.1.1.1 FallbackDNS=8.8.4.4 #修改完后退出,重新启动 sudo systemctl restart systemd-resolved 1 2 3 4 5 6 7 8 9 10 11 12 13 #报错masked输入下面的命令 sudo systemctl unmask systemd-resolved #再次重启 sudo systemctl restart systemd-resolved #查看是否修改成功 resolvectl status #查看是否软链接成功 ls -l /etc/resolv.conf #上面命令示例 lrwxrwxrwx 1 root root 32 Feb 11 2024 /etc/resolv.conf -> /run/systemd/resolve/resolv.conf #不一样执行下面的命令后再次查看 sudo rm /etc/resolv.conf sudo ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf 方法二:Resolved 1 2 3 4 5 sudo apt update sudo apt install resolvconf sudo nano /etc/resolv.conf #防止被修改 sudo chattr +i /etc/resolv.conf

五月 15, 2025 · 1 分钟 · 253 字 · Beiyuan

Linux创建python虚拟环境解决依赖问题

1 sudo apt update && sudo apt install python3 -y #安装python 1 2 3 4 5 sudo apt install python3-venv -y #安装虚拟环境 mkdir /opt/env && cd /opt/env #创建文件夹单独存放相关文件和配置,也可以不创建 python3 -m venv env #创建虚拟环境,env是你虚拟环境的名称,可以自定义,这里创建虚拟环境同时会创建一个文件夹 source env/bin/activate #激活虚拟环境,这里的env同理,需要和上面一致 deactivate #关闭虚拟环境

五月 15, 2025 · 1 分钟 · 148 字 · Beiyuan