Discourse 官方安装部署指南

用官方 discourse_docker 工具包部署 Discourse v2026.9.0:discourse-setup 交互向导实录(33GB 内存自动调优 db_shared_buffers=4096MB/UNICORN_WORKERS=8)、containers/app.yml 逐段配置(8125→80 端口映射、SMTP 中继、构建代理)、launcher rebuild 构建全过程回显(PostgreSQL 18 初始化、docker_manager 插件克隆 d-compat/2026.9 分支、db:migrate、资源预编译)、部署后验证与 rake admin:create 管理员创建实测。

Discourse安装部署DockerPostgreSQL2026/10/19

Discourse 官方安装部署指南

目标:用官方唯一支持的 discourse_docker 工具包,在单机完整部署 Discourse v2026.9.0,覆盖安装向导交互实录、配置文件逐段解析、构建(bootstrap/rebuild)全过程真实回显、部署后验证、管理员账号创建与日常运维命令族。逐命令实测(真实回显)。版本与选型背景见《Discourse v2026.9.0 介绍与选型指南》。

一、环境信息

  • 实测服务器:Ubuntu 22.04.4 LTS(内核 6.8.0-138-generic),x86_64,12 核 CPU,安装向导实查内存 33GB,磁盘 786G(可用 453G)
  • Docker Engine 29.8.1(build 4a63305)
  • Discourse 版本:v2026.9.0(2026-09-22 官方月度发布,构建时 app.yml 中 version: v2026.9.0 锁定)
  • 部署工具:discourse_docker 官方主分支(克隆时 HEAD 提交 1deba5f,DEV: Build a Ruby 4.0 test image (#1139),2026-10-16)
  • 工具包目录:/opt/data/quzuo/discourse-v2026.9.0(官方文档建议放 /var/discourse,路径可自选;但数据卷固定落在 /var/discourse/shared/standalone,见 app.yml volumes 段)
  • 端口映射:宿主 8125 → 实例内 80
  • 构建网络出口:HTTP 代理 192.168.1.62:7897(构建期克隆插件代码需要外网访问)
  • 实测产物镜像:local_discourse/app:latest(5.79GB,由官方基础镜像 discourse/base:2.0.20260915-0028 构建而来)、向导镜像 discourse/setup-wizard:release(539MB)
  • 数据落盘:/var/discourse/shared/standalone(部署完成实测 94M,含 PostgreSQL 数据、Redis 数据、上传文件、日志、备份目录)

1.1 网络形态说明(与批次子网约定的偏差记录)

discourse_docker 的启动模板(templates/web.template.yml)不提供自定义网络参数,./launcher 生成的启动命令默认将实例接入 Docker 默认 bridge 网络(实测本实例 IP 10.0.0.6/24,网关 10.0.0.1)。本批次预分配的 10.89.53.0/24 子网槽位因此未使用——这是官方工具链的固有限制,非配置遗漏;生产部署同样使用默认 bridge,仅通过端口映射对外暴露服务,不影响功能。SMTP 中继通过网关地址 10.0.0.1 回流宿主实现(见 4.3 节)。

二、官方安装形态说明

Discourse 官方唯一支持的安装途径是 discourse_docker 工具包(https://github.com/discourse/discourse_docker),其工作模型与常见应用不同:

  1. 一体化实例:官方基础镜像 discourse/base 内置 Ubuntu + Ruby + PostgreSQL 18 + Redis + nginx 全套依赖,配置文件(YAML 模板)经 pups 引导器在构建期执行,产出本地镜像 local_discourse/app;
  2. 声明式配置:站点所有参数集中在唯一配置文件 containers/app.yml,改动配置后通过 rebuild 重建实例生效;
  3. 数据外置:PostgreSQL/Redis 数据、上传文件、日志全部落在宿主 /var/discourse/shared/standalone,重建实例不丢数据;
  4. 命令族运维:启动、停止、重建、进入、日志等全生命周期操作由 ./launcher 一个入口完成(命令族清单见第六章)。

安装路径有两条(均出自官方仓库):install-discourse 一键脚本(内部仍是克隆工具包 + 运行向导),或手动克隆后运行 ./discourse-setup 交互向导。本文采用后者,对每一步都有完整回显。

三、前置条件

3.1 官方硬性校验项

运行 ./discourse-setup 时向导自动执行以下校验(实测回显见 4.2 节):

校验项要求实测结果
运行用户root✓ Running as root
Docker已安装可用✓ Docker is available
内存最低 1GB;≤4GB 时强制要求先创建 2GB swap,否则拒绝继续33GB,未触发 swap 分支
磁盘最低 5GB453G 可用
域名必须是可解析的 DNS 域名,纯 IP 会被向导直接拒绝(提示 "Discourse requires a DNS hostname. IP addresses are unsupported and will not work.")使用 discourse.quzuo.net

3.2 域名与 SMTP 的实验环境处理

  • 域名:本机无公网 DNS,在宿主 /etc/hosts 添加映射后向导接受配置(实验环境做法;生产环境必须配置真实 DNS A 记录指向服务器):
127.0.0.1 discourse.quzuo.net
  • SMTP:向导阶段先选择暂不配置 SMTP(可跳过);实例启动前在 app.yml 补上本机中继地址(4.3 节),指向宿主网关上监听 1025 端口的轻量 SMTP 收信端(python3 smtpd 形态,仅收信落盘、不外发)。生产环境应替换为真实 SMTP 服务商或自建邮件服务参数。

3.3 网络出口

构建期需要从 GitHub 克隆官方插件(docker_manager 等),并拉取基础镜像。内网环境先确认代理可用:

# curl -x http://192.168.1.62:7897 -sI https://github.com -o /dev/null -w '%{http_code}\n'
200

四、部署步骤

4.1 克隆官方工具包

# export https_proxy=http://192.168.1.62:7897 http_proxy=http://192.168.1.62:7897
# git clone https://github.com/discourse/discourse_docker.git /opt/data/quzuo/discourse-v2026.9.0
# cd /opt/data/quzuo/discourse-v2026.9.0
# git log --oneline -3
1deba5f DEV: Build a Ruby 4.0 test image (#1139)
a0807d9 DEV: Build a temporary Ruby 4 web only image in parallel (#1138)
945d491 FIX: correct the `openssl verify` command in the LE template

4.2 运行安装向导 discourse-setup(实录)

# ./discourse-setup --skip-rebuild --skip-connection-test

--skip-rebuild 表示本轮只生成配置不立即构建(便于先补齐 SMTP/代理配置再一次性构建);--skip-connection-test 跳过向导的域名连通性外呼(实验域名无真实 DNS,必跳)。新版本向导是图形化 TUI(官方 discourse/setup-wizard:release 镜像驱动),实测交互依次为:

  1. Email address for admin account(s)? → 输入 admin@quzuo.net
  2. Do you have a domain name for your Discourse? → y
  3. Hostname for your Discourse? → discourse.quzuo.net
  4. Configure SMTP for sending emails? (Requires SMTP credentials) → n(稍后手工补配置)
  5. Does this look right? → y

实测关键回显(系统自检与自动调优):

── System Checks ──

[1/5] Verifying system requirements
✓ Running as root
✓ Docker is available
✓ Memory: 33GB, CPU: 12 cores

── Review Configuration ──

╭─────────────────────────────────────────────────────────╮
│                                                         │
│  Hostname       discourse.quzuo.netdiscourse.quzuo.net  │
│  Admin Email    admin@quzuo.netadmin@quzuo.net          │
│  SMTP           (not configured)                        │
│  Let's Encrypt  Enabled                                 │
│                                                         │
╰─────────────────────────────────────────────────────────╯

Does this look right?

→ Found 33GB of memory and 12 CPU cores
→ Setting db_shared_buffers = 4096MB
→ Setting UNICORN_WORKERS = 8

── Network Validation ──

[4/5] Verifying domain configuration
→ Skipping connection test (--skip-connection-test)

── Saving Configuration ──

[5/5] Writing configuration file
✓ Configuration saved to containers/app.yml
✓ Configuration saved to containers/app.yml

✓ Discourse has been configured successfully!

✓ Updates successful. --skip-rebuild requested.

说明:Review 框中主机名/邮箱出现两次是 TUI 渲染残影(终端重绘叠字),配置文件中的实际值是单个;Let's Encrypt Enabled 是向导默认推荐项,因本次走非标准端口(8125)无 443,最终配置中未保留 SSL 模板(见 4.3)。

向导的自动调优逻辑值得注意:内存与 worker 数由向导按机器规格自动计算——33GB 内存对应 db_shared_buffers = 4096MB、UNICORN_WORKERS = 8,小内存机器会得到更保守的值,一般无需手工覆盖。

4.3 完成 containers/app.yml(SMTP、代理、端口、版本锁定)

向导生成配置后,编辑 containers/app.yml 补齐四处(完整文件如下,可直接对照):

templates:
  - templates/postgres.template.yml
  - templates/redis.template.yml
  - templates/web.template.yml
  - templates/web.ratelimited.template.yml
expose:
  - "8125:80"
params:
  db_default_text_search_config: pg_catalog.english
  db_shared_buffers: 4096MB
  version: v2026.9.0
env:
  LC_ALL: en_US.UTF-8
  LANG: en_US.UTF-8
  LANGUAGE: en_US.UTF-8
  DISCOURSE_HOSTNAME: "discourse.quzuo.net"
  DISCOURSE_DEVELOPER_EMAILS: "admin@quzuo.net"
  DISCOURSE_SMTP_ADDRESS: 10.0.0.1
  DISCOURSE_SMTP_PORT: 1025
  DISCOURSE_NOTIFICATION_EMAIL: noreply@discourse.quzuo.net
  DISCOURSE_SMTP_DOMAIN: discourse.quzuo.net
  HTTP_PROXY: http://192.168.1.62:7897
  HTTPS_PROXY: http://192.168.1.62:7897
  http_proxy: http://192.168.1.62:7897
  https_proxy: http://192.168.1.62:7897
  NO_PROXY: localhost,127.0.0.1
  no_proxy: localhost,127.0.0.1
  UNICORN_WORKERS: 8
volumes:
  - volume:
      host: "/var/discourse/shared/standalone"
      guest: "/shared"
  - volume:
      host: "/var/discourse/shared/standalone/log/var-log"
      guest: "/var/log"
hooks:
  after_code:
    - exec:
        cd: "$home/plugins"
        cmd:
          - git clone https://github.com/discourse/docker_manager.git
run:
  - exec: echo "Beginning of custom commands"
  - exec: echo "End of custom commands"

逐段说明:

段作用本机取值要点
templates构建模板组合postgres+redis+web+ratelimited 四件套为标准 standalone 形态;如需 443 直出再追加 web.ssl.template.yml 与 web.letsencrypt.ssl.template.yml
expose端口映射"8125:80" 宿主 8125 访问实例 80;务必加引号,避免 YAML 把 80:80 之类解析成六十进制
params.version版本锁定v2026.9.0,不写则构建主分支最新代码,生产必须锁版本
env.DISCOURSE_SMTP_*邮件出口DISCOURSE_SMTP_ADDRESS: 10.0.0.1 是实例可见的宿主网关地址(默认 bridge 网络下固定),1025 为宿主中继端口
env.HTTP_PROXY 等构建期代理构建阶段在实例内 git clone 插件需要外网出口;NO_PROXY 排除本机回环
volumes数据外置PostgreSQL/Redis/上传/日志全部落在 /var/discourse/shared/standalone,重建实例不丢数据
hooks.after_code官方插件docker_manager 是官方升级管理插件(后台升级页面的后端),标准必装

向导随后生成的备份文件自动落在 containers/app.yml.2026-10-19-104807.bak(向导重配置时自动保存上一版)。

4.4 构建并启动:./launcher rebuild app

配置就绪后执行构建(rebuild = 销毁旧实例 → bootstrap 构建镜像 → 启动新实例,首次部署时旧实例不存在,效果等同于 bootstrap + start):

# ./launcher rebuild app

实测构建全过程关键回显(完整日志约 990 行,以下摘录里程碑):

① 拉取官方基础镜像并启动 pups 引导器:

x86_64 arch detected.
2.0.20260915-0028: Pulling from discourse/base
Digest: sha256:5028d077b061225507e7093fda1ff5bdc64d483b5c0397776f9a52c50008cd9b
Status: Image is up to date for discourse/base:2.0.20260915-0028
/usr/local/lib/ruby/gems/3.4.0/gems/pups-1.4.0/lib/pups.rb
/usr/local/bin/pups --stdin
I, [2026-10-19T10:58:01.015238 #1]  INFO -- : Reading from stdin

② PostgreSQL 18 初始化,数据目录重定位到 /shared:

I, [2026-10-19T10:58:01.034005 #1]  INFO -- : Replacing data_directory = '/var/lib/postgresql/18/main' with data_directory = '/shared/postgres_data' in /etc/postgresql/18/main/postgresql.conf
I, [2026-10-19T10:58:01.035224 #1]  INFO -- : Replacing (?-mix:#?shared_buffers *=.*) with shared_buffers = $db_shared_buffers in /etc/postgresql/18/main/postgresql.conf
I, [2026-10-19T10:58:01.036758 #1]  INFO -- : Replacing (?-mix:^#local +replication +postgres +peer$) with local replication postgres  peer in /etc/postgresql/18/main/pg_hba.conf

③ 克隆官方插件 docker_manager 并自动切换到版本兼容分支:

I, [2026-10-19T10:58:26.923138 #1]  INFO -- : > cd /var/www/discourse/plugins && git clone https://github.com/discourse/docker_manager.git
Cloning into 'docker_manager'...
checking out compatible docker_manager version: origin/d-compat/2026.9

(d-compat/2026.9 分支是构建器按 params.version 自动匹配的插件兼容版本,这正是 4.3 锁定版本的价值——插件与主程序版本严格对齐。)

④ 数据库迁移与前端资源预编译:

I, [2026-10-19T10:58:50.621847 #1]  INFO -- : > cd /var/www/discourse && su discourse -c 'bundle exec rake db:migrate'
...
Done 'js/plugins/docker_manager_admin.BXRCud-mij58pp3.digested.js' : 0.0 secs
precompile target: docker_manager (cached)
precompile target: docker_manager_rtl

⑤ 构建收尾:

I, [2026-10-19T10:59:30.656522 #1]  INFO -- : Terminating async processes
2026-10-19 10:59:30.796 UTC [45] LOG:  database system is shut down
Successfully bootstrapped, to startup use ./launcher start app
BOOTSTRAP EXIT: 0

⑥ rebuild 完成后替换实例(销毁旧容器并以最终配置启动):

Removing old container
+ /usr/bin/docker rm app
app
+ /usr/bin/docker run --shm-size=512m -d --restart=always -e LANG=en_US.UTF-8 -e RAILS_ENV=production -e UNICORN_WORKERS=8 ... -e DISCOURSE_HOSTNAME=discourse.quzuo.net -e DISCOURSE_SMTP_ADDRESS=10.0.0.1 -e DISCOURSE_SMTP_PORT=1025 ... -h ops-app -e DOCKER_HOST_IP=10.0.0.1 --name app -t -p 8125:80 -v /var/discourse/shared/standalone:/shared -v /var/discourse/shared/standalone/log/var-log:/var/log --mac-address 02:ce:09:75:e2:b8 local_discourse/app /sbin/boot
9513b8610cac5e36937b75061c5cdd60e093b58cbb999dc42dfed671d413c9e4
REBUILD EXIT: 0

(docker run 完整参数过长,中段以 ... 略——完整可见于构建日志;值得注意 launcher 自动附加了 --restart=always(宿主重启后实例自启)、--shm-size=512m 与固定 MAC 地址。)

首次启动后约 20 秒内 Unicorn worker 逐个就绪(docker logs app 实测回显):

I, [2026-10-19T11:55:07.659283 #98]  INFO -- : worker=5 gen=0 pid=822 registered
I, [2026-10-19T11:55:07.705179 #822]  INFO -- : worker=5 gen=0 pid=822 ready
I, [2026-10-19T11:55:09.772051 #874]  INFO -- : worker=7 gen=0 pid=874 ready

4.5 防火墙与端口核对

# ss -ltnp | grep 8125
LISTEN 0      4096         0.0.0.0:8125       0.0.0.0:*    users:(("docker-proxy",pid=223149,fd=8))
LISTEN 0      4096            [::]:8125       [::]:*    users:(("docker-proxy",pid=223155,fd=8))

如宿主启用 ufw/firewalld,放行对应端口(ufw allow 8125/tcp);本机未启用防火墙,无此步骤。

4.6 创建管理员账号(rake admin:create 实测)

向导只登记了管理员邮箱;由于实验 SMTP 只收信不外发,无法走邮件注册链接,管理员账号用官方 rake 任务直接创建/激活(该任务同时把账号设为 admin 并强制激活,绕过邮件验证):

# docker exec -it app rake admin:create

对已存在账号(重置密码 + 确保管理员身份)实测回显:

Email:  admin@quzuo.net
User with this email already exists! Do you want to reset the password for this email? (Y/n)  Y
Password:  ********
Repeat password:  ********
Password is the same as your current password.
Email:

(对新邮箱则直接进入 Password 设置并最终输出 Admin account created;密码重复输入一致后账号即被置为管理员并激活。任务会循环回到 Email: 提示,直接回车空邮箱退出。)

账号状态复核:

# docker exec app rails runner "u=User.find_by(username: 'admin'); puts \"email=#{u.email} admin=#{u.admin?} active=#{u.active?}\""
email=admin@quzuo.net admin=true active=true

⚠️ 注意:rake admin:create 是交互式任务,重复执行对已有账号是幂等的(重置密码、确认激活),可用于找回管理员密码。

五、部署验证

逐项实测:

# docker ps --filter name=app
CONTAINER ID   IMAGE                   STATUS         PORTS
app 对应行     local_discourse/app     Up ...         0.0.0.0:8125->80/tcp, [::]:8125->80/tcp

# curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8125/
200

# curl -s -o /dev/null -w 'srv/status -> %{http_code}\n' http://127.0.0.1:8125/srv/status
srv/status -> 200

# curl -s http://127.0.0.1:8125/about.json | python3 -c "import json,sys; a=json.load(sys.stdin)['about']; print(a['version'], '|', a['title'], '| https:', a['https'])"
2026.9.0 | Discourse | https: False

版本双重核对(站点外 vs 实例内):

# docker exec app rails runner 'puts Discourse::VERSION::STRING'
2026.9.0

资源占用实测(空载,8 worker 配置):

# docker stats --no-stream --format 'table {{.Name}}\t{{.MemUsage}}\t{{.CPUPerc}}' app
NAME     MEM USAGE / LIMIT    CPU %
app      1.581GiB / 31.3GiB   0.68%

数据落盘核对:

# ls /var/discourse/shared/standalone/
backups  log  postgres_data  postgres_run  redis_data  state  tmp  uploads
# du -sh /var/discourse/shared/standalone
94M     /var/discourse/shared/standalone

浏览器访问 http://<宿主IP>:8125/ 应看到 Discourse 站点首页。管理员账号创建见 4.6 节;站点初始化向导与后台管理实操见《Discourse 快速入门与实战示例》。

六、日常运维

6.1 launcher 命令族

./launcher(无参数)输出的官方命令清单:

Usage: launcher COMMAND CONFIG [--skip-prereqs] [--docker-args STRING]
Commands:
    start:       Start/initialize a container
    stop:        Stop a running container
    restart:     Restart a container
    destroy:     Stop and remove a container
    enter:       Open a shell to run commands inside the container
    logs:        View the Docker logs for a container
    bootstrap:   Bootstrap a container for the config based on a template
    run:         Run the given command with the config in the context of the last bootstrapped image
    rebuild:     Rebuild a container (destroy old, bootstrap, start new)
    cleanup:     Remove all containers that have stopped for > 24 hours
    start-cmd:   Generate docker command used to start container

常用组合:

./launcher stop app        # 停站(数据保留)
./launcher start app       # 起站
./launcher restart app     # 重启
./launcher logs app        # 应用日志(Unicorn/Sidekiq/nginx 合流输出)
./launcher enter app       # 进入实例排障(内部即为完整 Discourse 运行环境)

6.2 升级(版本变更)

两种官方途径:

  1. 命令行全量重建(本文实测路径):更新 app.yml 中 params.version 为目标版本后执行 ./launcher rebuild app,构建器自动拉取对应版本代码并匹配插件兼容分支;
  2. 后台在线升级(docker_manager 插件):管理员登录后进入 /admin/upgrade,页面上一键升级,适合小版本跟进;命令行重建优先级更高、更可控。

工具包本体也随官方仓库更新,升级前可先 git pull 工具包目录再 rebuild。

6.3 日志与排障入口

位置内容
./launcher logs app实例主日志(Unicorn worker、Sidekiq、启动过程)
/var/discourse/shared/standalone/log/var-log/nginx/nginx 访问/错误日志(宿主可直接读)
/var/discourse/shared/standalone/log/rails/Rails 产物日志(production.log、sidekiq.log 等)
./discourse-doctor官方诊断脚本:核对 Docker、磁盘、内存、域名解析、端口占用、配置文件一致性
https://try.discourse.org / meta.discourse.org官方演示站与官方支持社区

6.4 备份与恢复

官方形态是站点内打包:管理员后台 /admin/backup 触发备份,产物为 .tar.gz 落在 /var/discourse/shared/standalone/backups/(实测目录已存在),后台可直接下载;恢复用后台 /admin/backup 的还原入口或 ./launcher enter app 内执行 discourse restore 流程。数据库物理文件在 /var/discourse/shared/standalone/postgres_data/,停站状态下可直接文件级快照,但跨大版本恢复建议用官方备份产物而非裸拷数据目录。

6.5 资源调优备忘

  • db_shared_buffers 与 UNICORN_WORKERS:向导按内存自动设定(本机 33GB → 4096MB / 8),手动改小机器配置后需同步修正这两个值;
  • 官方最低 1GB 内存可装,但 2GB 以下体验明显吃力(Ruby 进程 + PostgreSQL + Sidekiq 常驻),生产建议 2GB 起步;
  • --shm-size=512m 由 launcher 自动附加,缺省 64MB shm 会导致 Unicorn 异常退出,排障时留意。

七、卸载与清理

官方序列(按 ./launcher 命令定义与镜像清单整理;实测站点需保留运行,销毁步骤未在本机执行,命令语义均经 ./launcher 帮助输出与 docker images 实查核对):

cd /opt/data/quzuo/discourse-v2026.9.0

# 1. 停止并移除实例(destroy = stop + rm,数据卷不删)
./launcher destroy app

# 2. 删除数据目录(含 PostgreSQL 数据/上传/备份,不可逆,删前确认已备份)
rm -rf /var/discourse/shared/standalone

# 3. 删除镜像(构建产物 + 官方基础镜像 + 向导镜像)
docker rmi local_discourse/app:latest
docker rmi discourse/base:2.0.20260915-0028
docker rmi discourse/setup-wizard:release

# 4. 删除工具包目录(可选)
# rm -rf /opt/data/quzuo/discourse-v2026.9.0

两点提示:

  • 只删实例不删数据是安全的:./launcher destroy app 后重建(改好 app.yml 再 ./launcher rebuild app 或 ./launcher bootstrap app && ./launcher start app),原站点数据完整回归(数据全部在 /var/discourse/shared/standalone);
  • 若同时要清理 docker setup-wizard 类向导镜像与构建缓存,可再执行 docker builder prune(构建缓存实测占用显著,本机构建期缓存约 1.2GB 量级)。

八、常见问题

Q1:≤4GB 内存机器装不上? 向导检测到内存 ≤4GB 时强制要求先创建 2GB swap(官方脚本逻辑),否则拒绝继续。fallocate -l 2G /swapfile && chmod 600 /swapfile && mkswap /swapfile && swapon /swapfile 后重试即可;同时把 UNICORN_WORKERS 调到 2、db_shared_buffers 调到 256MB 左右。

Q2:向导拒绝我的 IP 地址? 官方明确不支持纯 IP 站点(注册邮件链接、防垃圾校验都依赖域名)。必须有可解析域名;内网实验可在 hosts 里映射后通过向导(本文做法),但浏览器访问同样需要配 hosts。

Q3:bootstrap 阶段 git clone 超时/失败? 实例构建期需要访问 GitHub(拉主程序、克隆插件)。内网环境把代理写进 app.yml 的 env 段(HTTP_PROXY/HTTPS_PROXY,本文 4.3 实测有效)再 rebuild;公网机器检查 DNS 与 443 出口。

Q4:改了 app.yml 不生效? 配置在构建期烧录,改完必须 ./launcher rebuild app;仅 restart 不会应用配置变更。

Q5:rebuild 会丢数据吗? 不会。数据全在 /var/discourse/shared/standalone(挂载卷),rebuild 只替换镜像与实例层。但稳妥起见,大版本升级前在后台做一次备份(见 6.4)。

Q6:非 80 端口映射后站点内链接跳到 80? Discourse 站点内链接是相对路径,经 http://IP:8125/ 访问不受影响;但页脚/邮件里出现的绝对地址取决于 DISCOURSE_HOSTNAME。如需对外正式服务,建议前置 nginx 反代 + 真实域名 + Let's Encrypt 模板(web.ssl.template.yml)。

Q7:忘了管理员密码? docker exec -it app rake admin:create 重置(4.6 节实测,幂等操作)。

九、参考链接

  1. 官方部署工具包 discourse_docker:https://github.com/discourse/discourse_docker
  2. 官方安装文档 INSTALL-cloud.md:https://github.com/discourse/discourse/blob/main/docs/INSTALL-cloud.md
  3. 官方管理员工具文档(Admin Console / rake 任务):https://meta.discourse.org/t/create-an-administer-account-from-the-command-line/194429
  4. Discourse 官方仓库:https://github.com/discourse/discourse
  5. 《Discourse v2026.9.0 介绍与选型指南》(版本事实与选型对比)
  6. 《Discourse 快速入门与实战示例》(站点初始化与后台管理实测)