Ubuntu 22.04 LTS 首次安装后,http/https 无法接受连接

这并非我首次安装 Discourse,但在 Digital Ocean droplet(1GB NVMe SSD Premium AMD)上使用 Ubuntu 22.04 LTS 进行三次 标准安装 后,我还是卡住了。我按照指南操作,并像过去多次做过的那样提供了 Let’s Encrypt 所需的电子邮件地址。安装完成后,浏览器中既无法通过 A 记录也无法通过 droplet 的直接 IP 访问 Discourse。随后我确认了安装程序在 HTTP 和 HTTPS 端口上都拒绝连接,之后便一直百思不得其解。

安装过程中唯一奇怪的地方是,Digital Ocean 的 droplet 默认没有安装 Docker,而在检测到克隆 Discourse 容器需要它时,系统提示我进行安装。除此之外,我按正常流程操作,并测试了 Docker 和 Discourse 安装。

好消息——Discourse 成功执行了邮件可送达性测试,这表明安装已就位并正在运行,Docker 似乎也工作正常(运行了 docker run -it --rm hello-world 后确认)。我还 ping 了 github.com 并收到了响应,因此看起来并非防火墙或连接问题。

问题:连接被拒绝
然而,运行 curl -v localhost:8080 返回:

*   Trying 127.0.0.1:8080...
* connect to 127.0.0.1 port 8080 failed: Connection refused
*   Trying ::1:8080...
* connect to ::1 port 8080 failed: Connection refused
* Failed to connect to localhost port 8080 after 1 ms: Connection refused
* Closing connection 0

运行 curl -v localhost 返回:

*   Trying 127.0.0.1:80...
* Connected to localhost (127.0.0.1) port 80 (#0)
> GET / HTTP/1.1
> Host: localhost
> User-Agent: curl/7.81.0
> Accept: */*
>
* Empty reply from server
* Closing connection 0
curl: (52) Empty reply from server

以下是我的 app.yml 文件以及运行 discourse-doctor 的结果:

app.yml
 ## 支持多少并发 Web 请求?取决于内存和 CPU 核心数。
 ## 将根据检测到的 CPU 自动设置,也可手动覆盖
 UNICORN_WORKERS: 2

 ## TODO: 此 Discourse 实例将响应的域名
 ## 必填项。Discourse 无法仅通过 IP 地址运行。
 DISCOURSE_HOSTNAME: community.example.io

 ## 如果希望容器以与上述相同的
 ## 主机名(-h 选项)启动,请取消注释(默认为 "$hostname-$config")
 #DOCKER_USE_HOSTNAME: true

 ## TODO: 初始注册时将设为管理员和开发者的逗号分隔邮箱列表
 ## 示例:'user1@example.com,user2@example.com'
 DISCOURSE_DEVELOPER_EMAILS: 'example@example.com'

 ## TODO: 用于验证新账户和发送通知的 SMTP 邮件服务器
 # SMTP 地址、用户名和密码为必填项
 # 警告:SMTP 密码中的 '#' 字符可能导致问题!
 DISCOURSE_SMTP_ADDRESS: smtp.mailgun.org
 DISCOURSE_SMTP_PORT: 587
 DISCOURSE_SMTP_USER_NAME: no-reply@example.io
 DISCOURSE_SMTP_PASSWORD: "XXXXXX"
 #DISCOURSE_SMTP_ENABLE_START_TLS: true           # (可选,默认为 true)
 DISCOURSE_SMTP_DOMAIN: community.example.io
 DISCOURSE_NOTIFICATION_EMAIL: noreply@community.example.io

 ## 如果已添加 Let's Encrypt 模板,请取消注释以下行以获取免费 SSL 证书
 LETSENCRYPT_ACCOUNT_EMAIL: example@example.com

 ## 此 Discourse 实例的 HTTP 或 HTTPS CDN 地址(配置为拉取)
 ## 详见 https://meta.discourse.org/t/14857
 #DISCOURSE_CDN_URL: https://discourse-cdn.example.com

 ## MaxMind 地理位置 IP 查询的许可证密钥
 ## 详见 https://meta.discourse.org/t/-/137387/23
 DISCOURSE_MAXMIND_LICENSE_KEY: XXXXX

## Docker 容器是无状态的;所有数据存储在 /shared
volumes:
  - volume:
      host: /var/discourse/shared/standalone
      guest: /shared
  - volume:

  ## TODO: 此 Discourse 实例将响应的域名
  ## 必填项。Discourse 无法仅通过 IP 地址运行。
  DISCOURSE_HOSTNAME: community.example.io

  ## 如果希望容器以与上述相同的
  ## 主机名(-h 选项)启动,请取消注释(默认为 "$hostname-$config")
  #DOCKER_USE_HOSTNAME: true

  ## TODO: 初始注册时将设为管理员和开发者的逗号分隔邮箱列表
  ## 示例:'user1@example.com,user2@example.com'
  DISCOURSE_DEVELOPER_EMAILS: 'example@example.com'

  ## TODO: 用于验证新账户和发送通知的 SMTP 邮件服务器
  # SMTP 地址、用户名和密码为必填项
  # 警告:SMTP 密码中的 '#' 字符可能导致问题!
  DISCOURSE_SMTP_ADDRESS: smtp.mailgun.org
  DISCOURSE_SMTP_PORT: 587
  DISCOURSE_SMTP_USER_NAME: no-reply@example.io
  DISCOURSE_SMTP_PASSWORD: "XXXXXXXX"
  #DISCOURSE_SMTP_ENABLE_START_TLS: true           # (可选,默认为 true)
  DISCOURSE_SMTP_DOMAIN: community.example.io
  DISCOURSE_NOTIFICATION_EMAIL: noreply@community.example.io

  ## 如果已添加 Let's Encrypt 模板,请取消注释以下行以获取免费 SSL 证书
  LETSENCRYPT_ACCOUNT_EMAIL: example@example.com

  ## 此 Discourse 实例的 HTTP 或 HTTPS CDN 地址(配置为拉取)
  ## 详见 https://meta.discourse.org/t/14857
  #DISCOURSE_CDN_URL: https://discourse-cdn.example.com

  ## MaxMind 地理位置 IP 查询的许可证密钥
  ## 详见 https://meta.discourse.org/t/-/137387/23
  DISCOURSE_MAXMIND_LICENSE_KEY: XXXXXX

## Docker 容器是无状态的;所有数据存储在 /shared
volumes:
  - volume:
      host: /var/discourse/shared/standalone
      guest: /shared
  - volume:
      host: /var/discourse/shared/standalone/log/var-log
      guest: /var/log
discourse-doctor 结果
Found containers/app.yml

==================== YML 设置 ====================
DISCOURSE_HOSTNAME=community.example.io
SMTP_ADDRESS=smtp.mailgun.org
DEVELOPER_EMAILS=example@example.com
SMTP_PASSWORD=XXXXXXXX
SMTP_PORT=587
SMTP_USER_NAME=no-reply@example.io
LETSENCRYPT_ACCOUNT_EMAIL=example@example.com

==================== Docker 信息 ====================
DOCKER VERSION: Docker version 20.10.21, build baeda1f

DOCKER 进程 (docker ps -a)

CONTAINER ID   IMAGE                 COMMAND        CREATED          STATUS          PORTS                                                                      NAMES
e1d88ff15b5b   local_discourse/app   "/sbin/boot"   18 minutes ago   Up 18 minutes   0.0.0.0:80->80/tcp, :::80->80/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp   app

e1d88ff15b5b   local_discourse/app   "/sbin/boot"   18 minutes ago   Up 18 minutes   0.0.0.0:80->80/tcp, :::80->80/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp   app

Discourse 容器 app 正在运行


==================== 插件 ====================
          - git clone https://github.com/discourse/docker_manager.git

未检测到非官方插件。

官方列表详见 https://github.com/discourse/discourse/blob/main/lib/plugin/metadata.rb。

========================================
community.example.io 上的 Discourse 版本:未找到
localhost 上的 Discourse 版本:未找到


==================== 内存信息 ====================
RAM (MB): 1016

               total        used        free      shared  buff/cache   available
Mem:             969         687          61          21         220         110
Swap:           2047         241        1806

==================== 磁盘空间检查 ====================
---------- 操作系统磁盘空间 ----------
Filesystem      Size  Used Avail Use% Mounted on
/dev/vda1        25G  8.2G   16G  34% /

==================== 磁盘信息 ====================
Disk /dev/loop0: 63.22 MiB, 66293760 bytes, 129480 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes


Disk /dev/loop1: 102.98 MiB, 107986944 bytes, 210912 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes


Disk /dev/loop2: 47.98 MiB, 50315264 bytes, 98272 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes


Disk /dev/vda: 25 GiB, 26843545600 bytes, 52428800 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 728BDF97-580D-4B6F-9462-7E2540D5378B

Device      Start      End  Sectors  Size Type
/dev/vda1  227328 52428766 52201439 24.9G Linux filesystem
/dev/vda14   2048    10239     8192    4M BIOS boot
/dev/vda15  10240   227327   217088  106M EFI System

分区表条目未按磁盘顺序排列。


Disk /dev/vdb: 466 KiB, 477184 bytes, 932 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

==================== 磁盘信息结束 ====================

==================== 邮件测试 ====================
要进行可靠测试,请从 http://www.mail-tester.com/ 获取一个地址。
或者只需给自己发送一封测试邮件。
邮件测试的邮箱地址?(输入 'n' 跳过)[example@example.com  ]:
正在向 example@example.com 发送邮件 . . .
使用 smtp.mailgun.org:587、用户名 no-reply@example.io 和明文认证测试发送。
SMTP 服务器连接成功。
正在向 example@example.com 发送 . . .
邮件已被 SMTP 服务器接受。
Message-ID: e3455d15-eb48-48bf-9859-a30f1acc765c@community.example.io

如果您未收到该邮件,请检查您的垃圾邮件文件夹
或使用 http://www.mail-tester.com/ 等服务再次测试。

如果邮件未送达,问题不在 Discourse。
请检查上述 Message ID 对应的 SMTP 服务器日志,以了解发送失败的原因。
正在替换:SMTP_PASSWORD
正在替换:LETSENCRYPT_ACCOUNT_EMAIL
正在替换:DEVELOPER_EMAILS
正在替换:DISCOURSE_DB_PASSWORD
正在替换:Sending mail to

==================== 完成! ====================

我还在 Discourse 目录下运行了 ./launcher enter app 以及 top 命令,以验证 nginx、redis、postmaster 和 ruby 是否都在运行。但我没有在列表中看到 nginx……

launcher enter app --> top 结果
Tasks:  31 total,   1 running,  30 sleeping,   0 stopped,   0 zombie
%Cpu(s):  1.3 us,  2.3 sy,  0.0 ni, 96.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.3 st
MiB Mem :    969.4 total,     72.4 free,    659.0 used,    238.0 buff/cache
MiB Swap:   2048.0 total,   1667.2 free,    380.8 used.    141.1 avail Mem

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
   4528 discour+  25   5  951480 289404   3096 S   0.3  29.2   4:21.14 ruby
      1 root      20   0    6772      0      0 S   0.0   0.0   0:00.02 boot
   4428 root      20   0    2340     24      0 S   0.0   0.0   0:01.14 runsvdir
   4429 root      20   0    2188      0      0 S   0.0   0.0   0:00.00 runsv
   4430 root      20   0    2188      0      0 S   0.0   0.0   0:00.00 runsv
   4431 root      20   0    2188      0      0 S   0.0   0.0   0:00.00 runsv
   4432 root      20   0    2188      0      0 S   0.0   0.0   0:00.00 runsv
   4433 root      20   0    2188    280    256 S   0.0   0.0   1:28.21 runsv
   4434 root      20   0    2188      0      0 S   0.0   0.0   0:00.00 runsv
   4435 root      20   0    2336      0      0 S   0.0   0.0   0:00.05 svlogd
   4436 redis     20   0   58072   2900   1624 S   0.0   0.3   3:17.52 redis-server
   4438 root      20   0    2336      0      0 S   0.0   0.0   0:00.00 svlogd
   4439 discour+  20   0   15256   1128    912 S   0.0   0.1   0:25.85 unicorn_launche
   4441 root      20   0    6620    488    384 S   0.0   0.0   0:00.21 cron
   4442 postgres  20   0  213172   5220   4776 S   0.0   0.5   0:02.75 postmaster
   4445 root      20   0  151068    132      0 S   0.0   0.0   0:00.06 rsyslogd
   4458 postgres  20   0  213392  10404   9896 S   0.0   1.0   0:00.78 postmaster
   4459 postgres  20   0  213172   5004   4604 S   0.0   0.5   0:01.50 postmaster
   4460 postgres  20   0  213172   4956   4588 S   0.0   0.5   0:27.50 postmaster
   4461 postgres  20   0  213840   2264   1652 S   0.0   0.2   0:01.98 postmaster
   4462 postgres  20   0   68200    788      0 S   0.0   0.1   0:05.01 postmaster
   4463 postgres  20   0  213724   1164    700 S   0.0   0.1   0:00.05 postmaster
   4464 discour+  20   0  457692 171868   1364 S   0.0  17.3   0:22.71 ruby
   4503 postgres  20   0  220116  11116  10812 S   0.0   1.1   0:01.51 postmaster
   4538 discour+  20   0  768724 169816   1032 S   0.0  17.1   0:08.27 ruby
   4549 discour+  20   0  768724 169948   1220 S   0.0  17.1   0:08.55 ruby
   4580 postgres  20   0  219408  10580  10460 S   0.0   1.1   0:00.13 postmaster
 134464 postgres  20   0  217332  21388  17444 S   0.0   2.2   0:00.24 postmaster
 137350 root      20   0    7036   3468   2972 S   0.0   0.3   0:00.02 bash
 137382 root      20   0   10108   3756   3080 R   0.0   0.4   0:00.08 top
 137609 discour+  20   0   13760   2004   1732 S   0.0   0.2   0:00.00 sleep

我查看了 var/discourse/shared/standalone/log/var-log/nginx 目录下的 error.log:

2022/12/12 07:55:26 [emerg] 5040#5040: cannot load certificate "/shared/ssl/community.example.io.cer": PEM_read_bio_X509_AUX(>
2022/12/12 07:55:27 [emerg] 5042#5042: cannot load certificate "/shared/ssl/community.example.io.cer": PEM_read_bio_X509_AUX(>
2022/12/12 07:55:28 [emerg] 5044#5044: cannot load certificate "/shared/ssl/community.example.io.cer": PEM_read_bio_X509_AUX(>
2022/12/12 07:55:29 [emerg] 5046#5046: cannot load certificate "/shared/ssl/community.example.io.cer": PEM_read_bio_X509_AUX(>
....

好的,根据 var/discourse/shared/standalone/log/var-log/nginx 目录下的 error.log 文件,我决定在 app.yml 中注释掉 ssl 模板:

## 如果您想添加 Let's Encrypt (https),请取消注释这两行
##  - "templates/web.ssl.template.yml"
## - "templates/web.letsencrypt.ssl.template.yml"

然后我运行了 ./launcher stop app./launcher rebuild app,现在通过 http 成功运行了 discourse 构建,并在浏览器中显示“恭喜,您已成功安装 discourse!”。

这算是一步前进,但我似乎无法让 ssl 工作。我的 LE 证书还没有过期,DNS 看起来也很好,这是一个全新的安装,服务器配置也非常标准。

有什么想法可以解释为什么安装不允许我通过 Let’s Encrypt 启用 ssl 吗?

我猜是你的DNS设置错误,或者曾经错误过,然后你尝试了太多次导致被速率限制了。简单的解决方法是等待一周或者选择一个不同的子域名。

由于你没有分享你的主机名,我们无法知道DNS是否正常工作。

感谢您的回复 @pfaffmanhttp:// 工作正常,但在启用 Let’s Encrypt 时 SSL 无法工作。尽管我是通过全新安装设置的 LE,但我还是阅读了设置 LE 教程,并且没有看到任何关于 DNS 修改的说明。

为了让 LE/SSL 工作,我需要 DNS 方面提供什么?

这是我的 DNS 设置截图:

(顺便说一句,DKIM/SPF 已验证,Discourse 邮件工作正常)

再说一遍,我猜您尝试了多次从 Let’s Encrypt 请求地址,但由于某种原因失败了,现在您需要等待一周才能再次尝试。如果我猜对了,那就等一周,或者换个名字。

有一种方法可以从他们那里获取错误信息,但我现在在手机上记不起来了。

好的。下周早期七天之后,我将重新启用 app.yml 中的 SSL,然后重建并汇报结果。