chore: import private baseline from gitea state

This commit is contained in:
Losita
2026-05-11 19:24:06 +08:00
parent 161fc42c52
commit 1ba863d135
111 changed files with 10873 additions and 7347 deletions

View File

@@ -0,0 +1,21 @@
FROM python:3.13-slim
WORKDIR /MaiMBot
ENV MAIBOT_LEGACY_0X_UPGRADE_CONFIRMED=1
ENV PATH="/MaiMBot/.venv/bin:${PATH}"
COPY pyproject.toml uv.lock ./
RUN apt-get update && apt-get install -y --no-install-recommends git && rm -rf /var/lib/apt/lists/*
RUN pip install --no-cache-dir uv
RUN uv sync --frozen --no-dev --no-install-project
COPY . .
RUN chmod +x deploy/server-maibot/docker-entrypoint.offline.sh
EXPOSE 8001
ENTRYPOINT ["./deploy/server-maibot/docker-entrypoint.offline.sh"]

View File

@@ -0,0 +1,14 @@
ARG MAIBOT_BASE_IMAGE=maibot-offline:latest
FROM ${MAIBOT_BASE_IMAGE}
WORKDIR /MaiMBot
RUN find /MaiMBot -mindepth 1 -maxdepth 1 ! -name '.venv' -exec rm -rf {} +
COPY . .
RUN chmod +x deploy/server-maibot/docker-entrypoint.offline.sh
EXPOSE 8001
ENTRYPOINT ["./deploy/server-maibot/docker-entrypoint.offline.sh"]

View File

@@ -0,0 +1,41 @@
Server runtime directory: /root/maibot-offline
Release archive directory: /srv/maibot/releases
Repo-managed deployment files:
- deploy/server-maibot/Dockerfile.offline
- deploy/server-maibot/Dockerfile.release
- deploy/server-maibot/docker-entrypoint.offline.sh
- deploy/server-maibot/docker-compose.server.yml
- deploy/server-maibot/activate-release.sh
- deploy/server-maibot/bot.lecspace.com.nginx.conf
Persistent files that stay on the server and do not go into Git:
- /root/maibot-offline/docker-config/mmc/*
- /root/maibot-offline/docker-config/napcat/*
- /root/maibot-offline/data/*
- /root/maibot-offline/depends-data/*
- /root/maibot-offline/bot.lecspace.com.key
- /root/maibot-offline/bot.lecspace.com_bundle.pem
Gitea workflow:
- .gitea/workflows/release-offline.yml
Current pipeline mode:
- single-host release on the repo-level `build-host` runner
- clones from local Gitea HTTP on `127.0.0.1:3000`
- stages source into `/srv/maibot/releases/<commit>`
- builds `maibot-offline:<commit>` from the staged release using local base image `maibot-offline:latest`
- tags the same image back to `maibot-offline:latest`
- deploys from `/root/maibot-offline` with `docker compose up -d`
Optional environment overrides for the workflow runtime:
- `MAIBOT_RELEASE_ROOT`
- `MAIBOT_RUNTIME_ROOT`
- `MAIBOT_BASE_IMAGE`
No repository secrets are required for the default same-host pipeline.
Bootstrap note:
- `deploy/server-maibot/Dockerfile.offline` is only for the first bootstrap or for refreshing the runtime base image.
- The normal Gitea release pipeline uses `deploy/server-maibot/Dockerfile.release`, so it does not need Docker Hub or GitHub during each deploy.
- If `pyproject.toml` or `uv.lock` changes, refresh the local base image once before relying on the release pipeline again.

View File

@@ -0,0 +1,79 @@
#!/usr/bin/env bash
set -euo pipefail
release_dir="${1:?usage: activate-release.sh <release-dir>}"
runtime_root="${MAIBOT_RUNTIME_ROOT:-/root/maibot-offline}"
base_image="${MAIBOT_BASE_IMAGE:-maibot-offline:latest}"
case "$runtime_root" in
/root/maibot-offline|/root/maibot-offline/*) ;;
*)
echo "runtime root must stay under /root/maibot-offline" >&2
exit 1
;;
esac
if [ ! -d "$release_dir" ]; then
echo "release dir not found: $release_dir" >&2
exit 1
fi
if ! docker image inspect "$base_image" >/dev/null 2>&1; then
echo "base image not found locally: $base_image" >&2
echo "bootstrap it once with deploy/server-maibot/Dockerfile.offline before using the release pipeline" >&2
exit 1
fi
for dep_file in pyproject.toml uv.lock; do
if [ -f "$runtime_root/$dep_file" ] && ! cmp -s "$release_dir/$dep_file" "$runtime_root/$dep_file"; then
echo "dependency metadata changed: $dep_file" >&2
echo "refresh the local base image with deploy/server-maibot/Dockerfile.offline before using the release pipeline" >&2
exit 1
fi
done
release_id="$(basename "$release_dir")"
release_image="maibot-offline:${release_id}"
mkdir -p \
"$runtime_root" \
"$runtime_root/data/MaiMBot" \
"$runtime_root/data/MaiMBot/emoji" \
"$runtime_root/data/MaiMBot/plugins" \
"$runtime_root/data/MaiMBot/logs" \
"$runtime_root/data/qq" \
"$runtime_root/depends-data" \
"$runtime_root/docker-config/mmc" \
"$runtime_root/docker-config/napcat"
python3 - "$release_dir/deploy/server-maibot" "$runtime_root/deploy/server-maibot" <<'PY'
from pathlib import Path
import shutil
import sys
src = Path(sys.argv[1]).resolve()
dst = Path(sys.argv[2]).resolve()
if dst.exists():
shutil.rmtree(dst)
shutil.copytree(
src,
dst,
ignore=shutil.ignore_patterns("__pycache__", "*.pyc", "*.pyo"),
)
PY
docker build \
--build-arg "MAIBOT_BASE_IMAGE=${base_image}" \
-f "$release_dir/deploy/server-maibot/Dockerfile.release" \
-t "$release_image" \
"$release_dir"
docker tag "$release_image" maibot-offline:latest
cd "$runtime_root"
MAIBOT_CORE_IMAGE="$release_image" docker compose \
--project-name maibot-offline \
-f deploy/server-maibot/docker-compose.server.yml \
up -d

View File

@@ -0,0 +1,37 @@
server {
listen 80;
server_name bot.lecspace.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
http2 on;
server_name bot.lecspace.com;
resolver 127.0.0.11 ipv6=off valid=30s;
ssl_certificate /etc/nginx/certs/bot.lecspace.com_bundle.pem;
ssl_certificate_key /etc/nginx/certs/bot.lecspace.com.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
location / {
set $maibot_upstream http://maibot-core:8001;
proxy_pass $maibot_upstream;
proxy_http_version 1.1;
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_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port 443;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
proxy_buffering off;
proxy_cache off;
}
}

View File

@@ -0,0 +1,51 @@
services:
core:
container_name: maibot-core
image: ${MAIBOT_CORE_IMAGE:-maibot-offline:latest}
environment:
- TZ=Asia/Shanghai
- EULA_AGREE=1b662741904d7155d1ce1c00b3530d0d
- PRIVACY_AGREE=9943b855e72199d0f5016ea39052f1b6
- MAIBOT_LEGACY_0X_UPGRADE_CONFIRMED=1
- MAIBOT_STATISTICS_REPORT_PATH=/MaiMBot/data/maibot_statistics.html
ports:
- "18001:8001"
volumes:
- ../../docker-config/mmc:/MaiMBot/config
- ../../data/MaiMBot:/MaiMBot/data
- ../../data/MaiMBot/emoji:/data/emoji
- ../../data/MaiMBot/plugins:/MaiMBot/plugins
- ../../data/MaiMBot/logs:/MaiMBot/logs
- ../../depends-data:/MaiMBot/depends-data
restart: always
networks:
maibot_net: {}
smartflow-full_default:
aliases:
- maibot-core
napcat:
container_name: maibot-napcat
image: ${NAPCAT_IMAGE:-mlikiowa/napcat-docker:latest}
environment:
- NAPCAT_UID=1000
- NAPCAT_GID=1000
- TZ=Asia/Shanghai
volumes:
- ../../docker-config/napcat:/app/napcat/config
- ../../data/qq:/app/.config/QQ
- ../../data/MaiMBot:/MaiMBot/data
restart: always
networks:
maibot_net:
aliases:
- napcat
smartflow-full_default:
aliases:
- napcat
networks:
maibot_net:
driver: bridge
smartflow-full_default:
external: true

View File

@@ -0,0 +1,40 @@
#!/bin/sh
set -eu
ADAPTER_TEMPLATE="/MaiMBot/plugin-templates/MaiBot-Napcat-Adapter"
ADAPTER_TARGET="/MaiMBot/plugins/MaiBot-Napcat-Adapter"
CONFIG_DIR="/MaiMBot/config"
BOT_CONFIG_PATH="$CONFIG_DIR/bot_config.toml"
MODEL_CONFIG_PATH="$CONFIG_DIR/model_config.toml"
mkdir -p /MaiMBot/plugins
mkdir -p "$CONFIG_DIR"
if [ ! -e "$ADAPTER_TARGET" ] && [ -d "$ADAPTER_TEMPLATE" ]; then
cp -a "$ADAPTER_TEMPLATE" "$ADAPTER_TARGET"
fi
if [ ! -f "$BOT_CONFIG_PATH" ] || [ ! -f "$MODEL_CONFIG_PATH" ]; then
/MaiMBot/.venv/bin/python -c "from src.config.config import config_manager; print('config initialized')"
fi
if [ -f "$BOT_CONFIG_PATH" ]; then
/MaiMBot/.venv/bin/python - "$BOT_CONFIG_PATH" <<'PY'
import re
import sys
from pathlib import Path
path = Path(sys.argv[1])
content = path.read_text(encoding="utf-8")
updated = re.sub(
r'(^host\s*=\s*)"(127\.0\.0\.1|localhost)"',
r'\1"0.0.0.0"',
content,
flags=re.MULTILINE,
)
if updated != content:
path.write_text(updated, encoding="utf-8")
PY
fi
exec /MaiMBot/.venv/bin/python bot.py "$@"