chore: import private baseline from gitea state
This commit is contained in:
21
deploy/server-maibot/Dockerfile.offline
Normal file
21
deploy/server-maibot/Dockerfile.offline
Normal 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"]
|
||||
14
deploy/server-maibot/Dockerfile.release
Normal file
14
deploy/server-maibot/Dockerfile.release
Normal 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"]
|
||||
41
deploy/server-maibot/README_DEPLOY_STEPS.txt
Normal file
41
deploy/server-maibot/README_DEPLOY_STEPS.txt
Normal 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.
|
||||
79
deploy/server-maibot/activate-release.sh
Normal file
79
deploy/server-maibot/activate-release.sh
Normal 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
|
||||
37
deploy/server-maibot/bot.lecspace.com.nginx.conf
Normal file
37
deploy/server-maibot/bot.lecspace.com.nginx.conf
Normal 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;
|
||||
}
|
||||
}
|
||||
51
deploy/server-maibot/docker-compose.server.yml
Normal file
51
deploy/server-maibot/docker-compose.server.yml
Normal 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
|
||||
40
deploy/server-maibot/docker-entrypoint.offline.sh
Normal file
40
deploy/server-maibot/docker-entrypoint.offline.sh
Normal 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 "$@"
|
||||
Reference in New Issue
Block a user