{"id":821,"date":"2026-08-04T06:30:17","date_gmt":"2026-08-03T22:30:17","guid":{"rendered":"https:\/\/book.yuekegu.com\/index.php\/2026\/08\/04\/mathai-%e9%a2%98%e5%ba%93%e7%b3%bb%e7%bb%9f-windows%e9%83%a8%e7%bd%b2%e6%96%87%e6%a1%a3\/"},"modified":"2026-08-04T06:30:17","modified_gmt":"2026-08-03T22:30:17","slug":"mathai-%e9%a2%98%e5%ba%93%e7%b3%bb%e7%bb%9f-windows%e9%83%a8%e7%bd%b2%e6%96%87%e6%a1%a3","status":"publish","type":"post","link":"https:\/\/book.yuekegu.com\/index.php\/2026\/08\/04\/mathai-%e9%a2%98%e5%ba%93%e7%b3%bb%e7%bb%9f-windows%e9%83%a8%e7%bd%b2%e6%96%87%e6%a1%a3\/","title":{"rendered":"MathAI \u9898\u5e93\u7cfb\u7edf &#8211; Windows\u90e8\u7f72\u6587\u6863"},"content":{"rendered":"<h1 id=\"mathai-docker\">MathAI \u9898\u5e93\u7cfb\u7edf &#8211; \u975e Docker \u90e8\u7f72\u6307\u5357<\/h1>\n<h2 id=\"_1\">\u73af\u5883\u8981\u6c42<\/h2>\n<h3 id=\"_2\">\u540e\u7aef<\/h3>\n<ul>\n<li>Python 3.13+<\/li>\n<li>MySQL 8.0<\/li>\n<li>ChromaDB<\/li>\n<\/ul>\n<h3 id=\"_3\">\u524d\u7aef<\/h3>\n<ul>\n<li>Node.js 18+<\/li>\n<li>pnpm 9+<\/li>\n<\/ul>\n<h2 id=\"_4\">\u90e8\u7f72\u6b65\u9aa4<\/h2>\n<h3 id=\"1\">1. \u5b89\u88c5\u7cfb\u7edf\u4f9d\u8d56<\/h3>\n<div class=\"codehilite\">\n<pre><span><\/span><code><span class=\"c1\"># Ubuntu\/Debian<\/span>\nsudo<span class=\"w\"> <\/span>apt<span class=\"w\"> <\/span>update\nsudo<span class=\"w\"> <\/span>apt<span class=\"w\"> <\/span>install<span class=\"w\"> <\/span>-y<span class=\"w\"> <\/span>python3.13<span class=\"w\"> <\/span>python3.13-venv<span class=\"w\"> <\/span>python3-pip\nsudo<span class=\"w\"> <\/span>apt<span class=\"w\"> <\/span>install<span class=\"w\"> <\/span>-y<span class=\"w\"> <\/span>mysql-server\nsudo<span class=\"w\"> <\/span>apt<span class=\"w\"> <\/span>install<span class=\"w\"> <\/span>-y<span class=\"w\"> <\/span>nodejs<span class=\"w\"> <\/span>npm\n\n<span class=\"c1\"># CentOS\/RHEL<\/span>\nsudo<span class=\"w\"> <\/span>yum<span class=\"w\"> <\/span>install<span class=\"w\"> <\/span>-y<span class=\"w\"> <\/span>python3.13\nsudo<span class=\"w\"> <\/span>yum<span class=\"w\"> <\/span>install<span class=\"w\"> <\/span>-y<span class=\"w\"> <\/span>mysql-server\nsudo<span class=\"w\"> <\/span>yum<span class=\"w\"> <\/span>install<span class=\"w\"> <\/span>-y<span class=\"w\"> <\/span>nodejs<span class=\"w\"> <\/span>npm\n\n<span class=\"c1\"># \u5b89\u88c5 pnpm<\/span>\nnpm<span class=\"w\"> <\/span>install<span class=\"w\"> <\/span>-g<span class=\"w\"> <\/span>pnpm@9\n<\/code><\/pre>\n<\/div>\n<h3 id=\"2-mysql\">2. \u914d\u7f6e MySQL<\/h3>\n<div class=\"codehilite\">\n<pre><span><\/span><code><span class=\"c1\"># \u542f\u52a8 MySQL<\/span>\nsudo<span class=\"w\"> <\/span>systemctl<span class=\"w\"> <\/span>start<span class=\"w\"> <\/span>mysql\nsudo<span class=\"w\"> <\/span>systemctl<span class=\"w\"> <\/span><span class=\"nb\">enable<\/span><span class=\"w\"> <\/span>mysql\n\n<span class=\"c1\"># \u5b89\u5168\u914d\u7f6e<\/span>\nsudo<span class=\"w\"> <\/span>mysql_secure_installation\n\n<span class=\"c1\"># \u521b\u5efa\u6570\u636e\u5e93\u548c\u7528\u6237<\/span>\nsudo<span class=\"w\"> <\/span>mysql<span class=\"w\"> <\/span>-u<span class=\"w\"> <\/span>root<span class=\"w\"> <\/span>-p\n<\/code><\/pre>\n<\/div>\n<div class=\"codehilite\">\n<pre><span><\/span><code><span class=\"c1\">-- \u521b\u5efa\u6570\u636e\u5e93<\/span>\n<span class=\"k\">CREATE<\/span><span class=\"w\"> <\/span><span class=\"k\">DATABASE<\/span><span class=\"w\"> <\/span><span class=\"n\">question_bank<\/span><span class=\"w\"> <\/span><span class=\"nb\">CHARACTER<\/span><span class=\"w\"> <\/span><span class=\"k\">SET<\/span><span class=\"w\"> <\/span><span class=\"n\">utf8mb4<\/span><span class=\"w\"> <\/span><span class=\"k\">COLLATE<\/span><span class=\"w\"> <\/span><span class=\"n\">utf8mb4_unicode_ci<\/span><span class=\"p\">;<\/span>\n\n<span class=\"c1\">-- \u521b\u5efa\u7528\u6237<\/span>\n<span class=\"k\">CREATE<\/span><span class=\"w\"> <\/span><span class=\"k\">USER<\/span><span class=\"w\"> <\/span><span class=\"s1\">&#39;question_bank&#39;<\/span><span class=\"o\">@<\/span><span class=\"s1\">&#39;localhost&#39;<\/span><span class=\"w\"> <\/span><span class=\"n\">IDENTIFIED<\/span><span class=\"w\"> <\/span><span class=\"k\">BY<\/span><span class=\"w\"> <\/span><span class=\"s1\">&#39;your-strong-password&#39;<\/span><span class=\"p\">;<\/span>\n\n<span class=\"c1\">-- \u6388\u6743<\/span>\n<span class=\"k\">GRANT<\/span><span class=\"w\"> <\/span><span class=\"k\">ALL<\/span><span class=\"w\"> <\/span><span class=\"k\">PRIVILEGES<\/span><span class=\"w\"> <\/span><span class=\"k\">ON<\/span><span class=\"w\"> <\/span><span class=\"n\">question_bank<\/span><span class=\"p\">.<\/span><span class=\"o\">*<\/span><span class=\"w\"> <\/span><span class=\"k\">TO<\/span><span class=\"w\"> <\/span><span class=\"s1\">&#39;question_bank&#39;<\/span><span class=\"o\">@<\/span><span class=\"s1\">&#39;localhost&#39;<\/span><span class=\"p\">;<\/span>\n<span class=\"n\">FLUSH<\/span><span class=\"w\"> <\/span><span class=\"k\">PRIVILEGES<\/span><span class=\"p\">;<\/span>\n\n<span class=\"c1\">-- \u5bfc\u5165 yuekegu \u6570\u636e\u5e93\u7684 sq_knowledge \u548c sq_catalog \u8868<\/span>\n<span class=\"c1\">-- \u5148\u4ece yuekegu \u6570\u636e\u5e93\u5bfc\u51fa\u8868\u7ed3\u6784\u548c\u6570\u636e<\/span>\n<span class=\"n\">USE<\/span><span class=\"w\"> <\/span><span class=\"n\">yuekegu<\/span><span class=\"p\">;<\/span>\n<span class=\"k\">SHOW<\/span><span class=\"w\"> <\/span><span class=\"k\">CREATE<\/span><span class=\"w\"> <\/span><span class=\"k\">TABLE<\/span><span class=\"w\"> <\/span><span class=\"n\">sq_knowledge<\/span><span class=\"p\">;<\/span>\n<span class=\"k\">SHOW<\/span><span class=\"w\"> <\/span><span class=\"k\">CREATE<\/span><span class=\"w\"> <\/span><span class=\"k\">TABLE<\/span><span class=\"w\"> <\/span><span class=\"n\">sq_catalog<\/span><span class=\"p\">;<\/span>\n\n<span class=\"c1\">-- \u5728 question_bank \u6570\u636e\u5e93\u4e2d\u521b\u5efa\u8868<\/span>\n<span class=\"n\">USE<\/span><span class=\"w\"> <\/span><span class=\"n\">question_bank<\/span><span class=\"p\">;<\/span>\n<span class=\"c1\">-- \u6267\u884c\u8fc1\u79fb\u811a\u672c<\/span>\n<\/code><\/pre>\n<\/div>\n<h3 id=\"3\">3. \u90e8\u7f72\u540e\u7aef<\/h3>\n<div class=\"codehilite\">\n<pre><span><\/span><code><span class=\"c1\"># \u8fdb\u5165\u540e\u7aef\u76ee\u5f55<\/span>\n<span class=\"nb\">cd<\/span><span class=\"w\"> <\/span>\/path\/to\/question-bank\/source\/backend\n\n<span class=\"c1\"># \u521b\u5efa\u865a\u62df\u73af\u5883<\/span>\npython3.13<span class=\"w\"> <\/span>-m<span class=\"w\"> <\/span>venv<span class=\"w\"> <\/span>venv\n<span class=\"nb\">source<\/span><span class=\"w\"> <\/span>venv\/bin\/activate\n\n<span class=\"c1\"># \u5b89\u88c5\u4f9d\u8d56<\/span>\npip<span class=\"w\"> <\/span>install<span class=\"w\"> <\/span>-e<span class=\"w\"> <\/span>.\n\n<span class=\"c1\"># \u914d\u7f6e\u73af\u5883\u53d8\u91cf<\/span>\ncp<span class=\"w\"> <\/span>.env.example<span class=\"w\"> <\/span>.env\nnano<span class=\"w\"> <\/span>.env\n<\/code><\/pre>\n<\/div>\n<p><strong>\u4fee\u6539 .env \u6587\u4ef6\uff1a<\/strong><\/p>\n<div class=\"codehilite\">\n<pre><span><\/span><code><span class=\"c1\"># \u751f\u6210\u968f\u673a\u5bc6\u94a5<\/span>\n<span class=\"nv\">SECRET_KEY<\/span><span class=\"o\">=<\/span><span class=\"k\">$(<\/span>openssl<span class=\"w\"> <\/span>rand<span class=\"w\"> <\/span>-hex<span class=\"w\"> <\/span><span class=\"m\">32<\/span><span class=\"k\">)<\/span>\n\n<span class=\"c1\"># \u6570\u636e\u5e93\u914d\u7f6e<\/span>\n<span class=\"nv\">DB_URL<\/span><span class=\"o\">=<\/span>mysql+aiomysql:\/\/question_bank:your-strong-password@localhost:3306\/question_bank\n\n<span class=\"c1\"># ChromaDB \u914d\u7f6e<\/span>\n<span class=\"nv\">CHROMADB_HOST<\/span><span class=\"o\">=<\/span>localhost\n<span class=\"nv\">CHROMADB_PORT<\/span><span class=\"o\">=<\/span><span class=\"m\">8001<\/span>\n<\/code><\/pre>\n<\/div>\n<p><strong>\u8fd0\u884c\u6570\u636e\u5e93\u8fc1\u79fb\uff1a<\/strong><\/p>\n<div class=\"codehilite\">\n<pre><span><\/span><code><span class=\"c1\"># \u8fd0\u884c\u8fc1\u79fb<\/span>\npython<span class=\"w\"> <\/span>-m<span class=\"w\"> <\/span>alembic<span class=\"w\"> <\/span>upgrade<span class=\"w\"> <\/span>head\n\n<span class=\"c1\"># \u521d\u59cb\u5316\u6570\u636e<\/span>\npython<span class=\"w\"> <\/span>scripts\/initial_data.py\n\n<span class=\"c1\"># \u521b\u5efa\u7ba1\u7406\u5458<\/span>\npython<span class=\"w\"> <\/span>scripts\/create_superuser.py\n<\/code><\/pre>\n<\/div>\n<p><strong>\u542f\u52a8\u540e\u7aef\u670d\u52a1\uff1a<\/strong><\/p>\n<div class=\"codehilite\">\n<pre><span><\/span><code><span class=\"c1\"># \u4f7f\u7528 systemd \u7ba1\u7406\u540e\u7aef\u670d\u52a1<\/span>\nsudo<span class=\"w\"> <\/span>nano<span class=\"w\"> <\/span>\/etc\/systemd\/system\/question-bank-backend.service\n<\/code><\/pre>\n<\/div>\n<div class=\"codehilite\">\n<pre><span><\/span><code><span class=\"k\">[Unit]<\/span>\n<span class=\"na\">Description<\/span><span class=\"o\">=<\/span><span class=\"s\">Question Bank Backend API<\/span>\n<span class=\"na\">After<\/span><span class=\"o\">=<\/span><span class=\"s\">network.target mysql.service<\/span>\n\n<span class=\"k\">[Service]<\/span>\n<span class=\"na\">Type<\/span><span class=\"o\">=<\/span><span class=\"s\">simple<\/span>\n<span class=\"na\">User<\/span><span class=\"o\">=<\/span><span class=\"s\">www-data<\/span>\n<span class=\"na\">Group<\/span><span class=\"o\">=<\/span><span class=\"s\">www-data<\/span>\n<span class=\"na\">WorkingDirectory<\/span><span class=\"o\">=<\/span><span class=\"s\">\/path\/to\/question-bank\/source\/backend<\/span>\n<span class=\"na\">Environment<\/span><span class=\"o\">=<\/span><span class=\"s\">&quot;PATH=\/path\/to\/question-bank\/source\/backend\/venv\/bin&quot;<\/span>\n<span class=\"na\">ExecStart<\/span><span class=\"o\">=<\/span><span class=\"s\">\/path\/to\/question-bank\/source\/backend\/venv\/bin\/uvicorn app.main:app --host 0.0.0.0 --port 8000<\/span>\n<span class=\"na\">Restart<\/span><span class=\"o\">=<\/span><span class=\"s\">always<\/span>\n<span class=\"na\">RestartSec<\/span><span class=\"o\">=<\/span><span class=\"s\">10<\/span>\n\n<span class=\"k\">[Install]<\/span>\n<span class=\"na\">WantedBy<\/span><span class=\"o\">=<\/span><span class=\"s\">multi-user.target<\/span>\n<\/code><\/pre>\n<\/div>\n<div class=\"codehilite\">\n<pre><span><\/span><code><span class=\"c1\"># \u542f\u52a8\u670d\u52a1<\/span>\nsudo<span class=\"w\"> <\/span>systemctl<span class=\"w\"> <\/span>daemon-reload\nsudo<span class=\"w\"> <\/span>systemctl<span class=\"w\"> <\/span>start<span class=\"w\"> <\/span>question-bank-backend\nsudo<span class=\"w\"> <\/span>systemctl<span class=\"w\"> <\/span><span class=\"nb\">enable<\/span><span class=\"w\"> <\/span>question-bank-backend\n\n<span class=\"c1\"># \u67e5\u770b\u72b6\u6001<\/span>\nsudo<span class=\"w\"> <\/span>systemctl<span class=\"w\"> <\/span>status<span class=\"w\"> <\/span>question-bank-backend\n<\/code><\/pre>\n<\/div>\n<p><strong>\u542f\u52a8 Worker \u670d\u52a1\uff1a<\/strong><\/p>\n<div class=\"codehilite\">\n<pre><span><\/span><code><span class=\"c1\"># \u521b\u5efa Worker \u670d\u52a1<\/span>\nsudo<span class=\"w\"> <\/span>nano<span class=\"w\"> <\/span>\/etc\/systemd\/system\/question-bank-worker.service\n<\/code><\/pre>\n<\/div>\n<div class=\"codehilite\">\n<pre><span><\/span><code><span class=\"k\">[Unit]<\/span>\n<span class=\"na\">Description<\/span><span class=\"o\">=<\/span><span class=\"s\">Question Bank Celery Worker<\/span>\n<span class=\"na\">After<\/span><span class=\"o\">=<\/span><span class=\"s\">network.target mysql.service<\/span>\n\n<span class=\"k\">[Service]<\/span>\n<span class=\"na\">Type<\/span><span class=\"o\">=<\/span><span class=\"s\">simple<\/span>\n<span class=\"na\">User<\/span><span class=\"o\">=<\/span><span class=\"s\">www-data<\/span>\n<span class=\"na\">Group<\/span><span class=\"o\">=<\/span><span class=\"s\">www-data<\/span>\n<span class=\"na\">WorkingDirectory<\/span><span class=\"o\">=<\/span><span class=\"s\">\/path\/to\/question-bank\/source\/backend<\/span>\n<span class=\"na\">Environment<\/span><span class=\"o\">=<\/span><span class=\"s\">&quot;PATH=\/path\/to\/question-bank\/source\/backend\/venv\/bin&quot;<\/span>\n<span class=\"na\">ExecStart<\/span><span class=\"o\">=<\/span><span class=\"s\">\/path\/to\/question-bank\/source\/backend\/venv\/bin\/python -m app.worker<\/span>\n<span class=\"na\">Restart<\/span><span class=\"o\">=<\/span><span class=\"s\">always<\/span>\n<span class=\"na\">RestartSec<\/span><span class=\"o\">=<\/span><span class=\"s\">10<\/span>\n\n<span class=\"k\">[Install]<\/span>\n<span class=\"na\">WantedBy<\/span><span class=\"o\">=<\/span><span class=\"s\">multi-user.target<\/span>\n<\/code><\/pre>\n<\/div>\n<div class=\"codehilite\">\n<pre><span><\/span><code><span class=\"c1\"># \u542f\u52a8 Worker<\/span>\nsudo<span class=\"w\"> <\/span>systemctl<span class=\"w\"> <\/span>daemon-reload\nsudo<span class=\"w\"> <\/span>systemctl<span class=\"w\"> <\/span>start<span class=\"w\"> <\/span>question-bank-worker\nsudo<span class=\"w\"> <\/span>systemctl<span class=\"w\"> <\/span><span class=\"nb\">enable<\/span><span class=\"w\"> <\/span>question-bank-worker\n<\/code><\/pre>\n<\/div>\n<h3 id=\"4\">4. \u90e8\u7f72\u524d\u7aef<\/h3>\n<div class=\"codehilite\">\n<pre><span><\/span><code><span class=\"c1\"># \u8fdb\u5165\u524d\u7aef\u76ee\u5f55<\/span>\n<span class=\"nb\">cd<\/span><span class=\"w\"> <\/span>\/path\/to\/question-bank\/source\/frontend\n\n<span class=\"c1\"># \u5b89\u88c5\u4f9d\u8d56<\/span>\npnpm<span class=\"w\"> <\/span>install\n\n<span class=\"c1\"># \u6784\u5efa\u751f\u4ea7\u7248\u672c<\/span>\npnpm<span class=\"w\"> <\/span>build\n\n<span class=\"c1\"># \u90e8\u7f72\u5230 Nginx \u76ee\u5f55<\/span>\nsudo<span class=\"w\"> <\/span>cp<span class=\"w\"> <\/span>-r<span class=\"w\"> <\/span>.output\/public\/*<span class=\"w\"> <\/span>\/var\/www\/question-bank\/\n<\/code><\/pre>\n<\/div>\n<h3 id=\"5-nginx\">5. \u914d\u7f6e Nginx<\/h3>\n<div class=\"codehilite\">\n<pre><span><\/span><code><span class=\"c1\"># \u5b89\u88c5 Nginx<\/span>\nsudo<span class=\"w\"> <\/span>apt<span class=\"w\"> <\/span>install<span class=\"w\"> <\/span>-y<span class=\"w\"> <\/span>nginx\n\n<span class=\"c1\"># \u521b\u5efa Nginx \u914d\u7f6e<\/span>\nsudo<span class=\"w\"> <\/span>nano<span class=\"w\"> <\/span>\/etc\/nginx\/sites-available\/question-bank\n<\/code><\/pre>\n<\/div>\n<div class=\"codehilite\">\n<pre><span><\/span><code><span class=\"k\">server<\/span><span class=\"w\"> <\/span><span class=\"p\">{<\/span>\n<span class=\"w\">    <\/span><span class=\"kn\">listen<\/span><span class=\"w\"> <\/span><span class=\"mi\">80<\/span><span class=\"p\">;<\/span>\n<span class=\"w\">    <\/span><span class=\"kn\">server_name<\/span><span class=\"w\"> <\/span><span class=\"s\">mathai.yuekegu.com<\/span><span class=\"p\">;<\/span>\n\n<span class=\"w\">    <\/span><span class=\"c1\"># \u524d\u7aef\u9759\u6001\u6587\u4ef6<\/span>\n<span class=\"w\">    <\/span><span class=\"kn\">location<\/span><span class=\"w\"> <\/span><span class=\"s\">\/<\/span><span class=\"w\"> <\/span><span class=\"p\">{<\/span>\n<span class=\"w\">        <\/span><span class=\"kn\">root<\/span><span class=\"w\"> <\/span><span class=\"s\">\/var\/www\/question-bank<\/span><span class=\"p\">;<\/span>\n<span class=\"w\">        <\/span><span class=\"kn\">index<\/span><span class=\"w\"> <\/span><span class=\"s\">index.html<\/span><span class=\"p\">;<\/span>\n<span class=\"w\">        <\/span><span class=\"kn\">try_files<\/span><span class=\"w\"> <\/span><span class=\"nv\">$uri<\/span><span class=\"w\"> <\/span><span class=\"nv\">$uri\/<\/span><span class=\"w\"> <\/span><span class=\"s\">\/index.html<\/span><span class=\"p\">;<\/span>\n<span class=\"w\">    <\/span><span class=\"p\">}<\/span>\n\n<span class=\"w\">    <\/span><span class=\"c1\"># \u540e\u7aef API \u4ee3\u7406<\/span>\n<span class=\"w\">    <\/span><span class=\"kn\">location<\/span><span class=\"w\"> <\/span><span class=\"s\">\/api\/<\/span><span class=\"w\"> <\/span><span class=\"p\">{<\/span>\n<span class=\"w\">        <\/span><span class=\"kn\">proxy_pass<\/span><span class=\"w\"> <\/span><span class=\"s\">http:\/\/127.0.0.1:8000<\/span><span class=\"p\">;<\/span>\n<span class=\"w\">        <\/span><span class=\"kn\">proxy_set_header<\/span><span class=\"w\"> <\/span><span class=\"s\">Host<\/span><span class=\"w\"> <\/span><span class=\"nv\">$http_host<\/span><span class=\"p\">;<\/span>\n<span class=\"w\">        <\/span><span class=\"kn\">proxy_set_header<\/span><span class=\"w\"> <\/span><span class=\"s\">X-Real-IP<\/span><span class=\"w\"> <\/span><span class=\"nv\">$remote_addr<\/span><span class=\"p\">;<\/span>\n<span class=\"w\">        <\/span><span class=\"kn\">proxy_set_header<\/span><span class=\"w\"> <\/span><span class=\"s\">X-Forwarded-For<\/span><span class=\"w\"> <\/span><span class=\"nv\">$proxy_add_x_forwarded_for<\/span><span class=\"p\">;<\/span>\n<span class=\"w\">        <\/span><span class=\"kn\">proxy_set_header<\/span><span class=\"w\"> <\/span><span class=\"s\">X-Forwarded-Proto<\/span><span class=\"w\"> <\/span><span class=\"nv\">$scheme<\/span><span class=\"p\">;<\/span>\n<span class=\"w\">        <\/span><span class=\"kn\">proxy_connect_timeout<\/span><span class=\"w\"> <\/span><span class=\"s\">60s<\/span><span class=\"p\">;<\/span>\n<span class=\"w\">        <\/span><span class=\"kn\">proxy_send_timeout<\/span><span class=\"w\"> <\/span><span class=\"s\">600s<\/span><span class=\"p\">;<\/span>\n<span class=\"w\">        <\/span><span class=\"kn\">proxy_read_timeout<\/span><span class=\"w\"> <\/span><span class=\"s\">600s<\/span><span class=\"p\">;<\/span>\n<span class=\"w\">    <\/span><span class=\"p\">}<\/span>\n\n<span class=\"w\">    <\/span><span class=\"c1\"># WebSocket \u652f\u6301<\/span>\n<span class=\"w\">    <\/span><span class=\"kn\">location<\/span><span class=\"w\"> <\/span><span class=\"s\">\/api\/ws\/<\/span><span class=\"w\"> <\/span><span class=\"p\">{<\/span>\n<span class=\"w\">        <\/span><span class=\"kn\">proxy_pass<\/span><span class=\"w\"> <\/span><span class=\"s\">http:\/\/127.0.0.1:8000<\/span><span class=\"p\">;<\/span>\n<span class=\"w\">        <\/span><span class=\"kn\">proxy_http_version<\/span><span class=\"w\"> <\/span><span class=\"mi\">1<\/span><span class=\"s\">.1<\/span><span class=\"p\">;<\/span>\n<span class=\"w\">        <\/span><span class=\"kn\">proxy_set_header<\/span><span class=\"w\"> <\/span><span class=\"s\">Upgrade<\/span><span class=\"w\"> <\/span><span class=\"nv\">$http_upgrade<\/span><span class=\"p\">;<\/span>\n<span class=\"w\">        <\/span><span class=\"kn\">proxy_set_header<\/span><span class=\"w\"> <\/span><span class=\"s\">Connection<\/span><span class=\"w\"> <\/span><span class=\"s\">&quot;upgrade&quot;<\/span><span class=\"p\">;<\/span>\n<span class=\"w\">        <\/span><span class=\"kn\">proxy_set_header<\/span><span class=\"w\"> <\/span><span class=\"s\">Host<\/span><span class=\"w\"> <\/span><span class=\"nv\">$http_host<\/span><span class=\"p\">;<\/span>\n<span class=\"w\">        <\/span><span class=\"kn\">proxy_set_header<\/span><span class=\"w\"> <\/span><span class=\"s\">X-Real-IP<\/span><span class=\"w\"> <\/span><span class=\"nv\">$remote_addr<\/span><span class=\"p\">;<\/span>\n<span class=\"w\">    <\/span><span class=\"p\">}<\/span>\n\n<span class=\"w\">    <\/span><span class=\"c1\"># \u7981\u6b62\u8bbf\u95ee\u654f\u611f\u6587\u4ef6<\/span>\n<span class=\"w\">    <\/span><span class=\"kn\">location<\/span><span class=\"w\"> <\/span><span class=\"p\">~<\/span><span class=\"w\"> <\/span><span class=\"sr\">^\/(\\.env|\\.git|\\.svn)<\/span><span class=\"w\"> <\/span><span class=\"p\">{<\/span>\n<span class=\"w\">        <\/span><span class=\"kn\">return<\/span><span class=\"w\"> <\/span><span class=\"mi\">404<\/span><span class=\"p\">;<\/span>\n<span class=\"w\">    <\/span><span class=\"p\">}<\/span>\n\n<span class=\"w\">    <\/span><span class=\"c1\"># \u65e5\u5fd7<\/span>\n<span class=\"w\">    <\/span><span class=\"kn\">access_log<\/span><span class=\"w\"> <\/span><span class=\"s\">\/var\/log\/nginx\/question-bank.access.log<\/span><span class=\"p\">;<\/span>\n<span class=\"w\">    <\/span><span class=\"kn\">error_log<\/span><span class=\"w\"> <\/span><span class=\"s\">\/var\/log\/nginx\/question-bank.error.log<\/span><span class=\"p\">;<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre>\n<\/div>\n<div class=\"codehilite\">\n<pre><span><\/span><code><span class=\"c1\"># \u542f\u7528\u7ad9\u70b9<\/span>\nsudo<span class=\"w\"> <\/span>ln<span class=\"w\"> <\/span>-s<span class=\"w\"> <\/span>\/etc\/nginx\/sites-available\/question-bank<span class=\"w\"> <\/span>\/etc\/nginx\/sites-enabled\/\nsudo<span class=\"w\"> <\/span>nginx<span class=\"w\"> <\/span>-t\nsudo<span class=\"w\"> <\/span>systemctl<span class=\"w\"> <\/span>reload<span class=\"w\"> <\/span>nginx\n<\/code><\/pre>\n<\/div>\n<h3 id=\"6-ssl\">6. \u914d\u7f6e SSL (\u53ef\u9009)<\/h3>\n<div class=\"codehilite\">\n<pre><span><\/span><code><span class=\"c1\"># \u5b89\u88c5 Certbot<\/span>\nsudo<span class=\"w\"> <\/span>apt<span class=\"w\"> <\/span>install<span class=\"w\"> <\/span>-y<span class=\"w\"> <\/span>certbot<span class=\"w\"> <\/span>python3-certbot-nginx\n\n<span class=\"c1\"># \u7533\u8bf7\u8bc1\u4e66<\/span>\nsudo<span class=\"w\"> <\/span>certbot<span class=\"w\"> <\/span>--nginx<span class=\"w\"> <\/span>-d<span class=\"w\"> <\/span>mathai.yuekegu.com\n\n<span class=\"c1\"># \u81ea\u52a8\u7eed\u671f<\/span>\nsudo<span class=\"w\"> <\/span>crontab<span class=\"w\"> <\/span>-e\n<span class=\"c1\"># \u6dfb\u52a0: 0 12 * * * \/usr\/bin\/certbot renew --quiet<\/span>\n<\/code><\/pre>\n<\/div>\n<h3 id=\"7-chromadb\">7. \u914d\u7f6e ChromaDB<\/h3>\n<div class=\"codehilite\">\n<pre><span><\/span><code><span class=\"c1\"># \u4e0b\u8f7d ChromaDB<\/span>\npip<span class=\"w\"> <\/span>install<span class=\"w\"> <\/span>chromadb\n\n<span class=\"c1\"># \u542f\u52a8 ChromaDB \u670d\u52a1<\/span>\nchroma<span class=\"w\"> <\/span>run<span class=\"w\"> <\/span>--host<span class=\"w\"> <\/span><span class=\"m\">0<\/span>.0.0.0<span class=\"w\"> <\/span>--port<span class=\"w\"> <\/span><span class=\"m\">8001<\/span><span class=\"w\"> <\/span>--path<span class=\"w\"> <\/span>\/var\/lib\/chromadb\n\n<span class=\"c1\"># \u4f7f\u7528 systemd \u7ba1\u7406<\/span>\nsudo<span class=\"w\"> <\/span>nano<span class=\"w\"> <\/span>\/etc\/systemd\/system\/chromadb.service\n<\/code><\/pre>\n<\/div>\n<div class=\"codehilite\">\n<pre><span><\/span><code><span class=\"k\">[Unit]<\/span>\n<span class=\"na\">Description<\/span><span class=\"o\">=<\/span><span class=\"s\">ChromaDB Vector Database<\/span>\n<span class=\"na\">After<\/span><span class=\"o\">=<\/span><span class=\"s\">network.target<\/span>\n\n<span class=\"k\">[Service]<\/span>\n<span class=\"na\">Type<\/span><span class=\"o\">=<\/span><span class=\"s\">simple<\/span>\n<span class=\"na\">User<\/span><span class=\"o\">=<\/span><span class=\"s\">www-data<\/span>\n<span class=\"na\">Group<\/span><span class=\"o\">=<\/span><span class=\"s\">www-data<\/span>\n<span class=\"na\">ExecStart<\/span><span class=\"o\">=<\/span><span class=\"s\">\/path\/to\/question-bank\/source\/backend\/venv\/bin\/chroma run --host 0.0.0.0 --port 8001 --path \/var\/lib\/chromadb<\/span>\n<span class=\"na\">Restart<\/span><span class=\"o\">=<\/span><span class=\"s\">always<\/span>\n<span class=\"na\">RestartSec<\/span><span class=\"o\">=<\/span><span class=\"s\">10<\/span>\n\n<span class=\"k\">[Install]<\/span>\n<span class=\"na\">WantedBy<\/span><span class=\"o\">=<\/span><span class=\"s\">multi-user.target<\/span>\n<\/code><\/pre>\n<\/div>\n<div class=\"codehilite\">\n<pre><span><\/span><code>sudo<span class=\"w\"> <\/span>systemctl<span class=\"w\"> <\/span>daemon-reload\nsudo<span class=\"w\"> <\/span>systemctl<span class=\"w\"> <\/span>start<span class=\"w\"> <\/span>chromadb\nsudo<span class=\"w\"> <\/span>systemctl<span class=\"w\"> <\/span><span class=\"nb\">enable<\/span><span class=\"w\"> <\/span>chromadb\n<\/code><\/pre>\n<\/div>\n<h2 id=\"_5\">\u9a8c\u8bc1\u90e8\u7f72<\/h2>\n<div class=\"codehilite\">\n<pre><span><\/span><code><span class=\"c1\"># \u68c0\u67e5\u540e\u7aef<\/span>\ncurl<span class=\"w\"> <\/span>http:\/\/localhost:8000\/docs\n\n<span class=\"c1\"># \u68c0\u67e5\u524d\u7aef<\/span>\ncurl<span class=\"w\"> <\/span>http:\/\/localhost\n\n<span class=\"c1\"># \u68c0\u67e5\u6570\u636e\u5e93<\/span>\nmysql<span class=\"w\"> <\/span>-u<span class=\"w\"> <\/span>question_bank<span class=\"w\"> <\/span>-p<span class=\"w\"> <\/span>-e<span class=\"w\"> <\/span><span class=\"s2\">&quot;USE question_bank; SHOW TABLES;&quot;<\/span>\n\n<span class=\"c1\"># \u68c0\u67e5\u670d\u52a1\u72b6\u6001<\/span>\nsudo<span class=\"w\"> <\/span>systemctl<span class=\"w\"> <\/span>status<span class=\"w\"> <\/span>question-bank-backend\nsudo<span class=\"w\"> <\/span>systemctl<span class=\"w\"> <\/span>status<span class=\"w\"> <\/span>question-bank-worker\nsudo<span class=\"w\"> <\/span>systemctl<span class=\"w\"> <\/span>status<span class=\"w\"> <\/span>chromadb\nsudo<span class=\"w\"> <\/span>systemctl<span class=\"w\"> <\/span>status<span class=\"w\"> <\/span>mysql\nsudo<span class=\"w\"> <\/span>systemctl<span class=\"w\"> <\/span>status<span class=\"w\"> <\/span>nginx\n<\/code><\/pre>\n<\/div>\n<h2 id=\"_6\">\u5e38\u7528\u547d\u4ee4<\/h2>\n<div class=\"codehilite\">\n<pre><span><\/span><code><span class=\"c1\"># \u91cd\u542f\u6240\u6709\u670d\u52a1<\/span>\nsudo<span class=\"w\"> <\/span>systemctl<span class=\"w\"> <\/span>restart<span class=\"w\"> <\/span>question-bank-backend\nsudo<span class=\"w\"> <\/span>systemctl<span class=\"w\"> <\/span>restart<span class=\"w\"> <\/span>question-bank-worker\nsudo<span class=\"w\"> <\/span>systemctl<span class=\"w\"> <\/span>restart<span class=\"w\"> <\/span>chromadb\nsudo<span class=\"w\"> <\/span>systemctl<span class=\"w\"> <\/span>restart<span class=\"w\"> <\/span>mysql\nsudo<span class=\"w\"> <\/span>systemctl<span class=\"w\"> <\/span>restart<span class=\"w\"> <\/span>nginx\n\n<span class=\"c1\"># \u67e5\u770b\u65e5\u5fd7<\/span>\nsudo<span class=\"w\"> <\/span>journalctl<span class=\"w\"> <\/span>-u<span class=\"w\"> <\/span>question-bank-backend<span class=\"w\"> <\/span>-f\nsudo<span class=\"w\"> <\/span>journalctl<span class=\"w\"> <\/span>-u<span class=\"w\"> <\/span>question-bank-worker<span class=\"w\"> <\/span>-f\n\n<span class=\"c1\"># \u5907\u4efd\u6570\u636e\u5e93<\/span>\nmysqldump<span class=\"w\"> <\/span>-u<span class=\"w\"> <\/span>question_bank<span class=\"w\"> <\/span>-p<span class=\"w\"> <\/span>question_bank<span class=\"w\"> <\/span>&gt;<span class=\"w\"> <\/span>backup_<span class=\"k\">$(<\/span>date<span class=\"w\"> <\/span>+%Y%m%d<span class=\"k\">)<\/span>.sql\n\n<span class=\"c1\"># \u6062\u590d\u6570\u636e\u5e93<\/span>\nmysql<span class=\"w\"> <\/span>-u<span class=\"w\"> <\/span>question_bank<span class=\"w\"> <\/span>-p<span class=\"w\"> <\/span>question_bank<span class=\"w\"> <\/span>&lt;<span class=\"w\"> <\/span>backup.sql\n<\/code><\/pre>\n<\/div>\n<h2 id=\"_7\">\u6545\u969c\u6392\u67e5<\/h2>\n<h3 id=\"1_1\">1. \u540e\u7aef\u65e0\u6cd5\u542f\u52a8<\/h3>\n<div class=\"codehilite\">\n<pre><span><\/span><code><span class=\"c1\"># \u68c0\u67e5\u65e5\u5fd7<\/span>\nsudo<span class=\"w\"> <\/span>journalctl<span class=\"w\"> <\/span>-u<span class=\"w\"> <\/span>question-bank-backend<span class=\"w\"> <\/span>-n<span class=\"w\"> <\/span><span class=\"m\">100<\/span>\n\n<span class=\"c1\"># \u68c0\u67e5\u7aef\u53e3\u5360\u7528<\/span>\nnetstat<span class=\"w\"> <\/span>-tlnp<span class=\"w\"> <\/span><span class=\"p\">|<\/span><span class=\"w\"> <\/span>grep<span class=\"w\"> <\/span><span class=\"m\">8000<\/span>\n\n<span class=\"c1\"># \u68c0\u67e5 MySQL \u8fde\u63a5<\/span>\nmysql<span class=\"w\"> <\/span>-u<span class=\"w\"> <\/span>question_bank<span class=\"w\"> <\/span>-p<span class=\"w\"> <\/span>-e<span class=\"w\"> <\/span><span class=\"s2\">&quot;SELECT 1&quot;<\/span>\n<\/code><\/pre>\n<\/div>\n<h3 id=\"2\">2. \u524d\u7aef\u65e0\u6cd5\u8bbf\u95ee<\/h3>\n<div class=\"codehilite\">\n<pre><span><\/span><code><span class=\"c1\"># \u68c0\u67e5 Nginx \u72b6\u6001<\/span>\nsudo<span class=\"w\"> <\/span>systemctl<span class=\"w\"> <\/span>status<span class=\"w\"> <\/span>nginx\n\n<span class=\"c1\"># \u68c0\u67e5 Nginx \u914d\u7f6e<\/span>\nsudo<span class=\"w\"> <\/span>nginx<span class=\"w\"> <\/span>-t\n\n<span class=\"c1\"># \u68c0\u67e5\u9759\u6001\u6587\u4ef6<\/span>\nls<span class=\"w\"> <\/span>-la<span class=\"w\"> <\/span>\/var\/www\/question-bank\/\n<\/code><\/pre>\n<\/div>\n<h3 id=\"3_1\">3. \u6570\u636e\u5e93\u8fde\u63a5\u5931\u8d25<\/h3>\n<div class=\"codehilite\">\n<pre><span><\/span><code><span class=\"c1\"># \u68c0\u67e5 MySQL \u72b6\u6001<\/span>\nsudo<span class=\"w\"> <\/span>systemctl<span class=\"w\"> <\/span>status<span class=\"w\"> <\/span>mysql\n\n<span class=\"c1\"># \u68c0\u67e5\u7528\u6237\u6743\u9650<\/span>\nmysql<span class=\"w\"> <\/span>-u<span class=\"w\"> <\/span>root<span class=\"w\"> <\/span>-p<span class=\"w\"> <\/span>-e<span class=\"w\"> <\/span><span class=\"s2\">&quot;SELECT User, Host FROM mysql.user;&quot;<\/span>\n<\/code><\/pre>\n<\/div>\n<h2 id=\"_8\">\u751f\u4ea7\u73af\u5883\u5efa\u8bae<\/h2>\n<ol>\n<li><strong>\u5b89\u5168\u914d\u7f6e<\/strong><\/li>\n<li>\u4f7f\u7528\u9632\u706b\u5899\u9650\u5236\u8bbf\u95ee<\/li>\n<li>\u5b9a\u671f\u66f4\u65b0\u7cfb\u7edf\u548c\u4f9d\u8d56<\/li>\n<li>\n<p>\u4f7f\u7528\u5f3a\u5bc6\u7801<\/p>\n<\/li>\n<li>\n<p><strong>\u6027\u80fd\u4f18\u5316<\/strong><\/p>\n<\/li>\n<li>\u914d\u7f6e MySQL \u7f13\u5b58<\/li>\n<li>\u542f\u7528 Nginx \u7f13\u5b58<\/li>\n<li>\n<p>\u4f7f\u7528 CDN<\/p>\n<\/li>\n<li>\n<p><strong>\u76d1\u63a7<\/strong><\/p>\n<\/li>\n<li>\u914d\u7f6e\u65e5\u5fd7\u76d1\u63a7<\/li>\n<li>\u76d1\u63a7\u670d\u52a1\u72b6\u6001<\/li>\n<li>\n<p>\u76d1\u63a7\u78c1\u76d8\u7a7a\u95f4<\/p>\n<\/li>\n<li>\n<p><strong>\u5907\u4efd<\/strong><\/p>\n<\/li>\n<li>\u5b9a\u671f\u5907\u4efd\u6570\u636e\u5e93<\/li>\n<li>\u5907\u4efd\u4e0a\u4f20\u6587\u4ef6<\/li>\n<li>\u6d4b\u8bd5\u6062\u590d\u6d41\u7a0b<\/li>\n<\/ol>\n","protected":false},"excerpt":{"rendered":"<p>MathAI \u9898\u5e93\u7cfb\u7edf &#8211; \u975e Docker \u90e8\u7f72\u6307\u5357 \u73af\u5883\u8981\u6c42 \u540e\u7aef  [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[70],"tags":[],"class_list":["post-821","post","type-post","status-publish","format-standard","hentry","category-mathai"],"_links":{"self":[{"href":"https:\/\/book.yuekegu.com\/index.php\/wp-json\/wp\/v2\/posts\/821","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/book.yuekegu.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/book.yuekegu.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/book.yuekegu.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/book.yuekegu.com\/index.php\/wp-json\/wp\/v2\/comments?post=821"}],"version-history":[{"count":0,"href":"https:\/\/book.yuekegu.com\/index.php\/wp-json\/wp\/v2\/posts\/821\/revisions"}],"wp:attachment":[{"href":"https:\/\/book.yuekegu.com\/index.php\/wp-json\/wp\/v2\/media?parent=821"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/book.yuekegu.com\/index.php\/wp-json\/wp\/v2\/categories?post=821"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/book.yuekegu.com\/index.php\/wp-json\/wp\/v2\/tags?post=821"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}