确实,这需要一些试错,但我按如下方式使其生效(不保证这是最佳方法——事实上,我知道肯定有更好的方法——所以非常欢迎更正和改进):
pfaffman 移至 OP 的说明
首先,有两种方式可以访问您的 Discourse 实例:1. 暴露端口,2. 通过 WebSocket。我相信我在这个论坛上某处学到过,WebSocket 更快/更高效,所以我正在使用它,但暴露端口应该要容易得多,所以如果您无法让 WebSocket 工作,请尝试暴露端口(下面会详细介绍)。
因此,假设您已经完成了 30 分钟标准安装,并且假设您尚未让 Discourse 获取 Let’s Encrypt 证书——因为在使用反向代理时您不需要它。NPM 会处理此事。不过,如果您已经有了证书也没关系。NPM 只需获取一个新的证书即可。
1. 安装 NPM
下一步是安装 NPM,这样您就会多运行两个 Docker 容器(NPM 及其数据库容器)。
接下来就是您询问的棘手部分。
第一个障碍是 Discourse 运行在默认的 Docker bridge 网络上,而 NPM 默认运行在默认的“用户创建的网络”上(在我的例子中称为 npm_default),这意味着 NPM 无法看到 Discourse。![]()
2. 将所有容器带入默认的 bridge 网络
因此,只要 我不知道 Discourse 是否可以移动到自定义网络,我们就必须将 NPM 移动到默认的 bridge 网络。我们可以通过在 Docker Compose 文件 中的两个 NPM 容器添加 network_mode: bridge 来实现这一点。
3. 使用 IP 地址而不是服务名称
下一个问题是,如果您只是将其移动到 bridge 网络,标准的 Docker Compose 文件将不再起作用。NPM 将无法再找到其数据库容器。这是因为服务名称的内部 DNS 解析(Docker Compose 文件依赖于此)仅在用户创建的网络上可用,而在默认 Docker 网络上不可用。因此,我们不得不使用硬编码的 IP 地址(这就是为什么这绝对不是最佳解决方案,因为如果您的容器 IP 发生变化,它就会失效)。因此,您需要启动容器,即使您知道它无法工作,记下 NPM 数据库容器的 IP,并在您的 Docker Compose 文件中将 DB_MYSQL_HOST: "db" 替换为 DB_MYSQL_HOST: "<db_container_IP>"。
现在,所有容器都应该位于默认的 bridge 网络上,以便 NPM 可以看到 Discourse 及其数据库。
4. 使 Discourse 可访问
但是,“看到”Discourse 和能够访问它并不是一回事。因此,您需要确保 Discourse 会接受 NPM 转发给它的任何流量。如果您不在乎使用 WebSocket,我想您可以直接将 NPM 指向 Discourse 容器 IP 的 80 端口(而不是 443 端口),如下所示:
不过我还没有测试过这个。正如我所提到的,我使用的是 WebSocket 设置,这需要一些额外的步骤。请注意,当您使用 WebSocket 时,上述主机名/IP 和端口将被忽略。
5. 配置 app.yml 以使用 WebSocket
这在 OP 中有所解释,所以我不再赘述。
6. 在 NPM 容器中挂载 WebSocket
我们需要通过将其挂载为卷来让 NPM 访问 WebSocket:- /var/discourse/shared/standalone/nginx.http.sock:/var/discourse/shared/standalone/nginx.http.sock。这是对默认 NPM Docker Compose 文件的最终更改,因此以下是适用于我的最终版本:
version: '3'
services:
app:
image: 'jc21/nginx-proxy-manager:latest'
restart: unless-stopped
network_mode: bridge
ports:
- '80:80'
- '81:81'
- '443:443'
environment:
DB_MYSQL_HOST: "172.17.0.6"
DB_MYSQL_PORT: 3306
DB_MYSQL_USER: "npm"
DB_MYSQL_PASSWORD: "my-super-safe-pwd"
DB_MYSQL_NAME: "npm"
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
- /var/discourse/shared/standalone/nginx.http.sock:/var/discourse/shared/standalone/nginx.http.sock
db:
image: 'jc21/mariadb-aria:latest'
restart: unless-stopped
network_mode: bridge
environment:
MYSQL_ROOT_PASSWORD: 'my-super-safe-pwd'
MYSQL_DATABASE: 'npm'
MYSQL_USER: 'npm'
MYSQL_PASSWORD: 'my-super-safe-pwd'
volumes:
- ./data/mysql:/var/lib/mysql
7. 配置 NPM 以使用 WebSocket
最后一步:告诉 NPM 使用 WebSocket。据我回忆,仅仅开启“WebSocket 支持”是不够的,所以我从 OP 中的 NGINX 位置 复制到了“高级”选项卡,如下所示:
我在“自定义位置”选项卡下未能使其工作。
8. 别忘了激活 SSL
我没有在 NPM 中提到 SSL 配置,因为这似乎显而易见,而且我不认为在过程的哪个阶段激活它很重要。所以如果您还没有这样做,我的配置如下所示:
9. 最终免责声明
在我写这篇文章时,我突然想到,当我们使用 WebSocket 时,NPM 和 Discourse 甚至可能不需要在同一个 Docker 网络上。我现在没有时间检查这一点,但如果这是真的,那么您可以直接忘记上面的第 2、3 和 4 步,它应该就能工作。
支持论坛最迷人的方面在于:很好地描述您的问题往往会引导您找到解决方案,甚至无需发布您的问题。在这种情况下,我正在回答别人的问题,但也可能找到了自己问题的答案。![]()


