Skip to content

Commit f9b6da2

Browse files
committed
Merge branch 'dev' of https://github.com/Mai-with-u/MaiBot into dev
2 parents 8d2946a + fa750c8 commit f9b6da2

5 files changed

Lines changed: 539 additions & 394 deletions

File tree

.devcontainer/Dockerfile

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
FROM mcr.microsoft.com/devcontainers/python:1-3.13-bookworm
2+
3+
# 修复 Yarn APT 仓库 GPG 密钥过期(NO_PUBKEY 62D54FD4003F6525)
4+
# 必须在任何 apt-get update 之前移除,否则 features 中的 apt-packages 等会失败
5+
RUN rm -f /etc/apt/sources.list.d/yarn.list
6+
7+
# 安装 uv:与生产 Dockerfile 一致
8+
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
9+
10+
# 需要使用 gitpod-remote-ssh 扩展的开发者请注释下面三行构建命令
11+
RUN for d in /home/vscode/.vscode-server/extensions/gitpod.gitpod-remote-ssh-*; do \
12+
[ -d "$d" ] && mv "$d" "${d}.disabled"; \
13+
done; exit 0

.devcontainer/devcontainer.json

Lines changed: 80 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,80 @@
1-
{
2-
"name": "MaiBot-DevContainer",
3-
"image": "mcr.microsoft.com/devcontainers/python:1-3.12-bullseye",
4-
"features": {
5-
"ghcr.io/rocker-org/devcontainer-features/apt-packages:1": {
6-
"packages": [
7-
"tmux"
8-
]
9-
},
10-
"ghcr.io/devcontainers/features/github-cli:1": {}
11-
},
12-
"forwardPorts": [
13-
"8000:8000"
14-
],
15-
"postCreateCommand": "pip3 install --user -r requirements.txt",
16-
"customizations": {
17-
"jetbrains": {
18-
"backend": "PyCharm"
19-
},
20-
"vscode": {
21-
"extensions": [
22-
"tamasfe.even-better-toml",
23-
"njpwerner.autodocstring",
24-
"ms-python.python",
25-
"KevinRose.vsc-python-indent",
26-
"ms-python.vscode-pylance",
27-
"ms-python.autopep8"
28-
]
29-
}
30-
}
31-
}
1+
{
2+
"name": "MaiBot-DevContainer",
3+
"build": {
4+
"dockerfile": "Dockerfile"
5+
},
6+
"features": {
7+
"ghcr.io/devcontainers/features/docker-outside-of-docker:1": {
8+
"moby": true,
9+
"installDockerBuildx": true,
10+
"installDockerComposeSwitch": true,
11+
"version": "latest",
12+
"dockerDashComposeVersion": "latest"
13+
}
14+
},
15+
// 同时转发 API 端口(8000)和 WebUI 面板端口(8001)
16+
"forwardPorts": [
17+
8000,
18+
8001
19+
],
20+
// 开发环境变量:对齐生产部署的必要 env 设定
21+
"containerEnv": {
22+
"MAIBOT_LOCALE": "zh-CN",
23+
"MAIBOT_LEGACY_0X_UPGRADE_CONFIRMED": "1",
24+
"TZ": "Asia/Shanghai",
25+
"EULA_AGREE": "1b662741904d7155d1ce1c00b3530d0d",
26+
"PRIVACY_AGREE": "9943b855e72199d0f5016ea39052f1b6"
27+
},
28+
// 将 .venv/bin 加入 PATH,对齐生产镜像的 ENV PATH="/MaiMBot/.venv/bin:${PATH}"
29+
// 清空从宿主机继承的 HTTP_PROXY,网络路由由 Docker 决定,与宿主机无关
30+
// COMPOSE_FILE 指定仅 devcontainer 内加载的覆盖文件,容器外 docker compose 不受影响
31+
"remoteEnv": {
32+
"PATH": "${containerWorkspaceFolder}/.venv/bin:${containerEnv:PATH}",
33+
"HTTP_PROXY": "",
34+
"HTTPS_PROXY": "",
35+
"COMPOSE_FILE": "docker-compose.yml:docker-compose.devcontainer.yml"
36+
},
37+
// 处理WSL/开发容器遗留的 safe.directory ;修复 Docker-outside-of-Docker 挂载路径;使用uv安装依赖
38+
"postCreateCommand": "git config --global --get-all safe.directory | grep -qx '${containerWorkspaceFolder}' || git config --global --add safe.directory ${containerWorkspaceFolder}; chmod +x ${containerWorkspaceFolder}/.devcontainer/setup-dood-override.sh && ${containerWorkspaceFolder}/.devcontainer/setup-dood-override.sh ${containerWorkspaceFolder}; uv sync",
39+
// 启动时重置 safe.directory ;修改 docker-config 权限,使得 WSL 和容器内用户都能访问修改
40+
"postStartCommand": "git config --global --unset-all safe.directory 2>/dev/null; git config --global --add safe.directory ${containerWorkspaceFolder}; sudo chmod -R a+rwX ${containerWorkspaceFolder}/docker-config ${containerWorkspaceFolder}/data 2>/dev/null || true",
41+
42+
"customizations": {
43+
"jetbrains": {
44+
"backend": "PyCharm"
45+
},
46+
// 配置VS Code插件和设置
47+
"vscode": {
48+
"extensions": [
49+
// 显式列出以在容器内安装和激活copilot和智能体所需workspace组件
50+
"github.copilot",
51+
"github.copilot-chat",
52+
// github.copilot-chat模型提供程序
53+
"vizards.deepseek-v4-for-copilot",
54+
"johnny-zhao.oai-compatible-copilot",
55+
56+
// 开发相关插件
57+
"tamasfe.even-better-toml",
58+
"njpwerner.autodocstring",
59+
"ms-python.python",
60+
"KevinRose.vsc-python-indent",
61+
"ms-python.vscode-pylance",
62+
"ms-python.autopep8",
63+
"charliermarsh.ruff"
64+
],
65+
"settings": {
66+
// 使用uv创建的虚拟环境
67+
"python.defaultInterpreterPath": "${workspaceFolder}/.venv/bin/python",
68+
"python.terminal.activateEnvironment": true,
69+
// Python文件使用ruff格式化、自动整理import
70+
"[python]": {
71+
"editor.defaultFormatter": "charliermarsh.ruff",
72+
"editor.formatOnSave": true,
73+
"editor.codeActionsOnSave": {
74+
"source.organizeImports": "explicit"
75+
}
76+
}
77+
}
78+
}
79+
}
80+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#!/bin/sh
2+
# ============================================================================
3+
# Docker-outside-of-Docker (DooD) bind mount 路径修正脚本
4+
# ============================================================================
5+
# 问题:VS Code devcontainer 将宿主机项目路径(如 /home/user/MaiBot)挂载到
6+
# 容器内的 ${containerWorkspaceFolder}。当 docker compose 在容器内执行时,
7+
# Docker Compose 将相对路径 ./ 解析为容器内路径,发送给宿主机 Docker 守护进程。
8+
# 守护进程在宿主机上找不到同名路径,自动创建空目录,导致数据"消失"。
9+
#
10+
# 解决:从 /proc/1/mountinfo 提取宿主机真实项目路径,生成 docker-compose.devcontainer.yml,
11+
# 将 bind mount 源路径改写为宿主机绝对路径。该文件仅在 devcontainer 内通过
12+
# COMPOSE_FILE 环境变量加载,容器外 docker compose 不受任何影响。
13+
#
14+
# 兼容性:devcontainer 始终运行 Linux,本脚本依赖 /proc/1/mountinfo(Linux 内核接口)。
15+
# Windows/macOS 宿主机的 Docker Desktop 会自动处理路径转换。
16+
# ============================================================================
17+
18+
set -eu
19+
20+
WORKSPACE_FOLDER="${1:-/workspaces/MaiBot}"
21+
OVERRIDE_FILE="${WORKSPACE_FOLDER}/docker-compose.devcontainer.yml"
22+
23+
# 从 /proc/1/mountinfo 提取宿主机上对应 workspace 的真实路径
24+
# mountinfo 格式: mount_id parent_id major:minor root mount_point options - fs_type source super_options
25+
# 我们需要第5列(mount_point)匹配 workspace,取第4列(root)为宿主机路径
26+
HOST_ROOT=$(awk -v ws="$WORKSPACE_FOLDER" '$5 == ws {print $4; exit}' /proc/1/mountinfo)
27+
28+
if [ -z "$HOST_ROOT" ]; then
29+
echo "[devcontainer] ⚠ 未能从 /proc/1/mountinfo 检测到 ${WORKSPACE_FOLDER} 的宿主机路径"
30+
echo "[devcontainer] docker compose 的 bind mount 可能指向错误位置,数据不会持久化"
31+
exit 0
32+
fi
33+
34+
echo "[devcontainer] 检测到宿主机项目路径: ${HOST_ROOT}"
35+
36+
# 生成 docker-compose.devcontainer.yml(通过 COMPOSE_FILE 加载)
37+
# 仅覆盖 volumes 配置,其余配置继承自 docker-compose.yml
38+
cat > "$OVERRIDE_FILE" << OVERRIDE_EOF
39+
# 此文件由 .devcontainer/setup-dood-override.sh 自动生成
40+
# 修复 Docker-outside-of-Docker 场景下 bind mount 的宿主机路径解析问题
41+
# 仅在 devcontainer 内通过 COMPOSE_FILE 环境变量加载,容器外 docker compose 不受影响
42+
# 请勿手动编辑,删除后将在下次容器创建时重新生成
43+
services:
44+
core:
45+
volumes:
46+
- ${HOST_ROOT}/docker-config/mmc:/MaiMBot/config
47+
- ${HOST_ROOT}/data/MaiMBot:/MaiMBot/data
48+
- ${HOST_ROOT}/data/MaiMBot/emoji:/data/emoji
49+
- ${HOST_ROOT}/data/MaiMBot/plugins:/MaiMBot/plugins
50+
- ${HOST_ROOT}/data/MaiMBot/logs:/MaiMBot/logs
51+
- ${HOST_ROOT}/depends-data:/MaiMBot/depends-data
52+
napcat:
53+
volumes:
54+
- ${HOST_ROOT}/docker-config/napcat:/app/napcat/config
55+
- ${HOST_ROOT}/data/qq:/app/.config/QQ
56+
- ${HOST_ROOT}/data/MaiMBot:/MaiMBot/data
57+
sqlite-web:
58+
volumes:
59+
- ${HOST_ROOT}/data/MaiMBot:/data/MaiMBot
60+
OVERRIDE_EOF
61+
62+
echo "[devcontainer] ✓ 已生成 ${OVERRIDE_FILE}"

0 commit comments

Comments
 (0)