⚠ 无法通过主机名 metabolism.logophilia.eu 访问此计算机的 443 端口 ----

感谢反馈,真的很感激您花时间。虽然这么说有点自作聪明,但:

[2/5] 正在准备配置
✓ 端口 80 和 443 可供使用

确实一开始就显示“可供使用”。不过,在 Gemini 的帮助下(主要是关于 Docker 的各种用法,哈哈),我的实例现在已经正常运行了。我想为其他 Virtualmin 用户提供我的“运行手册”,因为:“释放 443 端口”并不是这里的解决方案。我接下来的内容就是这份手册。如果我觉得应该把它发到其他地方,比如新线程,请告诉我该去哪里;我想不止我一个人有这种设置,这对其他人可能也有用。再次感谢!

如果您使用的是由 Webmin/Virtualmin 管理的 VPS,并且使用了子域名:

终极 Virtualmin + Discourse 运行手册 *

  • (1) 清理残留(如果是重试,像我之前那样):

    rm -rf /var/discourse/shared/standalone/ssl/*

    rm -rf /var/discourse/shared/standalone/letsencrypt

    rm -rf /var/discourse/shared/standalone/state

  • (2) 删除模板:

    您必须完全删除app.yml 中的 templates/web.ssl.template.ymltemplates/web.letsencrypt.ssl.template.yml 行。即使前面加了 #,自定义的启动器解析器仍然会评估它们。

  • (3) 电子邮件设置与变量:

    DISCOURSE_SKIP_EMAIL_SETUP'1' 改为 '0',因为否则您的 Discourse 将无法连接并检查 DiscordID;

    添加 DISCOURSE_FORCE_HTTPS: true,以便后端生成安全的 URL。

    温馨提示:确保您的 DISCOURSE_SMTP_USER_NAME 设置为您的原始邮箱账户名(例如 'logophilia'),而不是完整的电子邮件地址(例如 'logophilia@logophilia.eu'),并将凭实用单引号(')括起来,以绕过潜在的 YAML 字符解析错误。

  • (4) 暴露块配置:

    确保您的 app.yml 中的 expose: 块包含一个 HTTP 映射;映射 443=>8443 是可选的/多余的,因为 Virtualmin 在传递之前已经终止了 SSL 逻辑:

    expose:
      - 8080:80
    

    现在您可以开始重建了:

    cd /var/discourse
    ./launcher rebuild app
    
  • (5) 子域名和代理路径设置:

    • 像往常一样在 Virtualmin 中创建您的子域名,并用 Let’s Encrypt SSL 证书保护它(自动完成,只是提醒:确保不会因为任何无关原因报错)。
    • 导航到代理路径(Virtualmin → 您的子域名 → Web 配置 → 代理路径),创建一个新的映射 /http://localhost:8080/,保持“本地服务”未勾选,但将代理 WebSocket 切换为,以允许实时更新和通知流。
  • (6) CSRF 头指令:

    • Webmin ➔ 服务器 ➔ Apache Webserver ➔ [找到您的子域名配置并点击 443 的配置] ➔ 编辑指令 中,将以下行放在 Virtualmin 自己的 Let’s Encrypt 代理块上方(通常是 ProxyPass /.well-known !),以促进 CSRF 令牌的转发:
    ProxyPreserveHost On
    RequestHeader set X-Forwarded-Proto "https"
    RequestHeader set X-Forwarded-For %{REMOTE_ADDR}s
    

    ProxyPreserveHost On:告诉 Discourse 您的实际域名,而不是“localhost”。
    RequestHeader set X-Forwarded-Proto "https":明确告诉 Discourse 用户正在使用安全连接,与您的 DISCOURSE_FORCE_HTTPS: true 设置相匹配。
    RequestHeader set X-Forwarded-For:将访问者的真实 IP 地址传递给容器,以便安全日志正常工作。

  • (7) 干净的容器握手:

    在漫长的(抱歉……但这是真的;-) 重建过程完成时,确保使用 docker rm -f app 清除任何可能卡住的容器蓝图,这样运行 ./launcher start app 就会启动一个完全绑定到端口 8080 的全新实例。检查 docker ps 是否在“端口”下显示类似以下内容:

    # docker ps
    CONTAINER ID   IMAGE                 COMMAND        CREATED          STATUS          PORTS                                                                                NAMES
    d21772a21e36   local_discourse/app   "/sbin/boot"   45 minutes ago   Up 45 minutes   0.0.0.0:8080->80/tcp, [::]:8080->80/tcp, 0.0.0.0:8443->443/tcp, [::]:8443->443/tcp   app
    

    (如您所见,我在 app.yml 中保留了 443=>8443 指令,两种方式都可以。)

  • (8) 监控与启动:

    使用 docker logs -f app 跟踪启动流,直到数据库迁移完成且工作人员开始处理请求。基本上就是一连串的快速出现的“INFO”行。

  • (9) 最终化:

    在浏览器中加载您的子域名,点击注册,让系统向您的邮箱发送验证邮件。

*)直到被证明是错误的 :wink: