# 从零搭建个人导航页：Docker部署Mtab，附域名+HTTPS配置

**URL:** <https://forum.rainyun.com/t/topic/13345>\
**Category:** 云服务器 RCS\
**Created:** [2026 年7 月 31 日 14:56 UTC](https://forum.rainyun.com/t/topic/13345 "2026-07-31T14:56:38Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

作者： ![gzy](https://forum.rainyun.com/user_avatar/forum.rainyun.com/gzy/32/12796_2.png) [@gzy](https://forum.rainyun.com/u/gzy)\
发布日期： [2026 年7 月 31 日 14:56 UTC](https://forum.rainyun.com/t/topic/13345/1 "2026-07-31T14:56:38Z")

</div>

​本文来自我的博客：[从零搭建个人导航页：Docker部署Mtab，附域名+HTTPS配置 - 叹惋博客](https://twbk.cn/326.html "从零搭建个人导航页：Docker部署Mtab，附域名+HTTPS配置 - 叹惋博客")

​

## **写在前面：为什么我要折腾这个？**

不知道你是不是和我一样，每次打开浏览器看到默认的新标签页——要么是搜索引擎的广告堆，要么是空白一片，想找个常逛的网站还得手动输网址或翻收藏夹。书签倒是存了一堆，但真正用的时候总是找不到，杂乱无章。

直到我遇到了 **Mtab** ——一个开源的、长得像“在线桌面”的个人导航页。它支持分类管理网址、后台可视化编辑、多用户（可给朋友开账号）、还带天气、搜索框、甚至壁纸切换。最重要的是，它非常轻量， **低配服务器就能流畅跑起来** 。官方推荐配置甚至低至 512MB 内存

* * *

## **一、准备工作：你需要的东西**

1. **一台云服务器** ：我用的是[雨云服务器](https://www.rainyun.com/xls_)，系统推荐 Ubuntu 22.04 LTS 或 Debian 12。如果你用 CentOS，命令稍有不同，但核心逻辑一样。

2. **一个域名** （非必需）：绑域名加 HTTPS 更正规，也方便长期使用。没有的话直接用 IP 加端口访问也完全没问题。

3. **SSH 工具** ：Windows 推荐 FinalShell 或 Putty，Mac/Linux 直接用自带终端。

4. **一点点命令行基础** ：会复制粘贴、会看报错信息就行。

* * *

## **二、连接服务器 & 基础环境准备**

### **2.1 SSH 登录**

拿到服务器的公网 IP、root 密码（或密钥）后，用终端工具连上去：

```auto
ssh root@你的服务器IP

```

输入密码后看到 `root@主机名:~#` 就说明成功了。如果提示密钥错误，可以去云服务商后台重置密码。

### **2.2 更新系统 & 安装必要工具**

登录后第一件事，更新软件源和已装软件，这步能避免后续安装依赖时版本冲突，这步耗时挺久，请耐心等待：

```auto
apt update && apt upgrade -y

```

安装一些后面会用到的工具，比如 `curl`、`wget`、`vim`（也可以用 nano）：

```auto
apt install curl wget vim git ufw -y

```

这里多装了一个 `ufw`，是 Ubuntu 的防火墙管理工具，后面如果要用可以顺手开启 22、80、443 端口。

### **2.3 安装 Docker 和 Docker Compose（核心）**

Mtab 官方提供了 Docker 镜像，这是最省心的部署方式，所以必须先把 Docker 环境装好。

**一键安装 Docker（官方脚本，最稳妥）：**

```auto
curl -fsSL https://get.docker.com | bash -s docker

```

等待几分钟，装完后检查版本：

```auto
docker --version

```

如果显示类似 `Docker version 29.7.0` 就成功了。

![](https://forum.rainyun.com/uploads/default/original/2X/d/da26756e6447f86e31f02c9c3edd8dd9c6b161c8.png)

**关于 Docker Compose 的说明** ：现在 Docker 官方已经把 Compose 功能集成到 `docker` 命令里了（子命令 `docker compose`），不再需要单独安装二进制文件。为了验证，可以运行：

```auto
docker compose version

```

如果能正常输出版本号，说明已经内置。

![](https://forum.rainyun.com/uploads/default/original/2X/0/0657040407749427bdaa79735e3b42f428fba54d.png)

如果你的系统提示“command not found”，再单独安装插件：

```auto
apt install docker-compose-plugin -y

```

**注意** ：旧教程里常用的 `docker-compose`（带横杠）是独立程序，新版本推荐直接用 `docker compose`（空格），以下全文均使用新命令，兼容性更好。

* * *

## **三、部署 Mtab**

官方文档提供了两种部署方式：直接 `docker run` 和 `docker compose`。我强烈推荐后者，因为 Compose 方式把所有配置都写在一个文件里，后期维护、升级、迁移都极其方便，而且可以一键管理多个容器（比如 Mtab 本身加上它依赖的 MySQL）。

> **特别提醒：Mtab 需要 MySQL 数据库来存储数据，所以我们的部署方案里会包含两个容器：一个是 Mtab 主程序，另一个是 MySQL。Compose 会让这两个容器互相配合，省去你手动安装配置数据库的麻烦。**

* * *

### **3.1 创建项目目录**

我们先在服务器上建一个专门的文件夹来存放 Mtab 的全部数据。这样做的好处是：所有相关文件都集中在一起，以后想备份就打包这个目录，想卸载就直接删除，干干净净不留残余。

```auto
mkdir -p /opt/mtab && cd /opt/mtab

```

`-p` 参数的作用是如果父目录不存在则自动创建，避免报错。

* * *

### **3.2 编写 docker-compose.yml**

用 vim 新建配置文件：

```auto
vim docker-compose.yml

```

按下 `i` 键进入插入模式，然后粘贴以下完整内容。 **注意 YAML 对缩进极其敏感** ，缩进必须使用 **两个空格** ，不能用 Tab 键，否则启动时会报语法错误。

```auto
services:
  # ---------- MySQL 数据库服务 ----------
  mysql:
    image: mysql:8.0
    container_name: mtab-mysql
    restart: always
    ports:
      - "3306:3306"
    volumes:
      - ./mysql-data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: root123456
      MYSQL_DATABASE: mtab
      MYSQL_USER: mtab
      MYSQL_PASSWORD: mtab123456
    command: --default-authentication-plugin=mysql_native_password
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      timeout: 10s
      retries: 5

  # ---------- Mtab 导航页服务 ----------
  mtab:
    image: itushan/mtab:latest
    container_name: mtab
    restart: always
    ports:
      - "8080:80"
    volumes:
      - ./:/app
    depends_on:
      mysql:
        condition: service_healthy
    environment:
      - TZ=Asia/Shanghai

```

按 `ESC`，输入 `:wq` 回车

请注意，MySQL 版本需 \>= 5.7，推荐使用 MySQL 8

官方也提供了一键部署的配置文件，你可以直接下载使用：`wget https://mtab.cc/assets/docker-compose.yml`

* * *

### **3.3 逐行拆解：这份配置文件到底在说什么？**

刚接触 Docker 的朋友可能会被这一段配置吓到，别怕，我逐条给你解释清楚：

#### **MySQL 服务部分**

- **`image: mysql:8.0`** ：使用 MySQL 官方 8.0 版本的镜像。兼容性好。
- **`container_name: mtab-mysql`** ：给这个 MySQL 容器起个固定的名字，方便后续管理（比如 `docker logs mtab-mysql` 查看日志）。
- **`restart: always`** ：无论容器是正常退出还是意外崩溃，都会自动重启。服务器重启后也会自动拉起，省心省力。
- **`ports: - "3306:3306"`** ：将宿主机的 3306 端口映射到容器的 3306 端口。 **注意** ：如果宿主机上已经安装了 MySQL 占用了 3306，这里需要改成其他端口，比如 `"3307:3306"`，但后面的 Mtab 连接配置也要相应修改。
- **`volumes: - ./mysql-data:/var/lib/mysql`** ：这是 **数据持久化** 的核心。`/var/lib/mysql` 是 MySQL 容器内存储实际数据文件的目录，我们把它挂载到宿主机当前目录下的 `mysql-data` 文件夹。这样一来，即使容器被删除重建，所有数据库数据都还在。
- **`environment`** ：设置 MySQL 初始化所需的环境变量：
  - `MYSQL_ROOT_PASSWORD`：root 用户的密码（请务必改成你自己的强密码！）
  - `MYSQL_DATABASE`：安装时自动创建的数据库名，这里设为 `mtab`
  - `MYSQL_USER` 和 `MYSQL_PASSWORD`：创建一个专门给 Mtab 程序使用的数据库账号和密码（ **建议修改密码** ，不要用示例密码）

- **`command: --default-authentication-plugin=mysql_native_password`** ：指定 MySQL 8.0 使用旧版认证插件，确保与 Mtab 程序的兼容性。不加这行可能会报认证错误。
- **`healthcheck`** ：健康检查配置。它会定期执行 `mysqladmin ping` 来检测 MySQL 是否已经完全启动。`depends_on` 会等待健康检查通过后才启动 Mtab，防止 Mtab 在数据库还没准备好时就尝试连接导致报错。

#### **Mtab 服务部分**

- **`image: itushan/mtab:latest`** ：使用 Mtab 官方维护的 Docker 镜像。`latest` 标签会自动拉取最新稳定版。
- **`container_name: mtab`** ：给 Mtab 容器起名，方便操作。
- **`ports: - "8080:80"`** ：将宿主机的 8080 端口映射到容器内的 80 端口。容器内 Mtab 监听的是 80，宿主机的端口你可以随意改，比如 `9200:80` 或 `8888:80`，只要不和其他服务冲突即可。
- **`volumes: - ./:/app`** ：将当前目录（`/opt/mtab`）整个挂载到容器内的 `/app`。Mtab 的程序文件、配置文件、上传的图片都会存放在这个目录下，所有数据都会持久化保存在宿主机上，容器删除后重新创建也不会丢失任何东西。
- **`depends_on`** ：指定依赖关系——Mtab 要等 MySQL 服务达到健康状态（`service_healthy`）之后才启动。这避免了启动顺序混乱导致的连接失败。
- **`environment: - TZ=Asia/Shanghai`** ：设置容器内时区为中国上海，保证日志时间显示正确。

* * *

### **3.4 启动容器**

一切准备就绪，在 `/opt/mtab` 目录下执行启动命令：

```auto
docker compose up -d

```

**解释一下各个参数** ：

- `up`：创建并启动容器。
- `-d`：后台运行（detach 模式），这样终端不会被日志刷屏，可以继续做其他操作。

**首次执行会发生什么？**

1. Compose 会读取 `docker-compose.yml` 文件。
2. 检查本地是否已有 `mysql:8.0` 和 `itushan/mtab:latest` 两个镜像，如果没有，会自动从 Docker Hub 拉取（这一步取决于你的网络速度，一般需要 1-3 分钟）。
3. 按依赖顺序先启动 MySQL 容器，等它健康检查通过后再启动 Mtab 容器。

* * *

### **3.5 验证是否启动成功**

启动完成后，用以下命令查看容器运行状态：

```auto
docker ps

```

正常情况你应该看到两行记录，状态都是 `Up`：

```auto
CONTAINER ID IMAGE STATUS PORTS
xxxxxx itushan/mtab:latest Up 10 seconds 0.0.0.0:8080->80/tcp
xxxxxx mysql:8.0 Up 2 minutes 0.0.0.0:3306->3306/tcp

```

 ![](https://forum.rainyun.com/uploads/default/original/2X/7/76460bdea4506ef324eec24b325638131937458c.png)

如果只看到一个甚至没有，说明出了问题。也可以用更详细的 `docker compose ps` 查看：

```auto
docker compose ps

```

* * *

### **3.6 常见启动失败的原因及排查方法**

如果容器没有正常运行，别慌，按下面的步骤一步步排查：

**情况一：端口被占用**

- 错误特征：日志里出现 `address already in use` 或 `bind: address already in use`
- 解决办法：要么修改 `docker-compose.yml` 里的宿主机端口（把 `"8080:80"` 改成 `"8081:80"` 或 `"9200:80"`），要么停掉占用该端口的其他程序，然后重新 `docker compose up -d`。

**情况二：镜像拉取失败**

- 错误特征：日志里出现 `pull access denied` 或 `repository does not exist`
- 解决办法：先检查镜像名是否正确（`itushan/mtab` 确认无误）。如果确认无误还拉不下来，考虑配置 Docker 镜像加速器（国内服务器访问 Docker Hub 有时候会慢或超时）。

**情况三：MySQL 无法启动**

- 错误特征：`docker ps` 里看不到 MySQL 容器，或状态是 `Exited`
- 排查方法：查看 MySQL 日志 `docker logs mtab-mysql`。常见原因是 `MYSQL_ROOT_PASSWORD` 没设置或设置了空值，或者 `volumes` 挂载的目录权限不足。

**情况四：Mtab 一直重启（CrashLoopBackOff）**

- 错误特征：`docker ps` 显示 Mtab 不断重启
- 排查方法：查看日志 `docker logs mtab`。大部分情况下是 Mtab 启动时连不上 MySQL——检查 MySQL 是否已经完全启动（`docker logs mtab-mysql` 看最后几行是否有 `ready for connections`），或者 `docker-compose.yml` 中 `depends_on` 的配置是否写对。

**最常用的排查三连** ：

```auto
docker compose logs # 查看所有容器的日志
docker compose logs mysql # 只看 MySQL 日志
docker compose logs mtab # 只看 Mtab 日志

```

* * *

### **3.7 补充：如果不想用 Docker Compose（备用方案）**

万一你不想用 Compose 方式，也可以直接用 Docker 命令分别运行两个容器（别忘了设置密码）：

**第一步：启动 MySQL**

```auto
docker run -d --name mtab-mysql \
  -p 3306:3306 \
  -v /opt/mtab/mysql-data:/var/lib/mysql \
  -e MYSQL_ROOT_PASSWORD=root123456 \
  -e MYSQL_DATABASE=mtab \
  -e MYSQL_USER=mtab \
  -e MYSQL_PASSWORD=mtab123456 \
  mysql:8.0 \
  --default-authentication-plugin=mysql_native_password

```

**第二步：启动 Mtab**

```auto
docker run -d --name mtab \
  -p 8080:80 \
  -v /opt/mtab:/app \
  --link mtab-mysql:mysql \
  itushan/mtab:latest

```

> **注意：`--link` 是旧式容器互联方式，在新版本 Docker 中仍可用但已不推荐，用 Compose 方式会更优雅可靠。**

* * *

### **3.8 数据持久化验证**

启动成功后，检查一下 `/opt/mtab` 目录下是否自动生成了 `mysql-data` 文件夹（里面是 MySQL 的数据文件），以及 Mtab 的相关配置文件。这证明挂载生效了，容器里的数据确实落到了宿主机硬盘上。

以后迁移服务器时，只需把这个 `/opt/mtab` 整个目录打包带走，在新服务器上安装好 Docker 和 Compose，然后 `docker compose up -d`，所有数据都会原样恢复，极其方便。

* * *

**总结这一步的检查清单** ：

- □ `/opt/mtab` 目录已创建
- □ `docker-compose.yml` 文件已正确编写且缩进无误
- □ `docker compose up -d` 执行成功
- □ `docker ps` 显示两个容器均为 `Up` 状态
- □ 浏览器访问 `http://你的IP:8080` 能打开页面（此时会进入安装向导）

如果以上都顺利通过，说明部署环节已经打通，可以进入下一步的初始化配置了！`ogs mtab` 查看错误日志，绝大多数情况是端口冲突或挂载目录权限问题。

* * *

## **四、初始化 Mtab 后台**

### **4.1 访问前台 & 后台**

打开浏览器，输入 `http://你的服务器IP:8080`。注意是 **http** 不是 https，如果浏览器强制跳转 https 会打不开，手动改成 http 即可。

第一次访问会弹出一个 **安装向导** 。

**先连接数据库**

1.因为mysql是docker部署的数据库地址请填入`mysql`

2.数据库用户名，密码和名称按照你前面设置的填入

3.然后点击测试连接

4.测试成功后点击下一步

 ![](https://forum.rainyun.com/uploads/default/original/2X/3/3a6c3b181d94a178c5ce8801bd5d6e368b3963a3.jpeg)

**创建管理员账号**

1.选择全新安装

2.设置好管理员账号和密码

4.点击开始安装

 ![](https://forum.rainyun.com/uploads/default/original/2X/b/bf893cdb1df60e2be6541b6e85c4b7775b31de0a.jpeg)

之后页面会跳转，点前往首页即可

 ![](https://forum.rainyun.com/uploads/default/original/2X/5/5621c5955a2c22a68f29348685f53273ddeadc36.jpeg)

之后进入首页

 ![](https://forum.rainyun.com/uploads/default/original/2X/9/9b3a1bc32eae3d32e36c7a1f282c9acf255c6df8.jpeg)

### **4.2 后台功能介绍（快速上手）**

登录后台后，左侧菜单栏主要有这几个核心功能：

- **仪表盘** ：显示总链接数、分类数、用户数等统计信息。
- **链接管理** ：这是最常用的地方。添加、编辑、删除网址，支持选择分类、自定义图标、设置排序权重。添加链接时，“图标”字段支持 FontAwesome 类名（比如 `fa-solid fa-house`），也支持上传图片。
- **分类管理** ：新建分类，比如“开发工具”、“影音娱乐”、“常用文档”。分类可以设置是否在前台显示。
- **主题设置** ：更换背景（支持上传本地图片或填写外链 URL）、调整强调色、卡片圆角、字体大小、是否开启毛玻璃效果等。Mtab 的颜值全靠这里调。
- **系统设置** ：网站标题、Logo、是否允许用户注册、默认搜索引擎（百度/Google/Bing/自定义）、天气插件位置等。

**建议你先加几个分类和链接，让前台看起来有内容。** 比如：

- 分类「常用」：添加百度、Google、GitHub、B站。
- 分类「工具」：添加腾讯云、阿里云、你的服务器管理面板地址。
- 分类「技术」：添加 Linux 命令查询、Stack Overflow。

添加链接时注意“图标”项，如果不知道 FontAwesome 类名，可以去官网搜索，或者暂时留空，系统会显示默认图标。

* * *

## **五、绑定域名 & 开启 HTTPS**

到这一步，Mtab 已经可以正常使用了。但如果你想让朋友访问时更正规，或者去掉端口号（直接用 443/80 端口），就需要绑定域名并配置反向代理。

### **5.1 域名解析**

去你的域名服务商（阿里云、腾讯云、Cloudflare 等）添加一条 **A 记录** 。主机记录填 `nav` 或 `bookmark` 或直接 `@`（取决于你想用 `nav.你的域名.com` 还是根域名），记录值填你服务器的公网 IP。

解析生效通常需要几分钟到半小时，可以用 `ping 你的域名` 检查是否已指向你的 IP。

### **5.2 使用 Nginx 做反向代理**

我选择用 Nginx 来转发请求，同时用 Certbot 自动申请 Let’s Encrypt 证书。Nginx 比 Apache 更轻量，对 1核2G 服务器更友好。

**安装 Nginx：**

```auto
apt install nginx -y

```

**配置 Nginx 站点：**

新建配置文件 `/etc/nginx/sites-available/mtab`：

```auto
vim /etc/nginx/sites-available/mtab

```

粘贴以下内容（把 `your-domain.com` 替换成你的真实域名）：

```auto
server {
    listen 80;
    server_name your-domain.com;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_http_version 1.1; # 新增：支持长连接
        proxy_set_header Upgrade $http_upgrade; # 新增：支持 WebSocket
        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;
    }
}

```

**解释** ：`proxy_pass` 指向 `http://127.0.0.1:8080`，因为 Nginx 和 Mtab 在同一台机器上，用本地回环地址访问比用公网 IP 更快更安全。

启用站点（创建软链接）：

```auto
ln -s /etc/nginx/sites-available/mtab /etc/nginx/sites-enabled/
nginx -t  
systemctl reload nginx

```

现在访问 `http://your-domain.com` 应该能打开 Mtab 了（不带端口号，清爽很多）。

### **5.3 用 Certbot 自动加 HTTPS**

安装 Certbot 和 Nginx 插件：

```auto
apt install certbot python3-certbot-nginx -y

```

申请证书（注意替换域名）：

```auto
certbot --nginx -d your-domain.com

```

按提示输入邮箱（用于接收到期通知）、同意服务条款。Certbot 会自动修改 Nginx 配置并启用 HTTPS。完成后访问 `https://your-domain.com` 就能看到绿色小锁。证书有效期 90 天，Certbot 会自动续期，无需人工干预。

 ![](https://forum.rainyun.com/uploads/default/original/2X/9/9ed6bfc8782a1dc2ee91d95c3e07cd81c675d3ba.png)

![](https://forum.rainyun.com/uploads/default/original/2X/3/38424098731de729cb0a4f6f72987140c04150b1.png)

* * *

## **六、进阶玩法与深度配置**

### **6.1 数据持久化原理**

在 `docker-compose.yml` 中我们定义了两个挂载点，这是保证数据不丢失的核心设计：

**MySQL 数据挂载：`./mysql-data:/var/lib/mysql`**

- 宿主机目录：`./mysql-data`（即 `/opt/mtab/mysql-data`）
- 容器内目录：`/var/lib/mysql`（MySQL 数据文件存储位置）
- 作用：所有数据库表、用户账号、网址分类都保存在这里。即使 `docker compose down` 销毁容器，数据依然保留。

**Mtab 程序挂载：`./:/app`**

- 宿主机目录：`./`（即 `/opt/mtab` 整个目录）
- 容器内目录：`/app`（Mtab 运行根目录）
- 作用：Mtab 的配置文件、上传壁纸、头像等静态资源都存放在这里。

> **⚠ 特别注意：本文使用的是 MySQL 数据库，数据保存在 `mysql-data` 目录。如果你在其他教程中看到 `./data` 和 `./uploads` 的挂载方式，那是旧版 SQLite 方案，请以本文为准。**

**验证持久化** ：添加几条链接 → `docker compose down` → `docker compose up -d` → 刷新页面，链接应全部还在。

**备份建议** ：打包 `/opt/mtab` 整个目录即可完成备份和迁移。

### **6.2 自定义图标库的高级用法**

后台添加链接时，图标字段支持完整的 FontAwesome 6 免费版类名。比如：

- 技术类：`fa-solid fa-code`
- 视频类：`fa-solid fa-video`
- 购物类：`fa-solid fa-cart-shopping`

如果不确定图标名，可以在前台打开浏览器开发者工具（F12），查看示例图标的 `class` 属性，照葫芦画瓢即可。

### **6.3 移动端适配与 PWA**

Mtab 的前端界面天然适配手机屏幕。在手机上用浏览器访问后，可以点击浏览器菜单选择“添加到主屏幕”，它就像一个小型 App 一样打开，没有浏览器地址栏，体验很好。

### **6.4 性能调优**

Mtab 本身就非常轻量，实测空载时容器内存占用约 40-60MB。如果你的服务器还跑了其他服务，建议开启 Swap 虚拟内存，防止偶发内存溢出导致进程被系统杀掉：

```auto
dd if=/dev/zero of=/swapfile bs=1M count=2048
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
echo '/swapfile none swap sw 0 0' >> /etc/fstab

```

这步创建了 2GB 的 Swap，对 1核2G 来说是锦上添花。

* * *

## **七、易踩的坑 & 解决办法**

**端口被占用** ：如果你发现 8080 端口已经被其他服务占用，可以在 `docker-compose.yml` 里把宿主机端口换成别的，比如 `"8888:80"` 或 `"9200:80"`，然后重新 `docker compose up -d` 即可。记得把安装页面的访问地址也换成新端口。

* * *

**容器启动后反复重启（CrashLoopBackOff）** ：用 `docker logs mtab` 查看 Mtab 日志，或者 `docker logs mtab-mysql` 查看 MySQL 日志。绝大多数情况是以下三种原因：

1. **MySQL 还没完全启动** ：Mtab 虽然配置了 `depends_on` 等待 MySQL 健康检查，但首次拉取镜像时 MySQL 初始化可能需要额外时间。稍等一两分钟再 `docker compose restart mtab` 即可。
2. **端口冲突** ：检查 3306（MySQL）或 8080（Mtab）是否被其他程序占用。
3. **MySQL 密码未正确设置** ：检查 `docker-compose.yml` 中 `MYSQL_ROOT_PASSWORD` 是否为空或格式不对。

根据具体报错信息对症下药，不要盲目重启。

* * *

**后台登录后页面空白或报错** ：大概率是 MySQL 连接失败或数据库未正确初始化。按顺序排查：

1. 确认 MySQL 容器在运行：`docker ps | grep mtab-mysql`
2. 确认数据库已创建：进入容器检查 `docker exec -it mtab-mysql mysql -uroot -p -e "show databases;"`（密码就是你设置的 `MYSQL_ROOT_PASSWORD`）
3. 如果数据库 `mtab` 不存在，可以删除 `/opt/mtab/mysql-data` 目录，然后 `docker compose up -d` 重新初始化（会清空所有数据，谨慎操作！）
4. 查看 Mtab 日志：`docker logs mtab --tail 50`

* * *

**Nginx 反代后出现 502 Bad Gateway** ：检查 Nginx 配置中的 `proxy_pass` 地址是否指向 `http://127.0.0.1:8080`，并且 Mtab 容器确实在监听 8080 端口：

```auto
netstat -tunlp | grep 8080
# 或者
docker ps | grep mtab

```

如果容器没在运行，用 `docker logs mtab` 查看原因。另外确认 Nginx 配置中的 `proxy_set_header` 已正确设置（参考第五章节的完整配置）。

* * *

**上传图片/壁纸显示不出来** ：确认 `docker-compose.yml` 中的 `volumes: - ./:/app` 挂载配置正确，且 `/opt/mtab` 目录对 Docker 有写权限。如果修改过宿主机目录的权限，可以尝试：

```auto
chmod 755 /opt/mtab

```

另外检查 Nginx 反代配置中对静态资源是否有特殊限制，通常默认配置不需要额外处理。

* * *

**Certbot 申请证书失败** ：确保域名解析已经生效（`ping 你的域名` 能返回服务器 IP），并且 80 端口外网可访问（检查服务器防火墙 `ufw status`，以及云服务商安全组是否放行 80 端口）。

国内服务器如果 80/443 端口被运营商封锁，可以改用 Cloudflare 的 DNS 验证方式申请证书：

```auto
certbot --nginx -d your-domain.com --preferred-challenges dns

```

或者直接使用 Cloudflare 提供的 15 年源证书（不推荐），更简单的方案是用 Cloudflare 的代理模式，在 Cloudflare 侧开启 HTTPS，服务器只需监听 80 端口即可。

* * *

**MySQL 连接失败（安装页面报错）** ：安装向导里填数据库地址时， **一定要填 `mysql` 而不是 `localhost`** 。因为 Mtab 和 MySQL 跑在不同的容器里，`localhost` 指向的是 Mtab 容器自身，正确的数据库主机名是 `docker-compose.yml` 中定义的 MySQL 服务名称。

* * *

**容器日志查看技巧** ：遇到任何问题，先看日志再动手：

```auto
docker compose logs # 查看所有容器的日志
docker compose logs mysql # 只看 MySQL 日志
docker compose logs mtab # 只看 Mtab 日志
docker compose logs --tail 100 # 只看最后100行

```

* * *

## **八、日常维护与备份策略**

### **8.1 定期备份数据**

Mtab 的所有数据都保存在 `/opt/mtab` 目录下（包含 MySQL 数据和程序文件）。写一个脚本定时打包：

```auto
#!/bin/bash
BACKUP_DIR="/root/backups"
mkdir -p $BACKUP_DIR
tar -czf $BACKUP_DIR/mtab-$(date +%Y%m%d-%H%M%S).tar.gz -C /opt/mtab .

```

配合 crontab 每周日凌晨 3 点执行：

```auto
crontab -e
# 添加一行
0 3 * * 0 /root/backup_mtab.sh

```

恢复时，解压到新服务器的 `/opt/mtab`，然后 `docker compose up -d` 即可。

### **8.2 更新 Mtab 版本**

当官方发布新版本时，更新非常无脑：

```auto
cd /opt/mtab
docker compose pull
docker compose up -d

```

`pull` 拉取最新镜像，`up -d` 会销毁旧容器并创建新容器，但数据卷不受影响，配置和链接全部保留。

### **8.3 查看容器运行日志**

如果某天发现服务异常，第一时间查日志：

```auto
docker logs --tail 100 mtab

```

* * *

## **九、最终效果与心得**

经过以上步骤，我的 Mtab 变成了这样：

- 浏览器一打开就是自己设计的导航页，背景是我最喜欢的星空图。
- 分类清晰：开发、日常、娱乐、工具。
- 右上角显示实时天气和当前时间。
- 搜索框默认用必应。
- 手机端自适应，完美代替系统书签。

**Mtab 相比同类项目（如 Flare）最大的优势就是后台可视化操作** ，想增删改直接点鼠标，不用对着 YAML 或 JSON 配置文件苦哈哈地改。虽然官方文档比较简洁，但实际部署下来异常稳定，跑了快两个月没崩过。

* * *

**附录：完整命令速查表（一键复制）**

```auto
# 更新系统与安装基础工具
apt update && apt upgrade -y
apt install curl wget vim git ufw -y

# 安装 Docker（官方脚本）
curl -fsSL https://get.docker.com | bash -s docker

# 部署 Mtab
mkdir -p /opt/mtab && cd /opt/mtab
vim docker-compose.yml # 粘贴文章中的 YAML 内容
docker compose up -d

# 修复目录权限（如果容器反复重启）
chown -R 1000:1000 /opt/mtab/data /opt/mtab/uploads

# 安装 Nginx 和 Certbot
apt install nginx certbot python3-certbot-nginx -y
vim /etc/nginx/sites-available/mtab # 配置反向代理
ln -s /etc/nginx/sites-available/mtab /etc/nginx/sites-enabled/
nginx -t && systemctl reload nginx
certbot --nginx -d your-domain.com

```
