标签 1Panel 下的文章

记一次 Emlog Docker 部署后全站 404 的排查与解决

分类:建站运维 · 标签:Emlog、Docker、1Panel、伪静态、Apache

最近用 Docker 在服务器上部署了一个 Emlog 博客,配合 1Panel 面板和 OpenResty 反向代理。容器跑起来之后,访问首页直接返回一个 Apache 的 404 页面:

Not Found
The requested URL was not found on this server.
Apache/2.4.54 (Debian) Server at www.你的域名 Port 80

奇怪的是,容器明明是运行状态,数据库也连上了,但就是打不开。折腾了一番才找到根因,这里把完整的排查思路和解决方法记录下来,给遇到同样问题的朋友一个参考。

一、我的部署环境

先交代一下环境,方便对照:

  • 博客程序:Emlog Pro(Docker 容器部署)
  • 镜像:emlog/emlog:pro-latest-php7.4-apache
  • 面板:1Panel
  • Web 服务:OpenResty(反向代理到容器)
  • 数据库:MySQL 容器
  • 端口映射:宿主机 8080 → 容器 80
  • 数据挂载:宿主机数据目录 → 容器 /app

请求链路是这样的:用户 → CDN → OpenResty → Docker Emlog 容器(Apache + PHP)→ MySQL。

二、排查过程

1. 先确认容器在不在

容器名可能因为重建而变化,所以第一步先看实际容器名:

docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Ports}}"

确认容器确实在运行,名字也记下来(下文用 emlog容器 代指)。

2. 检查伪静态模块

Emlog 的伪静态依赖 Apache 的 mod_rewrite,先确认它启用了:

docker exec emlog容器 apache2ctl -M | grep rewrite

输出 rewrite_module (shared),说明模块没问题。

3. 关键发现:DocumentRoot 指向了空目录

接着看 Apache 的站点配置:

docker exec emlog容器 apache2ctl -S 2>&1 | head -20

输出里有一行:

Main DocumentRoot: "/var/www/html"

再去看这个目录里有什么:

docker exec emlog容器 ls /var/www/html/

结果是空的,什么都没有。

那 Emlog 的文件到底在哪?全局搜一下 index.php:

docker exec emlog容器 find / -name "index.php" -not -path "*/usr/share/*" 2>/dev/null

输出里能看到 Emlog 的程序文件其实在 /app 目录下:

/app/index.php
/app/admin/index.php
/app/content/...

到这里问题就清楚了。

三、问题根因

这个 Emlog Docker 镜像有一个设计上的坑:

Apache 默认的站点配置 000-default.conf 里,DocumentRoot 指向的是 /var/www/html,但 Emlog 的实际程序文件放在了 /app 目录。/var/www/html 是一个空目录,所以无论访问什么路径,Apache 都找不到文件,统统返回 404。

雪上加霜的是,Apache 默认配置里所有 Directory 块的 AllowOverride 都是 None。这意味着即使你放了 .htaccess 伪静态文件,Apache 也根本不会去读它。

所以要让站点正常访问、伪静态生效,必须同时解决两个问题:

  1. 把 DocumentRoot 指向正确的 /app 目录
  2. 开启 AllowOverride All,让 .htaccess 生效

四、解决方案

第一步:准备 .htaccess 文件

Emlog 的数据目录是挂载到容器 /app 的,所以直接在宿主机的数据目录里创建 .htaccess 即可:

cat > /你的数据目录/.htaccess << "EOF"
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
EOF

第二步:准备自定义站点配置

在宿主机上写一个 Apache 站点配置文件,把 DocumentRoot 指向 /app 并开启 AllowOverride:

mkdir -p /opt/emlog/conf

cat > /opt/emlog/conf/emlog-site.conf << "EOF"
<VirtualHost *:80>
    DocumentRoot /app
    <Directory /app>
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>
EOF

第三步:用 docker run 重建容器

这里要特别注意:不要用 1Panel 的图形界面去改挂载,它会报一个莫名其妙的错误:

includes invalid characters for a local volume name, only "[a-zA-Z0-9][a-zA-Z0-9_.-]" are allowed

这是 1Panel 把挂载路径当成了 Docker 的命名卷(named volume)而不是 bind mount。直接用 docker run 手动建容器最稳妥:

docker run -d \
  --name emlog容器 \
  --restart always \
  -p 8080:80 \
  -v /你的数据目录:/app \
  -v /opt/emlog/conf/emlog-site.conf:/etc/apache2/sites-enabled/000-default.conf \
  emlog/emlog:pro-latest-php7.4-apache

注意:.htaccess 要放在 /app 目录下(也就是宿主机的数据目录里),不要挂载到 /var/www/html/.htaccess,那个目录是空的,挂了也没用。

第四步:配置 OpenResty 伪静态

在 1Panel 里找到对应站点 → 站点设置 → 伪静态,填入:

if (!-e $request_filename) {
    rewrite ^/(.*)$ /index.php last;
}

如果面板的伪静态入口对反向代理站点不生效,就手动编辑 OpenResty 配置,在 location / 之前加入 rewrite 规则:

server {
    listen 80;
    server_name 你的域名 www.你的域名;

    if (!-e $request_filename) {
        rewrite ^/(.*)$ /index.php last;
    }

    location / {
        proxy_pass http://你的服务器IP:8080;
        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 $scheme;
    }
}

改完重载 OpenResty:

docker exec openresty容器 nginx -s reload

第五步:Emlog 后台设置

  1. 登录 Emlog 后台
  2. 进入「设置 → 链接结构」
  3. 选择「文件格式」(形如 /post-1.html),SEO 友好
  4. 确认「站点地址」填的是你的正式域名(https://你的域名),而不是 http://服务器IP:8080,否则生成的链接会带 IP 和端口
  5. 保存

五、一个容易遇到的小插曲:.htaccess 不可写

后台保存链接结构时,可能会提示「根目录下的.htaccess不可写」。

原因是 .htaccess 是用 root 创建的,而容器里 Apache 的运行用户是 www-data(UID 33),没有写权限。改一下文件归属就行:

chown 33:33 /你的数据目录/.htaccess

还不行就直接放开写权限:

chmod 666 /你的数据目录/.htaccess

其实我们手动放的规则已经是通用的了,Emlog 保存时只是用自带规则覆盖一遍,效果一样。这一步主要是让后台保存不报错,同时把链接结构写进数据库。

六、让配置持久化

上面这套配置都是放在宿主机、通过挂载进容器的,所以容器重建也不会丢。需要持久化的就两个文件:

宿主机路径容器路径说明
/你的数据目录//appEmlog 全部数据(含 .htaccess)
/opt/emlog/conf/emlog-site.conf/etc/apache2/sites-enabled/000-default.confApache 站点配置

以后无论容器怎么重建,只要这两条挂载在,伪静态就一直是好的。

七、踩坑总结

把这次踩的坑集中列一下,方便快速对照:

  1. DocumentRoot 陷阱:Emlog 镜像的 Apache 默认指向空的 /var/www/html,真实文件在 /app,必须用自定义站点配置覆盖。
  2. AllowOverride 默认 None:即使放了 .htaccess 也不生效,必须显式开启 AllowOverride All
  3. 别用 1Panel UI 改挂载:会报 "invalid characters for a local volume name",直接用 docker run
  4. proxy_pass 别用 127.0.0.1:容器内的 127.0.0.1 指向容器自己,要用宿主机内网 IP。
  5. 站点地址要填正式域名:填 IP:端口会导致生成的链接全是 IP。
  6. .htaccess 写权限:root 创建的文件 www-data 写不了,记得 chown 33:33
  7. 改完 OpenResty 要重载:否则配置不生效。

八、常用排查命令备忘

最后留一份排查命令清单,下次遇到问题可以按顺序敲:

# 确认容器名
docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Ports}}"

# 检查 mod_rewrite
docker exec emlog容器 apache2ctl -M | grep rewrite

# 查看 DocumentRoot 指向
docker exec emlog容器 apache2ctl -S 2>&1 | head -20

# 检查 .htaccess(注意是 /app 不是 /var/www/html)
docker exec emlog容器 cat /app/.htaccess

# 检查站点配置
docker exec emlog容器 cat /etc/apache2/sites-enabled/000-default.conf

# 确认 Emlog 文件存在
docker exec emlog容器 ls /app/index.php

# 查看挂载情况
docker inspect emlog容器 --format '{{json .Mounts}}' | python3 -m json.tool

# 看 Apache 错误日志
docker exec emlog容器 tail -20 /var/log/apache2/error.log

结语

这次问题的核心,就是 Emlog Docker 镜像的 DocumentRoot 指向和实际文件位置不一致。看似一个 404,背后其实是「DocumentRoot 指错 + AllowOverride 没开」两个问题叠加。把这个坑记下来,希望能帮到同样在用 Docker 部署 Emlog 的朋友。

如果你也遇到了类似的 404,不妨先 apache2ctl -S 看看 DocumentRoot 到底指向哪里,多半问题就出在那。

Emlog Docker 部署实战:从 0 到上线的完整记录(1Panel + OpenResty)

分类:建站运维 · 标签:Emlog、Docker、1Panel、OpenResty、伪静态

这篇文章记录我用 Docker + 1Panel + OpenResty 从零部署一个 Emlog 博客的完整过程,包括踩过的坑和最终的稳定方案。如果你也打算用容器化方式跑 Emlog,这篇应该能帮你少走不少弯路。

一、写在前面

传统方式部署 Emlog 需要在服务器上装 PHP、Apache/Nginx、MySQL,环境配起来繁琐,迁移也麻烦。用 Docker 之后,整个博客就是一个容器,迁移、备份、重建都很方便。

但 Docker 部署也不是「一键起飞」,我这次就踩了几个不小的坑,最典型的一个是容器跑起来后全站 404。下面把完整流程和这些坑一次性讲清楚。

最终效果:一个带伪静态、邮件通知、CDN 加速的 Emlog 博客,所有配置持久化,容器重建不丢。

二、最终架构

先看一下整体架构,心里有个数:

用户 → CDN → OpenResty(反向代理)→ Emlog 容器(Apache + PHP)→ MySQL 容器

各组件分工:

  • OpenResty:由 1Panel 管理,负责接收请求、伪静态 rewrite、反向代理到 Emlog 容器
  • Emlog 容器:内置 Apache + PHP,运行博客程序
  • MySQL 容器:独立数据库容器,存储博客数据

为什么用 OpenResty 反代而不是直接暴露 Emlog 容器?因为这样可以在前面统一处理伪静态、SSL、缓存,Emlog 容器只管跑程序,职责清晰,也方便后续加 CDN。

三、环境准备

我的环境如下,供对照:

  • 服务器:一台 Linux VPS(Debian)
  • 面板:1Panel
  • 博客程序:Emlog Pro
  • 镜像:emlog/emlog:pro-latest-php7.4-apache
  • 数据库:MySQL 8.x 容器

需要准备的参数(下文用占位符表示,替换成你自己的):

占位符含义
你的域名博客正式域名
你的服务器IP服务器内网 IP
你的数据目录Emlog 数据在宿主机的存放路径
你的数据库密码MySQL 密码

四、第一步:部署 MySQL 容器

Emlog 需要数据库。我用独立的 MySQL 容器,方便管理和备份。

在 1Panel 的应用商店里安装 MySQL,或者直接用命令:

docker run -d \
  --name mysql \
  --restart always \
  -e MYSQL_ROOT_PASSWORD=你的数据库密码 \
  -v /opt/mysql/data:/var/lib/mysql \
  mysql:8.4

装好后进入容器创建 Emlog 专用数据库:

docker exec -it mysql mysql -u root -p
CREATE DATABASE emlog CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

注意:数据库端口不用对外开放,容器之间通过内部网络通信即可,更安全。

五、第二步:部署 Emlog 容器

在 1Panel 应用商店找到 Emlog 安装,或者用命令部署。这里先按默认方式跑起来:

docker run -d \
  --name emlog容器 \
  --restart always \
  -p 8080:80 \
  -v 你的数据目录:/app \
  -e EMLOG_DB_HOST=mysql \
  -e EMLOG_DB_NAME=emlog \
  -e EMLOG_DB_USER=root \
  -e EMLOG_DB_PASSWORD=你的数据库密码 \
  emlog/emlog:pro-latest-php7.4-apache

关键参数说明:

  • -p 8080:80:把容器 80 端口映射到宿主机 8080,后面 OpenResty 反代这个端口
  • -v 你的数据目录:/app:Emlog 程序和数据都在容器的 /app,挂载到宿主机实现持久化

容器跑起来后,先别急着访问,因为大概率会遇到下面这个坑。

六、第三步:那个绕不开的 404 坑

容器跑起来后访问首页,返回的是这样一个 Apache 404:

Not Found
The requested URL was not found on this server.
Apache/2.4.54 (Debian) Server at www.你的域名 Port 80

排查方法:先看 Apache 的 DocumentRoot 指向哪里。

docker exec emlog容器 apache2ctl -S 2>&1 | head -20

输出里会看到:

Main DocumentRoot: "/var/www/html"

再看这个目录:

docker exec emlog容器 ls /var/www/html/

空的。而 Emlog 的真实文件其实在 /app

docker exec emlog容器 ls /app/index.php

根因:这个 Emlog 镜像的 Apache 默认配置 000-default.conf 把 DocumentRoot 指向了空的 /var/www/html,而程序文件实际在 /app。所以所有请求都 404。

同时,Apache 默认的 AllowOverride 全是 None,就算放了 .htaccess 也不会被读取。

所以必须同时修两个地方:把 DocumentRoot 指向 /app,并开启 AllowOverride All

七、第四步:配置伪静态(含 404 修复)

1. 准备 .htaccess

数据目录挂载到容器 /app,所以直接在宿主机数据目录里建 .htaccess

cat > 你的数据目录/.htaccess << "EOF"
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
EOF

2. 准备自定义站点配置

写一个 Apache 站点配置,把 DocumentRoot 改到 /app 并开启 AllowOverride:

mkdir -p /opt/emlog/conf

cat > /opt/emlog/conf/emlog-site.conf << "EOF"
<VirtualHost *:80>
    DocumentRoot /app
    <Directory /app>
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>
EOF

3. 用 docker run 重建容器(关键)

这里要特别提醒:不要用 1Panel 图形界面改挂载,会报错:

includes invalid characters for a local volume name, only "[a-zA-Z0-9][a-zA-Z0-9_.-]" are allowed

这是 1Panel 把路径当成了命名卷。直接用 docker run 重建,把站点配置挂载进去覆盖默认的 000-default.conf

docker run -d \
  --name emlog容器 \
  --restart always \
  -p 8080:80 \
  -v 你的数据目录:/app \
  -v /opt/emlog/conf/emlog-site.conf:/etc/apache2/sites-enabled/000-default.conf \
  -e EMLOG_DB_HOST=mysql \
  -e EMLOG_DB_NAME=emlog \
  -e EMLOG_DB_USER=root \
  -e EMLOG_DB_PASSWORD=你的数据库密码 \
  emlog/emlog:pro-latest-php7.4-apache

这样 DocumentRoot 和 AllowOverride 两个问题一次性解决,而且配置在宿主机上,容器重建也不会丢。

4. 配置 OpenResty 反代和伪静态

在 1Panel 里创建网站,添加反向代理指向 你的服务器IP:8080,然后在「站点设置 → 伪静态」填入:

if (!-e $request_filename) {
    rewrite ^/(.*)$ /index.php last;
}

如果面板的伪静态入口对反代站点不生效,就手动编辑 OpenResty 配置:

server {
    listen 80;
    server_name 你的域名 www.你的域名;

    if (!-e $request_filename) {
        rewrite ^/(.*)$ /index.php last;
    }

    location / {
        proxy_pass http://你的服务器IP:8080;
        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 $scheme;
    }
}

改完重载:

docker exec openresty容器 nginx -s reload

八、第五步:Emlog 后台初始化

站点能访问后,登录后台做几项基础设置:

  1. 链接结构:设置 → 链接结构,选「文件格式」(/post-1.html),SEO 友好
  2. 站点地址:设置 → 基本设置,站点地址填 https://你的域名,千万别填 http://服务器IP:8080,否则生成的链接全带 IP 端口
  3. 保存报错处理:如果保存链接结构时提示「.htaccess不可写」,是因为文件归属问题,执行:
chown 33:33 你的数据目录/.htaccess

还不行就 chmod 666。容器里 Apache 运行用户是 www-data(UID 33),root 创建的文件它写不了。

九、第六步:美化邮件通知(可选)

Emlog 自带邮件通知功能(比如评论回复提醒),默认模板比较朴素。可以在后台「设置 → 邮件通知」里替换成自定义 HTML 模板。

模板里有两个变量,发信时自动替换,不用改:

  • {{mail_site_title}} → 站点名称
  • {{mail_content}} → 邮件正文

一个简洁美观的模板结构参考:顶部品牌区(站点名 + 标语)、中间白色正文卡片、底部信息区(站点链接 + 联系方式 + 版权)。具体样式可以根据自己网站的配色调整,核心是保留那两个变量。

十、持久化清单

这套方案所有配置都在宿主机上,容器重建不丢。需要保管好的就这些:

宿主机路径容器路径说明
你的数据目录//appEmlog 全部数据(含 .htaccess)
/opt/emlog/conf/emlog-site.conf/etc/apache2/sites-enabled/000-default.confApache 站点配置
/opt/mysql/data//var/lib/mysql数据库数据

备份时把这几个目录打包即可,迁移到新服务器原样恢复就能跑。

十一、故障排查速查

留一份命令清单,遇到问题按顺序敲:

# 确认容器名(重建后可能变)
docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Ports}}"

# 检查 mod_rewrite 是否启用
docker exec emlog容器 apache2ctl -M | grep rewrite

# 查看 DocumentRoot 指向(404 时第一个要看)
docker exec emlog容器 apache2ctl -S 2>&1 | head -20

# 检查 .htaccess(注意是 /app 不是 /var/www/html)
docker exec emlog容器 cat /app/.htaccess

# 检查站点配置是否挂载成功
docker exec emlog容器 cat /etc/apache2/sites-enabled/000-default.conf

# 确认 Emlog 文件存在
docker exec emlog容器 ls /app/index.php

# 查看挂载情况
docker inspect emlog容器 --format '{{json .Mounts}}' | python3 -m json.tool

# 看 Apache 错误日志
docker exec emlog容器 tail -20 /var/log/apache2/error.log

常见问题对照:

症状原因解决
全站 404(Apache 返回)DocumentRoot 指向空的 /var/www/html挂载 emlog-site.conf 覆盖默认配置
首页正常内页 404.htaccess 未生效检查 /app/.htaccess 和 AllowOverride All
链接带 IP:端口站点地址填错后台改成正式域名
502 Bad Gateway反代地址错误proxy_pass 用宿主机内网 IP,不用 127.0.0.1
改配置没效果没重载 OpenRestynginx -s reload
1Panel 改挂载报错UI 把路径当命名卷改用 docker run
.htaccess 不可写文件归属是 rootchown 33:33

十二、踩坑总结

把这次的坑集中列一下:

  1. DocumentRoot 陷阱:Emlog 镜像的 Apache 默认指向空的 /var/www/html,真实文件在 /app,必须用自定义站点配置覆盖。
  2. AllowOverride 默认 None:放了 .htaccess 也不生效,必须显式开启 AllowOverride All
  3. 别用 1Panel UI 改挂载:会报命名卷错误,直接 docker run
  4. proxy_pass 别用 127.0.0.1:容器内 127.0.0.1 指向自己,要用宿主机内网 IP。
  5. 站点地址填正式域名:填 IP:端口会导致链接全带 IP。
  6. .htaccess 写权限:root 建的文件 www-data 写不了,记得 chown 33:33
  7. 改完 OpenResty 要重载:否则不生效。

十三、结语

整体下来,Docker 部署 Emlog 的思路很清晰:MySQL 容器 + Emlog 容器 + OpenResty 反代,三层各司其职,数据全部挂载持久化。唯一的「惊喜」是镜像的 DocumentRoot 指向问题,只要知道真实文件在 /app,用自定义站点配置覆盖一下就能解决。

这套方案跑下来很稳定,迁移和备份也方便——打包几个数据目录就能整体搬走。如果你也在用容器跑 Emlog,希望这篇能帮你少踩点坑。

手把手教你用 1Panel 在 NAS 上部署 Hermes

全程图形化操作,小白也能搞定。从注册 DeepSeek 到微信聊天,一步一步来。

前言:为什么用 1Panel?

玩 NAS 的朋友都碰到过这样的困境:想装个 Docker 应用,要去网上搜命令、改配置、写 docker-compose……一搞就是半天,还容易报错。

<strong>1Panel</strong> 就是来解决这个的——它是一款<strong>国产开源</strong>的服务器管理面板,类似宝塔,但:

  • 对 Docker 的支持更原生
  • 界面更现代
  • 完全免费
  • 支持应用商店一键部署
  • 有了它,部署 Hermes 就是填几个表格的事。

    一、准备物料清单

    序号物料说明

    1飞牛NAS 或 绿联NAS系统正常、能联网、内存 ≥ 4GB

    2FinalShellWindows 上好用的 SSH 工具,官网:<a href="https://www.hostbuf.com/t/988.html">hostbuf.com</a>

    3DeepSeek 开发者账号调用大模型需要 API Key

    二、先注册 DeepSeek API

    Hermes 的核心是"大模型驱动",它自己不跑 AI,而是调用云端 API。先准备好 API Key。

    (一)为什么选 DeepSeek?

    DeepSeek 是目前最便宜的大模型 API 之一,效果很好:

    410 块钱DeepSeek 充值,够你用几个月

    模型输入价格(每百万 token)输出价格(每百万 token)

    DeepSeek-V3¥1¥4

    deepseek-chat 始终指向最新模型,注册后直接用就行。

    (二)注册步骤

    1. 浏览器访问 <a href="https://platform.deepseek.com">platform.deepseek.com</a>

    2. 点右上角「登录 / 注册」

    3. 手机号注册或微信扫码登录

    4. 注册完自动进入开发者后台

    (三)创建 API Key

    1. 左侧菜单 →「API Keys」

    2. 点「创建新的 API Key」

    3. 起个名字,比如 <code>hermes-nas</code>

    4. ⚠️ <strong>立刻复制保存!</strong> 这串 Key 只显示一次

    5. Key 格式类似:<code>sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx</code>

    <strong>把 Key 粘贴到记事本里存好</strong>,后面配置要用。

    (四)充值

    1. 左侧菜单 →「充值」

    2. 选金额:最低 10 元

    3. 微信/支付宝扫码支付

    ✅ DeepSeek 这边就搞定了。

    三、NAS 开启 SSH

    1Panel 需要通过 SSH 远程安装。

    (一)飞牛 NAS

    1. 浏览器打开飞牛 Web 管理页

    2. 左侧菜单 →「设置」→「终端」

    3. 勾选「开启 SSH」

    4. 默认端口 22

    (二)绿联 NAS

    1. 浏览器打开绿联 UGOS 管理页

    2. 「控制面板」→「终端机与SNMP」

    3. 勾选「启用 SSH 服务」

    4. 默认端口 22

    两种 NAS 操作差不多,找到 "SSH" 关键字打开就行。

    四、SSH 连接 NAS

    (一)Windows CMD(自带,无需安装)

    Windows 10/11 自带 SSH,按 <code>Win+R</code> 输入 <code>cmd</code> 回车,直接输入:

    
    ssh root@你的NAS_IP
    
    如果端口不是默认 22,加 <code>-p 端口号</code>,例如:<code>ssh root@192.168.1.100 -p 2222</code>

    第一次连接会提示确认,输入 <code>yes</code> 回车,然后输入 NAS 密码即可。

    (二)FinalShell(推荐新手)

    FinalShell 是 Windows 上好用的 SSH 客户端,界面友好、有中文、带文件管理,比 CMD 更好上手。

    官网:<a href="https://www.hostbuf.com/t/988.html">hostbuf.com</a>,下载 Windows 版,一路默认安装。

    (三)创建连接

    1. 打开 FinalShell → 左上角文件夹图标(新建连接)

    2. 选择「SSH 连接 (Linux)」

    3. 填写信息:

    DeepSeek-R1(推理增强)¥4¥16

    字段填什么

    名称随便写,比如「我的飞牛NAS」

    主机NAS 的 IP 地址(去路由器后台看,一般是 192.168.x.x)

    端口22

    用户名root

    4. 点「确定」→ 双击连接

    看到 <code>root@FNOS:~#</code> 就表示连上了!

    五、安装 1Panel 面板

    (一)获取安装命令

    浏览器打开 <a href="https://1panel.cn">1panel.cn</a>,首页就能看到大大的安装按钮,复制命令:

    
    curl -sSL https://resource.fit2cloud.com/1panel/package/quick_start.sh -o quick_start.sh && bash quick_start.sh
    

    (二)粘贴执行

    回到 SSH 终端(CMD 或 FinalShell),粘贴命令回车。

    安装程序会自动执行以下操作:

  • 检测你的 NAS 系统架构(x86/ARM64)
  • 自动安装 Docker(如果还没装)
  • 下载 1Panel 安装包
  • 配置面板服务
  • 整个过程 3-5 分钟,全程无需手动干预,等着就行。

    (三)设置面板账号

    安装到后半段,会弹出交互式配置,逐项输入:

    1. <strong>「请设置 1Panel 面板端口」</strong> → 直接回车,用默认 <code>10086</code>

    2. <strong>「请设置 1Panel 面板安全入口」</strong> → 设置一个后缀,比如 <code>/mypanel</code>。这是面板地址的路径部分,增加安全性。不设也行但建议设

    3. <strong>「请设置 1Panel 面板用户名」</strong> → 填 <code>admin</code>(或自定义)

    4. <strong>「请设置 1Panel 面板密码」</strong> → <strong>重点!</strong> 设复杂密码——大小写字母 + 数字 + 特殊符号,这是面板的唯一防线

    (四)保存登录信息

    安装完成后屏幕打印:

    
    ================================================
    面板地址: http://192.168.x.x:10086/mypanel
    用户名: admin
    密码: 你设的密码
    ================================================
    

    📸 <strong>截图或拍照保存!</strong> 马上要用。

    (五)访问面板验证

    浏览器打开面板地址 → 输入账号密码 → 看到蓝白仪表盘 → 安装成功!

    左侧「容器」菜单能看到 Docker 状态,说明 1Panel 已经把 Docker 也管理起来了。

    六、登录 1Panel

    1. 浏览器打开面板地址

    2. 输入用户名 <code>admin</code> 和密码

    3. 登录成功,看到蓝白配色的管理面板

    左侧菜单 →「容器」→ 能看到 Docker 运行状态,说明一切正常。

    (可选)配镜像加速

    国内访问 Docker Hub 有时很慢:

    1. 「容器」→「配置」→「镜像加速」

    2. 填入:

    
    https://docker.1panel.live
    

    3. 点「重启 Docker」

    七、部署 Hermes(三种方式任选)

    <strong>这就是装 1Panel 的目的!</strong> 1Panel 让 Hermes 部署变成了填表——不需要懂 Docker 命令,不需要写 docker-compose,甚至配置 DeepSeek API 都可以在面板里完成。对新手极其友好。

    下面提供三种方式,推荐新手用方式一。

    方式一:1Panel 应用商店一键安装(最推荐!⭐)

    这才是 1Panel 的核心优势——像手机装 App 一样部署 Hermes。

    1. 左侧菜单 →「应用商店」

    2. 搜索框输入 <code>hermes</code>

    3. 找到 <strong>Hermes Agent</strong>,点「安装」

    4. 填写配置:

    密码NAS 的管理员密码

    字段

    名称hermes

    端口8020

    5. 点「确认」→ 等 1-2 分钟 → 完成!

    这就是全部。不需要手动配端口映射、不需要配卷挂载、不需要写环境变量——1Panel 全部帮你处理好了。

    甚至配置 AI 模型都可以在应用商店的安装界面里直接填 DeepSeek API Key,不用进容器终端敲命令。

    方式二:Web 端手动创建(适合想了解参数的同学)

    1. 创建容器

    左侧菜单 →「容器」→「创建容器」,填写:

    数据目录/opt/hermes

    字段

    名称hermes

    ⚠️ 如果镜像拉不下来,换:<code>dockerpull.com/nousresearch/hermes-agent:latest</code>

    2. 端口映射

    「端口」栏 →「添加端口映射」:

    镜像ghcr.io/nousresearch/hermes-agent:latest

    主机端口容器端口

    3. 目录挂载

    「卷挂载」→「添加卷挂载」:

    80208020

    主机路径容器路径

    4. 环境变量

    「环境变量」→「添加环境变量」:

    /opt/hermes/opt/data

    变量名

    5. 启动

    点右下角「确认」,等待 1-2 分钟,容器状态变绿色「运行中」即可。

    方式三:一键 SSH 命令

    如果你更喜欢命令行,直接在 SSH 终端粘贴以下一整段:

    
    docker run -d \\
      --name hermes \\
      --restart=unless-stopped \\
      -p 8020:8020 \\
      -v /opt/hermes:/opt/data \\
      -e TZ=Asia/Shanghai \\
      ghcr.io/nousresearch/hermes-agent:latest
    
    如果镜像拉不下来,把最后一行换成 <code>dockerpull.com/nousresearch/hermes-agent:latest</code>

    执行后等 1-2 分钟,<code>docker ps | grep hermes</code> 看到状态 <code>Up</code> 就行。

    两种方式效果完全一样,选你喜欢的就好。

    八、配置 Hermes

    部署完成后需要配置 AI 模型,让 Hermes 接上 DeepSeek。同样两种方式任选。

    方式一:Hermes Web 管理界面配置(推荐!🌟)

    不用进终端,在浏览器里鼠标点击就能配好:

    1. 浏览器打开 <code>http://你的NAS_IP:8020</code>

    2. 左侧菜单 →「设置」→「模型配置」

    3. 1Panel / Hermes 提供了专门的模型配置页面,直接填表:

    TZAsia/Shanghai

    字段

    模型提供商自定义 (Custom)

    API 地址https://api.deepseek.com/v1

    默认模型deepseek-chat

    4. 点「保存」→ 立即生效!

    一行命令都不用敲,跟填注册表一样简单。这就是 1Panel 对新手最友好的地方。

    方式二:容器终端命令

    如果你想了解底层,也可以用命令行:

    1. 左侧「容器」→ 找到 <code>hermes</code>

    2. 点右边「终端」按钮 →「连接」

    3. 一行一行粘贴执行(<strong>把 Key 换成你自己的</strong>):

    
    hermes config set model.provider custom
    hermes config set model.base_url https://api.deepseek.com/v1
    hermes config set model.default deepseek-chat
    hermes config set model.api_key sk-你的APIKey粘贴到这里
    

    <strong>各参数含义:</strong>

  • <code>provider custom</code>:使用自定义 API
  • <code>base_url</code>:DeepSeek 的 API 地址
  • <code>default</code>:默认模型(deepseek-chat,始终使用最新版本)
  • <code>api_key</code>:你之前注册充值的那个 Key
  • 两种方式效果完全一样,推荐新手用方式一,填几个框就完事。

    (三)接入微信

    在同一个终端执行:

    
    hermes gateway setup
    

    终端会出现一个二维码。用<strong>微信扫这个码</strong>,按提示操作:

    1. 微信提示"发现一个新设备"

    2. 选择绑定到哪个聊天

    3. 确认授权

    绑定成功后执行:

    
    hermes gateway restart
    

    🎉 现在在微信里 @Hermes 就能跟它聊天了!

    九、验证一切正常

  • 🌐 浏览器打开下面这个地址,看到 Hermes Web 界面就成功了:
  • 
    http://你的NAS_IP:8020
    
  • 💬 微信里发一条消息 → 它应该会回复
  • 十、常见问题

  • <strong>镜像一直拉不下来?</strong> 换以下镜像之一:
  • 
    docker.1panel.live/nousresearch/hermes-agent:latest
    dockerpull.com/nousresearch/hermes-agent:latest
    
  • <strong>容器启动后马上退出?</strong> 点容器 →「日志」看错误信息,通常是网络不通或 API Key 没配对
  • <strong>FinalShell 连接提示 Connection refused?</strong> 检查 NAS 的 SSH 有没有开启,飞牛和绿联默认都是关闭的
  • <strong>微信扫码后没反应?</strong> 执行以下命令重启网关:
  • 
    hermes gateway restart
    
  • <strong>怎么升级到最新版?</strong> 1Panel → 容器 → hermes → 更多 → 重建 → 勾选「拉取最新镜像」
  • <strong>群晖/威联通/Unraid/OMV 能用吗?</strong> 完全可以!只要系统支持 Docker + 能开 SSH 就行
  • 十一、成本核算

    API Keysk-你的APIKey粘贴到这里

    项目费用

    NAS 硬件已有

    1Panel 面板免费

    Hermes 软件免费开源

    DeepSeek API≈ 10 元/2-3个月

    比腾讯云 VPS 一个月 50-100 元省太多了,而且数据全在自己手里!

    总结

    回顾整个过程:

    1. 注册 DeepSeek,拿到 API Key

    2. NAS 开 SSH → CMD/FinalShell 连接

    3. 一条命令装好 1Panel

    4. 应用商店一键安装 Hermes

    5. 配好 API Key + 绑微信

    6. 完成!

    全程不需要懂 Docker 命令,不需要写 docker-compose,不需要 vi 编辑器。<strong>1Panel 让部署 Hermes 变成了手机装 App 一样简单。</strong>

    这就是推荐 1Panel 的原因——对 NAS 玩家来说,简单就是王道。装 1Panel 就是为了用 1Panel 应用商店部署 Hermes,从注册 DeepSeek 到微信聊天,一条龙全搞定。

    <strong>排版:追梦学习库 文字:追梦学习库</strong>

    <strong>总计月均</strong><strong>≈ 3-5 元</strong>