如果你已经不想再用 WordPress 做所有内容后台,又觉得 Contentful、Strapi Cloud、各种 SaaS CMS 的费用和限制不太可控,Directus 自部署是一个很适合 VPS 用户的选择。
Directus 的定位不是“再造一个博客系统”,而是把 PostgreSQL、MySQL 等数据库变成可视化后台、REST API、GraphQL API 和权限系统。你可以用它管理文章、商品、工具目录、内部数据、运营表单,也可以把它当成一个轻量 Backend-as-a-Service。
这篇文章重点讲生产可维护方案:Directus + PostgreSQL + Redis + Caddy + Docker Compose。它比“只跑一个 SQLite 容器”更适合长期使用,也比手写 Nginx + Certbot 更省心,因为 Caddy 可以自动申请和续期 HTTPS 证书。
适合以下几类用户:
- 想用 VPS 自建无头 CMS,而不是长期付 SaaS 订阅费。
- 想给 Next.js、Nuxt、Astro、Hugo 或小程序提供内容 API。
- 想搭建内部管理后台、工具目录、资源库、客户资料库。
- 已经会基本 SSH、Docker,但不想维护复杂 Kubernetes。
- 希望数据在自己的 VPS 和数据库里,迁移时不被平台锁死。
如果你只是想搭博客,站内的 VPS 搭建个人博客指南 会更直接。如果你正在做自动化工作流,可以看 VPS 搭建 n8n 自动化工作流。Directus 更适合“内容结构复杂、需要权限、需要 API”的场景。
Directus 本身不算重,真正吃资源的是数据库、图片上传、API 请求量和你写的扩展。
| 场景 | 建议配置 | 说明 |
|---|---|---|
| 个人内容后台、测试项目 | 1 核 2GB 内存 | 可以跑,但别放太多扩展 |
| 小团队 CMS、工具目录 | 2 核 4GB 内存 | 更稳,推荐起步档 |
| 多站点内容 API、内部系统 | 4 核 8GB 内存 | 数据库、缓存、备份更从容 |
| 大量图片/文件上传 | 另配对象存储 | 不要把大文件都堆在系统盘 |
硬盘建议至少 40GB 起步。Directus 的核心数据在数据库里,上传文件在 uploads 目录,扩展在 extensions 目录。后面备份时,这三块都要覆盖。
你需要:
- 一台 Ubuntu 22.04 / 24.04 VPS。
- 一个域名,例如
cms.example.com。 - DNS A 记录指向 VPS 公网 IP。
- 已开放 22、80、443 端口。
- Docker 和 Docker Compose 插件。
安装 Docker 可以参考站内的 Docker 相关文章;这里给一个最小检查:
docker --version
docker compose version
如果命令不存在,先安装 Docker Engine 和 Compose 插件,再继续。
sudo mkdir -p /opt/directus/{uploads,extensions,database,caddy}
sudo chown -R $USER:$USER /opt/directus
cd /opt/directus
建议不要把 Directus 放在 /root 下。后续备份、迁移、systemd 管理都会更清晰。
Directus 需要一个 SECRET,数据库也需要强密码。不要在生产环境使用 directus/directus 这种默认值。
openssl rand -hex 32
openssl rand -base64 32
把生成结果保存到密码管理器里。后面写 .env 会用到。
创建 .env:
nano .env
示例:
DIRECTUS_DOMAIN=cms.example.com
DIRECTUS_PUBLIC_URL=https://cms.example.com
POSTGRES_DB=directus
POSTGRES_USER=directus
POSTGRES_PASSWORD=replace-with-strong-db-password
DIRECTUS_SECRET=replace-with-random-secret
[email protected]
DIRECTUS_ADMIN_PASSWORD=replace-with-strong-admin-password
注意:
DIRECTUS_DOMAIN不要带https://。DIRECTUS_PUBLIC_URL必须和最终访问地址一致。- 管理员密码首次启动后可以在后台改,但初始值不要太弱。
创建 docker-compose.yml:
nano docker-compose.yml
填入:
services:
database:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- ./database:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
interval: 10s
timeout: 5s
retries: 5
cache:
image: redis:7-alpine
restart: unless-stopped
command: redis-server --appendonly yes
volumes:
- ./redis:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
directus:
image: directus/directus:11.17.0
restart: unless-stopped
depends_on:
database:
condition: service_healthy
cache:
condition: service_healthy
environment:
SECRET: ${DIRECTUS_SECRET}
PUBLIC_URL: ${DIRECTUS_PUBLIC_URL}
DB_CLIENT: pg
DB_HOST: database
DB_PORT: 5432
DB_DATABASE: ${POSTGRES_DB}
DB_USER: ${POSTGRES_USER}
DB_PASSWORD: ${POSTGRES_PASSWORD}
CACHE_ENABLED: "true"
CACHE_STORE: redis
CACHE_AUTO_PURGE: "true"
REDIS: redis://cache:6379
ADMIN_EMAIL: ${DIRECTUS_ADMIN_EMAIL}
ADMIN_PASSWORD: ${DIRECTUS_ADMIN_PASSWORD}
WEBSOCKETS_ENABLED: "true"
IP_TRUST_PROXY: "true"
volumes:
- ./uploads:/directus/uploads
- ./extensions:/directus/extensions
expose:
- "8055"
caddy:
image: caddy:2-alpine
restart: unless-stopped
depends_on:
- directus
ports:
- "80:80"
- "443:443"
- "443:443/udp"
volumes:
- ./caddy/Caddyfile:/etc/caddy/Caddyfile:ro
- caddy_data:/data
- caddy_config:/config
volumes:
caddy_data:
caddy_config:
这里有几个关键点:
- Directus 没有直接映射
8055:8055到公网,只暴露给 Docker 网络里的 Caddy。 - PostgreSQL 数据挂载到
./database,上传文件挂载到./uploads。 - Caddy 负责公网 80/443 和 HTTPS。
directus/directus:11.17.0是示例版本,实际生产建议固定一个你测试过的版本,不要长期使用latest。
创建 Caddyfile:
nano caddy/Caddyfile
写入:
{$DIRECTUS_DOMAIN} {
encode zstd gzip
reverse_proxy directus:8055
}
Caddy 的逻辑很简单:域名能解析到这台 VPS,80/443 端口能访问,Caddy 就会自动申请并续期证书。相比 Nginx + Certbot,配置更短,也更不容易忘记续期。
如果你的 DNS 还没生效,先不要启动 Caddy,否则证书申请可能失败。可以用:
dig +short cms.example.com
确认返回的是 VPS 公网 IP。
cd /opt/directus
docker compose pull
docker compose up -d
查看状态:
docker compose ps
docker compose logs -f directus
访问:
https://cms.example.com
使用 .env 里的管理员邮箱和密码登录。
上线不是看到登录页就结束。至少检查这些:
-
https://cms.example.com/server/ping返回正常。 - HTTP 会自动跳转 HTTPS。
- 登录后台后能创建一个测试 Collection。
- 能新增、读取、编辑一条测试数据。
- 能上传一张测试图片,重启后仍然存在。
-
docker compose restart后 Directus 能恢复。 -
docker compose logs directus没有反复报数据库连接错误。
如果访问页面 502,先看:
docker compose ps
docker compose logs caddy
docker compose logs directus
常见原因是 DNS 没指到 VPS、80/443 没开放、Directus 容器没启动、PUBLIC_URL 写错,或者 Caddyfile 域名写错。
Directus 生产环境至少备份三类数据:
- PostgreSQL 数据库。
uploads文件目录。extensions扩展目录和docker-compose.yml/.env配置。
数据库备份示例:
cd /opt/directus
docker compose exec -T database pg_dump -U "$POSTGRES_USER" "$POSTGRES_DB" > directus-$(date +%F).sql
但这条命令直接用宿主机环境变量时可能读不到 .env。更稳的方式是写一个备份脚本,显式读取 .env 或在容器里指定变量。站内已经有 VPS 备份恢复演练,建议把 Directus 纳入同一套恢复演练,而不是只做“看起来有备份”的压缩包。
Directus 是后台系统,不要裸奔:
- 管理员密码必须足够强,并开启团队内部的账号权限分级。
- 不要把 PostgreSQL、Redis 暴露到公网。
- 不要把 Directus 的 8055 端口直接开放给全网。
- Caddy 前面如果套 Cloudflare,确认 SSL 模式和真实源站访问策略。
- 定期更新 Directus 镜像,但更新前先备份数据库和上传文件。
- 如果只给内部团队使用,可以考虑再加 Cloudflare Access 或 Tailscale。
如果你不确定数据库远程访问怎么做,先看 VPS 数据库不要直接暴露公网。如果你担心源站 IP 暴露,可以参考 Cloudflare Tunnel 隐藏源站 IP。
看场景。
| 场景 | 更适合 |
|---|---|
| 传统博客、插件生态、主题市场 | WordPress |
| 前后端分离内容站 | Directus |
| 工具目录、资源库、内部后台 | Directus |
| 需要复杂权限和 API | Directus |
| 不想写前端,只想快速发文章 | WordPress |
| 内容要同步到多个前端 | Directus |
Directus 的优势是结构自由、API 直接、权限模型清晰;缺点是你通常还需要一个前端站点,比如 Next.js、Nuxt、Astro 或静态站生成器。它不是“装完就有完整主题市场”的传统建站工具。
1. 能不能用 SQLite?
测试可以,生产不建议。官方教程里有 SQLite 场景,但长期生产更推荐 PostgreSQL 或 MySQL,尤其是多人后台、频繁写入、扩展功能较多时。
2. Caddy 和 Nginx 选哪个?
如果你已经熟悉 Nginx,可以继续用 Nginx。新项目更推荐 Caddy,因为自动 HTTPS、配置短、续期省心。本文选择 Caddy 是为了降低维护成本。
3. VPS 需要多大内存?
个人使用 2GB 可以起步,小团队建议 4GB。Directus、PostgreSQL、Redis、Caddy 同机运行时,1GB 机器会比较紧张。
4. 上传图片越来越多怎么办?
中长期建议接 S3 兼容对象存储,或者至少把 uploads 单独备份。不要等系统盘满了才迁移。
5. 更新 Directus 会不会破坏数据?
任何 CMS 更新都有风险。不要直接 latest 拉新版本;先看 changelog,在测试环境验证,再备份生产数据库和上传文件后更新。
- 域名 A 记录指向 VPS。
- VPS 开放 80/443,8055 不对公网开放。
-
.env中的SECRET、数据库密码、管理员密码足够强。 - Docker Compose 固定 Directus 版本。
- PostgreSQL、uploads、extensions 都有备份策略。
- Caddy 自动 HTTPS 正常。
- 登录、创建数据、上传文件、重启恢复均测试通过。
Directus 很适合“我想把内容和数据掌握在自己手里,但又不想从零写后台”的 VPS 用户。用 Docker Compose 把 Directus、PostgreSQL、Redis 和 Caddy 组合起来,可以在一台普通 VPS 上得到一个可维护的无头 CMS 环境。
真正要注意的不是“能不能启动”,而是:数据库是否持久化、上传文件是否备份、HTTPS 是否自动续期、后台端口是否没有裸露、更新前是否能回滚。这些做好了,Directus 才能从一个测试容器变成真正可长期使用的内容后台。