|-转 No VM guests are running outdated hypervisor (qemu) binaries on this host. error: externally-managed-environment
shi ji shang gen vm wu guan 20250929 1310
No VM guests are running outdated hypervisor (qemu) binaries on this host.
error: externally-managed-environment
× This environment is externally managed
╰─> To install Python packages system-wide, try apt install
python3-xyz, where xyz is the package you are trying to
install.
If you wish to install a non-Debian-packaged Python package,
create a virtual environment using python3 -m venv path/to/venv.
Then use path/to/venv/bin/python and path/to/venv/bin/pip. Make
sure you have python3-full installed.
If you wish to install a non-Debian packaged Python application,
it may be easiest to use pipx install xyz, which will manage a
virtual environment for you. Make sure you have pipx installed.
See /usr/share/doc/python3.12/README.venv for more information.
note: If you believe this is a mistake, please contact your Python installation or OS distribution provider. You can override this, at the risk of breaking your Python installation or OS, by passing --break-system-packages.
hint: See PEP 668 for the detailed specification.
root@racknerd-6e4bbd6:~#
SSH 72.11.150.175: session closed
Press any key to reconnect
zen me jie jue , feng zhuange ge han shu , rang wo jin ru xu ni huan jing .
20250929 0839
看到你遇到了 Python 的外部管理环境错误。这是因为 Ubuntu 24.04 默认启用了 PEP 668,禁止直接使用 pip 安装系统级包。我来为你编写一个函数来解决这个问题:#!/bin/bash
# 创建 Python 虚拟环境函数
create_python_venv() {
local venv_path="${1:-/opt/certbot-venv}"
log "[PYTHON] 创建 Python 虚拟环境: $venv_path"
# 检查是否已安装 python3-venv
if ! dpkg -l | grep -q python3-venv; then
log "[INSTALL] 安装 python3-venv..."
apt-get install -y python3-venv python3-full
fi
# 创建虚拟环境
if [[ ! -d "$venv_path" ]]; then
python3 -m venv "$venv_path"
log "[OK] 虚拟环境创建成功: $venv_path"
else
log "[INFO] 虚拟环境已存在: $venv_path"
fi
# 激活虚拟环境
source "$venv_path/bin/activate"
# 升级 pip
"$venv_path/bin/pip" install --upgrade pip
log "[OK] Python 虚拟环境已激活"
echo "$venv_path"
}
# 在虚拟环境中安装 certbot DNSPod 插件
install_certbot_dnspod_in_venv() {
local venv_path="${1:-/opt/certbot-venv}"
log "[CERTBOT] 在虚拟环境中安装 certbot DNSPod 插件..."
# 创建或使用现有虚拟环境
if [[ ! -d "$venv_path" ]]; then
venv_path=$(create_python_venv "$venv_path")
fi
# 激活虚拟环境
source "$venv_path/bin/activate"
# 在虚拟环境中安装 certbot 和 DNSPod 插件
"$venv_path/bin/pip" install certbot certbot-dns-dnspod
log "[OK] certbot 和 DNSPod 插件已在虚拟环境中安装"
}
# 使用虚拟环境中的 certbot 申请证书
apply_ssl_certificate_with_venv() {
local domain="$1"
local venv_path="${2:-/opt/certbot-venv}"
log "[SSL] 为域名 $domain 申请 SSL 证书(使用虚拟环境)..."
# 确保虚拟环境存在
if [[ ! -d "$venv_path" ]]; then
install_certbot_dnspod_in_venv "$venv_path"
fi
# 检查凭据文件
if [[ ! -f "/root/.dnspod.ini" ]]; then
log "[ERROR] DNSPod 凭据文件 /root/.dnspod.ini 不存在"
return 1
fi
# 使用虚拟环境中的 certbot
if "$venv_path/bin/certbot" certonly \
--authenticator dns-dnspod \
--dns-dnspod-credentials /root/.dnspod.ini \
--dns-dnspod-propagation-seconds 30 \
--non-interactive \
--agree-tos \
--email your-email@example.com \ # 请替换为你的邮箱
-d "$domain" \
-d "*.$domain"; then
log "[OK] SSL 证书申请成功: $domain"
return 0
else
log "[ERROR] SSL 证书申请失败: $domain"
return 1
fi
}
# 完整的依赖安装函数(包含虚拟环境设置)
install_dependencies() {
log "[INSTALL] 安装系统依赖..."
local system_packages=(
curl
wget
git
openssl
dnsutils
net-tools
python3-venv
python3-full
apt-transport-https
ca-certificates
gnupg
lsb-release
)
# ... 你原有的依赖安装逻辑 ...
# 安装 Python 虚拟环境相关包
local packages_to_install=()
for pkg in "${system_packages[@]}"; do
if ! dpkg -l | grep -q "^ii $pkg "; then
packages_to_install+=("$pkg")
fi
done
if [ ${#packages_to_install[@]} -gt 0 ]; then
apt-get update -qq
apt-get install -y "${packages_to_install[@]}"
fi
# 创建 certbot 虚拟环境
install_certbot_dnspod_in_venv "/opt/certbot-venv"
# ... 你原有的 Docker 和 Docker Compose 安装代码 ...
log "[OK] 所有依赖安装完成"
}
# 使用示例
# install_dependencies
# apply_ssl_certificate_with_venv "your-domain.com"使用方法:
在你的脚本中这样调用:#!/bin/bash
# 设置日志函数(如果你还没有)
log() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1"
}
# 包含上面的函数定义
# ... 将上面的函数复制到这里 ...
# 主执行流程
main() {
# 安装所有依赖(包括虚拟环境)
install_dependencies
# 申请 SSL 证书(使用虚拟环境中的 certbot)
apply_ssl_certificate_with_venv "your-domain.com"
# 检查证书状态
if [[ $? -eq 0 ]]; then
log "[SUCCESS] SSL 证书部署完成"
else
log "[ERROR] SSL 证书部署失败"
exit 1
fi
}
# 执行主函数
main "$@"关键改进:
- 创建专用虚拟环境:在 /opt/certbot-venv中创建独立的 Python 环境
- 在虚拟环境中安装:使用虚拟环境的 pip 安装 certbot 和插件,避免系统级冲突
- 使用虚拟环境的 certbot:通过完整路径调用虚拟环境中的 certbot
- 自动安装依赖:确保 python3-venv 和 python3-full 已安装
这样就能完全避免 PEP 668 的限制,同时保持系统环境的干净和安全。记得将 your-email@example.com替换为你的实际邮箱地址。...
|-转 /tmp/dc-jitsi-env.yml: the attribute `version` is obsolete, jitsi/prosody:latest not found:
WARN[0050] Found orphan containers ([nginx-acme nginx-proxy]) for this project. If you removed or renamed this service in your compose file, you can run this command with the --remove-orphans flag to clean it up. [+] Running 3/3 ✔ Container mongo Started 0.4s ✔ Container rocketchat Started 0.4s ✔ Container mongo-init Started 0.4s WARN[0000] /tmp/dc-jitsi-env.yml: the attribute `version` is obsolete, it will be ignored, please remove it to avoid potential confusion [+] Running 4/4 ! web Interrupted 0.3s ! jicofo Interrupted 0.3s ! jvb Interrupted 0.3s ✘ prosody Error manifest for jitsi/prosody:latest not found: manifest unknown: manifest unknown 0.3s Error response from daemon: manifest for jitsi/prosody:latest not found: manifest unknown: manifest unknown root@racknerd-6e4bbd6:~#
...
|-转 VS Code Server 全能脚本
dai jie jue
#!/bin/bash #====================================================# # ? VS Code Server 全能脚本 # 默认:显示状态 | -i:安装 | 安全智能,不误操作 #====================================================# set -euo pipefail # ========== 配置 ========== SERVICE_NAME="vscode-server" SERVICE_FILE="/etc/systemd/system/${SERVICE_NAME}.service" CODE_BIN="/usr/local/bin/code-cli" PORT=8080 ARCH=$(uname -m) USER="${SUDO_USER:-$USER}" HOME_DIR=$(getent passwd "$USER" | cut -d: -f6) USERNAME="http://72.11.150.175:8080/ " case $ARCH in x86_64) ARCH=x64 ;; aarch64) ARCH=arm64 ;; *) echo "❌ 不支持的架构: $ARCH" >&2; exit 1 ;; esac DOWNLOAD_URL="https://update.code.visualstudio.com/latest/cli-linux- ${ARCH}/stable" # =================================================== # 替换原 read 用户名密码部分 setup_auth() { echo "? 设置用户名和密码访问..." # 检查是否安装 apache2-utils 或 httpd-tools if ! command -v htpasswd &>/dev/null; then echo "? 安装 htpasswd 工具..." if command -v apt &>/dev/null; then sudo apt update && sudo apt install -y apache2-utils elif command -v yum &>/dev/null; then sudo yum install -y httpd-tools elif command -v dnf &>/dev/null; then sudo dnf install -y httpd-tools else echo "❌ 无法安装 htpasswd,请手动安装 apache2-utils 或 httpd-tools" exit 1 fi fi read -p "请输入用户名: " USERNAME PASSWORD_DIR="/etc/vscode-server" PASSWORD_FILE="$PASSWORD_DIR/passwd" sudo mkdir -p "$PASSWORD_DIR" # 使用 htpasswd 创建加密密码文件 if [[ -f "$PASSWORD_FILE" ]]; then sudo htpasswd -B "$PASSWORD_FILE" "$USERNAME" else sudo htpasswd -B -c "$PASSWORD_FILE" "$USERNAME" fi sudo chmod 600 "$PASSWORD_FILE" echo "✅ 用户凭证已加密保存到: $PASSWORD_FILE" # ✅ 关键:创建软链接并修复权限 sudo -u "$USER" mkdir -p "$HOME_DIR/.vscode-server" sudo ln -sf "$PASSWORD_FILE" "$HOME_DIR/.vscode-server/passwd" sudo chown "$USER:$USER" "$HOME_DIR/.vscode-server/passwd" } # ========== 函数:显示状态 ========== show_status() { echo "? 正在检查 VS Code Server 状态..." if [[ ! -f "$SERVICE_FILE" ]]; then echo "? 未安装:未找到服务文件 $SERVICE_FILE" echo "? 安装命令:$0 --install" exit 1 fi if ! systemctl is-enabled "$SERVICE_NAME" &>/dev/null; then echo "? 已安装但未启用" echo "? 启用服务:sudo systemctl enable --now $SERVICE_NAME" exit 1 fi if ! systemctl is-active --quiet "$SERVICE_NAME"; then echo "? 服务已安装但未运行" echo "? 启动服务:sudo systemctl start $SERVICE_NAME" # 尝试提取地址(可能上次运行过) URL=$(sudo journalctl -u "$SERVICE_NAME" --no-pager | grep -o "http://[^ ]*tkn=[^ ]*" | tail -n1) if [[ -n "$URL" ]]; then IP=$(echo "$URL" | sed "s|0.0.0.0|$(hostname -I | awk '{print $1}' || echo 'your-server-ip')|") echo "? 上次访问地址(服务未运行):$IP" fi exit 1 fi URL=$(sudo journalctl -u "$SERVICE_NAME" --no-pager | grep -o "http://[^ ]*tkn=[^ ]*" | tail -n1) if [[ -z "$URL" ]]; then # 日志没有 URL,则尝试从服务文件解析 token if [[ -f "$SERVICE_FILE" ]]; then TOKEN_FROM_SVC=$(grep -oE "--connection-token\s+[^ ]+" "$SERVICE_FILE" | awk '{print $2}' || true) if [[ -n "${TOKEN_FROM_SVC:-}" ]]; then IP_ADDR=$(hostname -I | awk '{print $1}' || echo 'your-server-ip') URL="http://${IP_ADDR}:${PORT}?tkn=${TOKEN_FROM_SVC}" fi fi if [[ -z "$URL" ]]; then echo "⚠️ 服务运行中,但未找到访问地址" echo "? 查看日志:sudo journalctl -u $SERVICE_NAME -f" exit 1 fi fi IP=$(echo "$URL" | sed "s|0.0.0.0|$(hostname -I | awk '{print $1}' || echo 'your-server-ip')|") echo "==================================================" echo "? VS Code Server 正在运行!" echo "? 访问地址: $IP" echo "? Token 已包含在链接中,请勿泄露" echo "? 提示:复制整个链接到浏览器打开" echo "⏹️ 停止服务: sudo systemctl stop $SERVICE_NAME" echo "? 重启服务: sudo systemctl restart $SERVICE_NAME" echo "==================================================" } # ========== 函数:安装 ========== # ========== 函数:安装 ========== # ========== 函数:安装 ========== install_server() { echo "? 开始安装 VS Code Server..." # 1. 清理旧状态 echo "? 清理旧服务..." sudo systemctl stop "$SERVICE_NAME" 2>/dev/null || true sudo systemctl disable "$SERVICE_NAME" 2>/dev/null || true sudo rm -f "$CODE_BIN" sudo rm -f "$SERVICE_FILE" # 2. 下载 CLI TMP_TAR="/tmp/code-cli.tar.gz" TMP_DIR="/tmp/vscode-install-$RANDOM" mkdir -p "$TMP_DIR" echo "? 正在下载 CLI..." for i in {1..3}; do if curl -# -f -L -o "$TMP_TAR" "$DOWNLOAD_URL"; then echo "✔ 下载成功" break else echo "? 第 $i 次下载失败,2 秒后重试..." sleep 2 fi done if [[ ! -f "$TMP_TAR" ]]; then echo "❌ 下载失败,请检查网络" exit 1 fi tar -xzf "$TMP_TAR" -C "$TMP_DIR" rm -f "$TMP_TAR" if [[ ! -f "$TMP_DIR/code" ]]; then echo "❌ 解压失败:未找到 'code' 文件" rm -rf "$TMP_DIR" exit 1 fi sudo mv "$TMP_DIR/code" "$CODE_BIN" sudo chmod +x "$CODE_BIN" rm -rf "$TMP_DIR" echo "✅ CLI 已安装到: $CODE_BIN" # 20250929 1908 setup_auth # 4. 创建服务文件 echo "? 创建 systemd 服务..." sudo tee "$SERVICE_FILE" > /dev/null << EOF [Unit] Description=VS Code Server After=network.target [Service] Type=simple User=$USER ExecStart=$CODE_BIN serve-web --host 0.0.0.0 --port $PORT --without-connection-token --accept-server-license-terms --verbose --server-data-dir $HOME_DIR/.vscode-server --enable-authentication Environment=SHELL=/bin/bash Restart=always RestartSec=3 [Install] WantedBy=multi-user.target EOF # 5. 防火墙 echo "?️ 防火墙放行 $PORT/tcp" if command -v ufw &>/dev/null && sudo ufw status | grep -q "Status: active"; then sudo ufw allow "$PORT/tcp" >/dev/null 2>&1 || true fi if command -v firewall-cmd &>/dev/null && sudo firewall-cmd --state &>/dev/null; then sudo firewall-cmd --permanent --add-port="$PORT/tcp" >/dev/null 2>&1 || true sudo firewall-cmd --reload >/dev/null 2>&1 || true fi # 6. 启动服务 echo "? 启动服务..." sudo systemctl daemon-reload sudo systemctl enable --now "$SERVICE_NAME" sleep 3 if ! systemctl is-active --quiet "$SERVICE_NAME"; then echo "❌ 服务启动失败!运行查看日志:" echo " sudo journalctl -u $SERVICE_NAME -f" exit 1 fi IP=$(hostname -I | awk '{print $1}' || echo "your-server-ip") echo "==================================================" echo "? 安装成功!" echo "? 访问地址: http://$IP:$PORT" echo "? 用户名: $USERNAME" echo "? 密码: ****** (您刚才设置的密码)" echo "? 已设置开机自启" echo "? 提示:访问时浏览器会弹出用户名/密码输入框" echo "==================================================" } # ========== 函数:卸载 ========== # ========== 函数:卸载 ========== uninstall_server() { echo "? 正在卸载 VS Code Server..." # 1. 停止并禁用服务 if systemctl is-active --quiet "$SERVICE_NAME"; then echo "⏹️ 停止服务..." sudo systemctl stop "$SERVICE_NAME" fi if systemctl is-enabled --quiet "$SERVICE_NAME"; then echo "? 禁用服务..." sudo systemctl disable "$SERVICE_NAME" >/dev/null 2>&1 || true fi # 2. 删除服务文件 echo "?️ 删除服务文件..." sudo rm -f "$SERVICE_FILE" sudo systemctl daemon-reload # 3. 删除 CLI 二进制 echo "?️ 删除 CLI 二进制..." sudo rm -f "$CODE_BIN" # 4. 删除用户数据(可选) echo "?️ 删除 VS Code 用户数据(缓存、扩展等)..." # 使用 -rf 递归删除目录及其内容,而不是仅仅尝试删除目录本身 rm -rf "$HOME_DIR/.vscode-server" 2>/dev/null || true rm -rf "$HOME_DIR/.vscode" 2>/dev/null || true # 5. 删除密码文件 echo "?️ 删除密码文件..." sudo rm -f "/etc/vscode-server/passwd" sudo rmdir "/etc/vscode-server" 2>/dev/null || true # 只有当目录为空时才删除 # 6. 防火墙规则清理(尽力而为) echo "?️ 清理防火墙规则(端口 $PORT/tcp)..." if command -v ufw &>/dev/null && sudo ufw status | grep -q "$PORT/tcp"; then sudo ufw delete allow "$PORT/tcp" >/dev/null 2>&1 || true fi if command -v firewall-cmd &>/dev/null && sudo firewall-cmd --state &>/dev/null; then sudo firewall-cmd --permanent --remove-port="$PORT/tcp" >/dev/null 2>&1 || true sudo firewall-cmd --reload >/dev/null 2>&1 || true fi echo "==================================================" echo "✅ 卸载完成!" echo "? 所有相关文件和服务已删除" echo "? 如需重新安装:$0 --install" echo "==================================================" } # ========== 主逻辑 ========== case "${1:-}" in -i|--install|install) install_server ;; -u|--uninstall|uninstall) uninstall_server ;; -h|--help|help) echo "Usage: $0 [option]" echo " (no args) 显示 VS Code Server 状态和访问地址" echo " -i, --install 安装或重装 VS Code Server" echo " -u, --uninstall 卸载 VS Code Server(彻底清理)" echo " -h, --help 显示帮助" exit 0 ;; "") show_status ;; *) echo "❌ 未知参数: $1" echo "? 使用 -h 查看帮助" exit 1 ;; esac ExecStart=$CODE_BIN serve-web --host 0.0.0.0 --port $PORT --without-connection-token --accept-server-license-terms --verbose --server-data-dir $HOME_DIR/.vscode-server neng zheng chang shi yong ,dan shi fang wen bu xu yao shu ru zhang hao mi ma , ExecStart=$CODE_BIN serve-web --host 0.0.0.0 --port $PORT --without-connection-token --accept-server-license-terms --verbose --server-data-dir $HOME_DIR/.vscode-server --enable-authentication , ben lai shi xiang jia yan zheng de ,jie guo bu neng fang wen le This site can’t be reached 72.11.150.175 refused to connect. Try: Checking the connection Checking the proxy and the firewall ERR_CONNECTION_REFUSED
20250929 1935 ...
|-转 mkdir -p /code/{shell,python,php,other}
|-转 Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed:
Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: error mounting "/jm/web-custom/recommendedBrowsers.html" to rootfs at "/usr/share/jitsi-meet/static/recommendedBrowsers.html": create mountpoint for /usr/share/jitsi-meet/static/recommendedBrowsers.html mount: cannot create subdirectories in "/var/lib/docker/overlay2/c61e5e821098182c8aaf007bcb0fa0778e219c7a45a40d04fdf1332df79d17e5/merged/usr/share/jitsi-meet/static/recommendedBrowsers.html": not a directory: unknown: Are you trying to mount a directory onto a file (or vice-versa)? Check if the specified host path exists and is the expected type
[+] Running 3/4 ✔ Container jitsi-jvb Started 0.4s ✔ Container jitsi-prosody Started 0.3s ⠸ Container jitsi-web Starting 0.5s ✔ Container jitsi-jicofo Started 0.5s Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: error mounting "/jm/web-custom/recommendedBrowsers.html" to rootfs at "/usr/share/jitsi-meet/static/recommendedBrowsers.html": create mountpoint for /usr/share/jitsi-meet/static/recommendedBrowsers.html mount: cannot create subdirectories in "/var/lib/docker/overlay2/c61e5e821098182c8aaf007bcb0fa0778e219c7a45a40d04fdf1332df79d17e5/merged/usr/share/jitsi-meet/static/recommendedBrowsers.html": not a directory: unknown: Are you trying to mount a directory onto a file (or vice-versa)? Check if the specified host path exists and is the expected type root@racknerd-6e4bbd6:/code/shell#
20250929 ...
|-转 narj.sh
bash narj.sh
===> 创建外部网络 webproxy ...
[+] Running 2/2
✔ Container nginx-proxy Running 0.0s
✔ Container nginx-acme Running 0.0s
[+] Running 3/3
✔ Container mongo Running 0.0s
✔ Container rocketchat Running 0.0s
✔ Container mongo-init Started 0.1s
[+] Running 4/4
✔ Container jitsi-web Started 0.2s
✔ Container jitsi-prosody Started 0.0s
✔ Container jitsi-jvb Started 0.0s
✔ Container jitsi-jicofo Started 0.0s
nginx-proxy
nginx-acme
rocketchat
mongo
jitsi-web
jitsi-prosody
jitsi-jicofo
jitsi-jvb
............................................................
==================================================
Rocket.Chat 地址:https://chat.dcdht.com
Jitsi Meet 地址:https://meet.dcdht.com
==================================================
=> 部署 code-server (VS Code Web) ...
请输入 VS Code Web 登录密码(不少于6位):
[+] Running 9/9
✔ vscode Pulled 9.3s
✔ d1da99c2f148 Pull complete 3.1s
✔ 7406571e392a Pull complete 5.7s
✔ 9ab922153835 Pull complete 5.7s
✔ fdf7c3eb3e70 Pull complete 5.7s
✔ 41d9baa20522 Pull complete 5.8s
✔ a87022ba70f0 Pull complete 5.8s
✔ 4974932e2904 Pull complete 8.6s
✔ 4f4fb700ef54 Pull complete 8.6s
[+] Running 1/1
✔ Container vscode Started 0.3s
==================================================
VS Code Web 地址:https://vscode.dcdht.com suo you https dou bu neng zheng chuang fang wen , hui bu hui shi wo de bian liang mei huan hao . #!/usr/bin/env bash
#==================================================
# 一键部署:nginx-proxy + acme-companion + Rocket.Chat + Jitsi Meet + vscode
# 项目根目录 $BASE_DIR ;数据、配置、compose 全放 $BASE_DIR 下
#==================================================
set -eu
############################ 头部常量区 #############################
DOMAIN_RC="chat.dcdht.com"
DOMAIN_JM="meet.dcdht.com"
DOMAIN_VSCODE="vscode.dcdht.com"
EMAIL="syh0304@gmail.com"
# 放在顶部常量区之后
BASE_DIR=${BASE_DIR:-/opt} # 若外部没传,默认 /opt
export BASE_DIR # 让 envsubst 也能拿到
###################################################################
# 后面所有 ROOT_DIR_* 直接用 BASE_DIR 拼接即可,无需再导出
ROOT_DIR_PROXY="$BASE_DIR/proxy"
ROOT_DIR_RC="$BASE_DIR/rc"
ROOT_DIR_JM="$BASE_DIR/jm"
ROOT_DIR_VSCODE="$BASE_DIR/vscode"
#########################################################################
[[ $EUID -eq 0 ]] || { echo "请 root 运行"; exit 1; }
command -v docker >/dev/null || {
echo "===> 未检测到 Docker,正在自动安装 ..."
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
systemctl enable --now docker
usermod -aG docker $USER
exec sg docker -c "bash -c 'docker version >/dev/null 2>&1'"
}
docker compose version >/dev/null 2>&1 || { echo "未安装 docker-compose-plugin"; exit 1; }
echo "===> 创建外部网络 webproxy ..."
docker network create webproxy 2>/dev/null || true
# 创建目录
mkdir -p "$ROOT_DIR_PROXY" "$ROOT_DIR_RC" "$ROOT_DIR_JM"
mkdir -p /data/{rc-db,rc-uploads,jitsi/{web,prosody,jicofo,jvb,transcripts}}
#################### 1. 反代 + 自动证书 ####################
cat >"$ROOT_DIR_PROXY/dc-proxy.yml" <<'EOF'
services:
nginx-proxy:
image: nginxproxy/nginx-proxy:latest
container_name: nginx-proxy
ports: ["80:80","443:443"]
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- ./certs:/etc/nginx/certs
- ./vhost:/etc/nginx/vhost.d
- ./html:/usr/share/nginx/html
restart: unless-stopped
networks: [webproxy]
acme:
image: nginxproxy/acme-companion:latest
container_name: nginx-acme
volumes_from: [nginx-proxy]
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./acme:/etc/acme.sh
environment:
DEFAULT_EMAIL: ${EMAIL}
restart: unless-stopped
networks: [webproxy]
volumes: {certs,vhost,html,acme}
networks:
webproxy:
external: true
EOF
export EMAIL
envsubst '$EMAIL' <"$ROOT_DIR_PROXY/dc-proxy.yml" >"$ROOT_DIR_PROXY/dc-proxy-env.yml"
docker compose -f "$ROOT_DIR_PROXY/dc-proxy-env.yml" up -d
#################### 2. Rocket.Chat ####################
cat >"$ROOT_DIR_RC/dc-rc.yml" <<'EOF'
services:
rocketchat:
image: rocketchat/rocket.chat:latest
container_name: rocketchat
environment:
VIRTUAL_HOST: ${DOMAIN_RC}
LETSENCRYPT_HOST: ${DOMAIN_RC}
VIRTUAL_PROTO: websocket
VIRTUAL_PORT: 3000
MONGO_URL: mongodb://mongo:27017/rocketchat
MONGO_OPLOG_URL: mongodb://mongo:27017/local
ROOT_URL: https://${DOMAIN_RC}
volumes:
- /data/rc-uploads:/app/uploads
restart: unless-stopped
networks: [webproxy]
depends_on: [mongo]
mongo:
image: mongo:6
container_name: mongo
command: mongod --oplogSize 128 --replSet rs0
volumes:
- /data/rc-db:/data/db
restart: unless-stopped
networks: [webproxy]
mongo-init:
image: mongo:6
container_name: mongo-init
command: >
bash -c "sleep 5 && mongosh --host mongo --eval '
rs.initiate({_id:\"rs0\",members:[{_id:0,host:\"mongo:27017\"}]})'"
depends_on: [mongo]
networks: [webproxy]
networks:
webproxy:
external: true
EOF
export DOMAIN_RC
envsubst '$DOMAIN_RC' <"$ROOT_DIR_RC/dc-rc.yml" >"$ROOT_DIR_RC/dc-rc-env.yml"
docker compose -f "$ROOT_DIR_RC/dc-rc-env.yml" up -d
#################### 3. Jitsi Meet + HTTPS 白屏修复 ####################
# ① 先准备“空白放行页”避免 Chrome 140 被踢
mkdir -p $BASE_DIR/jm/web-custom
cat >$BASE_DIR/jm/web-custom/recommendedBrowsers.html <<'EOF'
EOF
cat >"$ROOT_DIR_JM/dc-jm.yml" <<'EOF'
services:
web:
image: jitsi/web:stable
container_name: jitsi-web
environment:
VIRTUAL_HOST: ${DOMAIN_JM}
LETSENCRYPT_HOST: ${DOMAIN_JM}
PUBLIC_URL: https://${DOMAIN_JM}
ENABLE_LETSENCRYPT: 0
JICOFO_AUTH_USER: focus
XMPP_DOMAIN: ${DOMAIN_JM}
XMPP_AUTH_DOMAIN: auth.${DOMAIN_JM}
XMPP_MUC_DOMAIN: muc.${DOMAIN_JM}
XMPP_INTERNAL_MUC_DOMAIN: internal-muc.${DOMAIN_JM}
TZ: Asia/Shanghai
volumes:
- /data/jitsi/web:/config
- $BASE_DIR/jm/web-custom/recommendedBrowsers.html:/usr/share/jitsi-meet/static/recommendedBrowsers.html:ro
restart: unless-stopped
networks: [webproxy]
depends_on: [prosody]
prosody:
image: jitsi/prosody:stable
container_name: jitsi-prosody
environment:
XMPP_DOMAIN: ${DOMAIN_JM}
XMPP_AUTH_DOMAIN: auth.${DOMAIN_JM}
XMPP_MUC_DOMAIN: muc.${DOMAIN_JM}
XMPP_INTERNAL_MUC_DOMAIN: internal-muc.${DOMAIN_JM}
JICOFO_AUTH_USER: focus
JVB_AUTH_USER: jvb
GLOBAL_MODULES: "bosh,websocket,smacks"
TZ: Asia/Shanghai
volumes:
- /data/jitsi/prosody:/config
restart: unless-stopped
networks: [webproxy]
jicofo:
image: jitsi/jicofo:stable
container_name: jitsi-jicofo
environment:
XMPP_DOMAIN: ${DOMAIN_JM}
XMPP_AUTH_DOMAIN: auth.${DOMAIN_JM}
XMPP_INTERNAL_MUC_DOMAIN: internal-muc.${DOMAIN_JM}
JICOFO_AUTH_USER: focus
JVB_AUTH_USER: jvb
TZ: Asia/Shanghai
depends_on: [prosody]
restart: unless-stopped
networks: [webproxy]
jvb:
image: jitsi/jvb:stable
container_name: jitsi-jvb
environment:
XMPP_DOMAIN: ${DOMAIN_JM}
XMPP_AUTH_DOMAIN: auth.${DOMAIN_JM}
XMPP_INTERNAL_MUC_DOMAIN: internal-muc.${DOMAIN_JM}
JVB_AUTH_USER: jvb
JVB_BREWERY_MUC: jvbbrewery@internal-muc.${DOMAIN_JM}
JVB_PORT: 10000
JVB_TCP_HARVESTER_PORT: 4443
PUBLIC_URL: https://${DOMAIN_JM}
TZ: Asia/Shanghai
ports:
- "10000:10000/udp"
- "4443:4443/tcp"
volumes:
- /data/jitsi/jvb:/config
restart: unless-stopped
networks: [webproxy]
networks:
webproxy:
external: true
EOF
export DOMAIN_JM
envsubst '$DOMAIN_JM' <"$ROOT_DIR_JM/dc-jm.yml" >"$ROOT_DIR_JM/dc-jm-env.yml"
docker compose -f "$ROOT_DIR_JM/dc-jm-env.yml" up -d
#################### 4. 开机自启 & 等证书 ####################
docker update --restart=unless-stopped nginx-proxy nginx-acme rocketchat mongo jitsi-web jitsi-prosody jitsi-jicofo jitsi-jvb
i=0
while (( i++ < 60 )); do
if docker logs nginx-acme 2>&1 | grep -q "Certificate received"; then
echo "✔ 证书已颁发成功!"
break
fi
echo -n "."
sleep 2
done
echo
echo "=================================================="
echo "Rocket.Chat 地址:https://${DOMAIN_RC}"
echo "Jitsi Meet 地址:https://${DOMAIN_JM}"
echo "=================================================="
#################### 5. VS Code Web (code-server) ####################
echo "=> 部署 code-server (VS Code Web) ..."
mkdir -p $BASE_DIR/vscode/data $BASE_DIR/vscode/config
# 交互设置密码
while :; do
read -rsp '请输入 VS Code Web 登录密码(不少于6位): ' VSCODE_PW
echo
if [[ ${#VSCODE_PW} -ge 6 ]]; then
break
else
echo "密码太短,请重新输入!"
fi
done
cat >$BASE_DIR/vscode/config/config.yaml <$BASE_DIR/vscode/dc-vscode.yml <<'EOF'
services:
vscode:
image: codercom/code-server:4.19.1
container_name: vscode
environment:
VIRTUAL_HOST: ${DOMAIN_VSCODE}
LETSENCRYPT_HOST: ${DOMAIN_VSCODE}
TZ: Asia/Shanghai
volumes:
- $BASE_DIR/vscode/config:/home/coder/.config/code-server
- $BASE_DIR/vscode/data:/home/coder/data
- $BASE_DIR:$BASE_DIR:rw
- /code:/code:rw
- /data:/data:ro
restart: unless-stopped
networks: [webproxy]
networks:
webproxy:
external: true
EOF
# 域名变量(只在这用,可加在脚本头部常量区)
export DOMAIN_VSCODE
envsubst '$DOMAIN_VSCODE' < $ROOT_DIR_VSCODE/dc-vscode.yml > $ROOT_DIR_VSCODE/dc-vscode-env.yml
docker compose -f $ROOT_DIR_VSCODE/dc-vscode-env.yml up -d
echo "=================================================="
echo "VS Code Web 地址:https://${DOMAIN_VSCODE}"
echo "登录密码:${VSCODE_PW}"
echo "=================================================="
20250929...
|-转 certbot: error: unrecognized arguments: --nginx_conf /www/server/nginx/conf/nginx.conf
sudo certbot certonly --webroot -w /var/www/letsencrypt -d chat.chawen.org usage: certbot [SUBCOMMAND] [options] [-d DOMAIN] [-d DOMAIN] ... Certbot can obtain and install HTTPS/TLS/SSL certificates. By default, it will attempt to use a webserver both for obtaining and installing the certificate. certbot: error: unrecognized arguments: --nginx_conf /www/server/nginx/conf/nginx.conf [root@10-7-184-91 shell]#
20250930 0858 ...