前情提要

无意中通过朋友邀请注册了 LinuxDo 论坛,地址:

https://linux.do

他们用的就是 discourse,我玩了几天发现 dis 貌似比 nodebb 和 flarum 的功能都更完善一点(个人感觉),就想着自己也试试,没想到踩坑了几十次,教程都翻烂了,最后自己瞎琢磨没想到给部署成功了

本文使用 frp 内网穿透 + NginxProxyManager 反向代理部署

配置文件参考

最重要的 discourse-1.yml:(复制 samples/standalone.yml 文件到 containers/ 下,改文件名)

这里的文件名,关系到命令执行的参数。

## this is the all-in-one, standalone Discourse Docker container template
##
## After making changes to this file, you MUST rebuild
## /var/discourse/launcher rebuild app
##
## BE *VERY* CAREFUL WHEN EDITING!
## YAML FILES ARE SUPER SUPER SENSITIVE TO MISTAKES IN WHITESPACE OR ALIGNMENT!
## visit http://www.yamllint.com/ to validate this file as needed

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  ## Uncomment the next line to enable the IPv6 listener
  #- "templates/web.ipv6.template.yml"
  - "templates/web.ratelimited.template.yml"
  ## Uncomment these two lines if you wish to add Lets Encrypt (https)
  #- "templates/web.ssl.template.yml"
  #- "templates/web.letsencrypt.ssl.template.yml"
  - "templates/web.china.template.yml"

## which TCP/IP ports should this container expose?
## If you want Discourse to share a port with another webserver like Apache or nginx,
## see https://meta.discourse.org/t/17247 for details
expose:
  - "8888:80"   # http
  # - "443:443" # https

params:
  db_default_text_search_config: "pg_catalog.english"

  ## Set db_shared_buffers to a max of 25% of the total memory.
  ## will be set automatically by bootstrap based on detected RAM, or you can override
  #db_shared_buffers: "256MB"

  ## can improve sorting performance, but adds memory usage per-connection
  #db_work_mem: "40MB"

  ## Which Git revision should this container use? (default: tests-passed)
  #version: tests-passed

env:
  LC_ALL: en_US.UTF-8
  LANG: en_US.UTF-8
  LANGUAGE: en_US.UTF-8
  # DISCOURSE_DEFAULT_LOCALE: en

  ## How many concurrent web requests are supported? Depends on memory and CPU cores.
  ## will be set automatically by bootstrap based on detected CPUs, or you can override
  #UNICORN_WORKERS: 3

  ## TODO: The domain name this Discourse instance will respond to
  ## Required. Discourse will not work with a bare IP number.
  DISCOURSE_HOSTNAME: 'discou.imbhj.com'

  ## Uncomment if you want the container to be started with the same
  ## hostname (-h option) as specified above (default "$hostname-$config")
  #DOCKER_USE_HOSTNAME: true

  ## TODO: List of comma delimited emails that will be made admin and developer
  ## on initial signup example 'user1@example.com,user2@example.com'
  DISCOURSE_DEVELOPER_EMAILS: 'xxxxxx@xxxxxx.com'

  ## TODO: The SMTP mail server used to validate new accounts and send notifications
  # SMTP ADDRESS, username, and password are required
  # WARNING the char '#' in SMTP password can cause problems!
  DISCOURSE_SMTP_ADDRESS: smtpdm.aliyun.com
  DISCOURSE_SMTP_PORT: 25
  DISCOURSE_SMTP_USER_NAME: discou@xxxxxx.ltd
  DISCOURSE_SMTP_PASSWORD: xxxxxx
  # DISCOURSE_SMTP_ENABLE_START_TLS: true
  DISCOURSE_SMTP_DOMAIN: discou@xxxxxx.ltd
  DISCOURSE_NOTIFICATION_EMAIL: discou@xxxxxx.ltd

  ## If you added the Lets Encrypt template, uncomment below to get a free SSL certificate
  #LETSENCRYPT_ACCOUNT_EMAIL: me@example.com

  ## The http or https CDN address for this Discourse instance (configured to pull)
  ## see https://meta.discourse.org/t/14857 for details
  #DISCOURSE_CDN_URL: https://discourse-cdn.example.com

  ## The maxmind geolocation IP account ID and license key for IP address lookups
  ## see https://meta.discourse.org/t/-/173941 for details
  #DISCOURSE_MAXMIND_ACCOUNT_ID: 123456
  #DISCOURSE_MAXMIND_LICENSE_KEY: 1234567890123456

## The Docker container is stateless; all data is stored in /shared
volumes:
  - volume:
      host: /opt/1panel/docker/compose/discourse/data/standalone
      guest: /shared
  - volume:
      host: /opt/1panel/docker/compose/discourse/data/standalone/log/var-log
      guest: /var/log

## Plugins go here
## see https://meta.discourse.org/t/19157 for details
hooks:
  after_code:
    - exec:
        cd: $home/plugins
        cmd:
          - git clone https://github.com/discourse/docker_manager.git

## Any custom commands to run after building
run:
  - exec: echo "Beginning of custom commands"
  ## If you want to set the 'From' email address for your first registration, uncomment and change:
  ## After getting the first signup email, re-comment the line. It only needs to run once.
  #- exec: rails r "SiteSetting.notification_email='info@unconfigured.discourse.org'"
  - exec: echo "End of custom commands"

本文中的版本是 20241001 的版本,仅供参考。

本文不按照官方推荐的,必须要使用 80/443 端口,并且也不使用官方容器内部的 nginx 代理,而是在容器外使用反向代理实现 https 访问,并且亲测可以实现部署,且邮件服务和文件上传等全部正常

郑重提示,尽量不要按照官方给的部署教程,否则会踩无数的坑。

上面这个配置文件里最需要注意的是以下几点:

  • templates 部分一定不要引入以下三个文件: "templates/web.socketed.template.yml""templates/web.ssl.template.yml""templates/web.letsencrypt.ssl.template.yml" ,注意,是一定不要!!!

  • expose 部分,容器内部只需要暴露一个 80 端口即可,容器外部的端口可以根据自己需要进行定义(这一个端口在外部进行反代就可以实现 https,不需要多此一举暴露 443 端口

  • DISCOURSE_HOSTNAME :部署的论坛的访问域名,discourse 仅支持域名访问,不能使用 IP 访问,注意不要忘了单引号

  • DISCOURSE_DEVELOPER_EMAILS :管理员邮箱,后续注册第一个管理员需要用到,不要忘了单引号

  • DISCOURSE_SMTP_ADDRESS :论坛发信邮箱的 SMTP 服务域名,在对应的邮箱服务商里查询

  • DISCOURSE_SMTP_PORT :发信邮箱的工作端口,这里需要注意的是,discourse 官方默认加密协议只支持 587 端口,国内常用的 465 端口并不行(亲测),所以这里使用了未加密的传统的 25 端口,当然也要看你发信邮箱的服务商具体支持哪个端口

  • DISCOURSE_SMTP_USER_NAME :发信邮箱的用户名,部分邮件服务商指定用户名和发信邮箱必须一致,这里需要注意

  • DISCOURSE_SMTP_PASSWORD :发信邮箱的 SMTP 授权码,在对应的邮箱服务商里查询

  • DISCOURSE_SMTP_ENABLE_START_TLS :是否启用 TLS 加密协议,discourse 官方默认加密协议只支持 587 端口,如果不是这个端口,这个配置请注释

  • DISCOURSE_SMTP_DOMAIN :发信域名,建议与发信用户名一致

  • DISCOURSE_NOTIFICATION_EMAIL :发送邮件通知的地址,建议与发信用户名一致

挂载卷的路径,可以根据自己需要进行修改。

部署步骤

拉取 discourse 项目:

mkdir discourse && cd discourse
git clone https://github.com/discourse/discourse_docker.git ./discourse_docker
cd ./discourse_docker
chmod 700 containers

复制 ./samples/standalone.yml 文件到 ./containers/ 下,修改文件名为 discourse-1.yml ,文件名可以自己定义,但要记住,下面的步骤要用到

然后根据上文的配置文件修改 discourse-1.yml 文件中内容,修改完毕之后,更改该配置文件的权限为 0640 ,或者执行:

chmod o-rwx ./containers/discourse-1.yml

然后直接执行:

./launcher rebuild discourse-1

注意要启动的容器名称,对应配置文件的名称。

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:      Use nsenter to get a shell into a container
    logs:       View the Docker logs for a container
    bootstrap:  Bootstrap a container for the config based on a template
    rebuild:    Rebuild a container (destroy old, bootstrap, start new)
    cleanup:    Remove all containers that have stopped for > 24 hours

Options:
    --skip-prereqs             Don't check launcher prerequisites
    --docker-args              Extra arguments to pass when running docker

注意这个过程有点长,因为首先要拉取镜像,镜像大小高达 1G 多,然后要构建 app 镜像,构建的 app 镜像大小更是高达 4G 多,整个过程建议使用魔法环境

需要注意的是,上文的配置文件中的 templates 部分引入了一个 "templates/web.china.template.yml" 文件,这个是 discourse 官方提供的国服特供配置文件,可以将容器中的部分源替换为国内镜像,但是拉取 docker 镜像的过程还是需要使用魔法

如果构建过程中出现 Failed listening on port 6379 (TCP)database system is shut down 不要慌,这是正常现象,耐心等待构建完成,构建完成的最后一行日志输出就是 docker 容器的启动命令,包含了我们在 yml 配置文件中的各个设置项以供检查

容器启动成功之后,设置好反向代理和 https,就可以访问进行管理员注册了,如果在管理员注册过程中无法收到邮件,那么请检查自己的邮件配置是否正确,是否符合邮件服务商的规定

如果在注册页面点了一次发送验证邮件,但是页面没有反应的话,千万不要再继续点了!!!这就是邮件配置的问题,多点几次的话,一点邮件配置正确了,这些就会一股脑地发过去,会一次性发好几个。

如果发现什么配置设置错误,重新修改 yml 配置文件,然后重新执行:

./launcher stop discourse-1
./launcher rebuild discourse-1

进行重构即可

重构之后别忘了把旧的自定义镜像删除,因为重构并不会自己删除,每重构一次就会多一个 5G 左右的镜像,别问我怎么知道的。。。

20241002更新

部署的时候有个警告:

WARNING Memory overcommit must be enabled! Without it, a background save or replication may fail under low memory condition. Being disabled, it can can also cause failures without low memory condition, see https://github.com/jemalloc/jemalloc/issues/1328. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.

建议打开系统的 swap 交换内存,debian 系统打开交换内存的步骤如下:(实测没用)

# 创建一个1GB大小的swap文件
sudo fallocate -l 1G /swapfile 
# 修改文件权限,确保只有 root 用户可以读写
sudo chmod 600 /swapfile 
# 把这个文件设置成 swap 空间
sudo mkswap /swapfile 
# 启用 swap
sudo swapon /swapfile 
# 重启之后依然有效
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab 
# 查看是否生效
free -h

我百度了一下,应该是要命令开启 sysctl vm.overcommit_memory=1 ,这个可能会影响 redis 的内存分配

那个 "templates/web.china.template.yml" 文件,尽量不要引入了,因为在开魔法(拉取镜像)的情况下,可能反而会导致某些文件无法访问

20241004更新

配置文件 discourse-1.yml 更新:

## this is the all-in-one, standalone Discourse Docker container template
##
## After making changes to this file, you MUST rebuild
## /var/discourse/launcher rebuild app
##
## BE *VERY* CAREFUL WHEN EDITING!
## YAML FILES ARE SUPER SUPER SENSITIVE TO MISTAKES IN WHITESPACE OR ALIGNMENT!
## visit http://www.yamllint.com/ to validate this file as needed

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  ## Uncomment the next line to enable the IPv6 listener
  #- "templates/web.ipv6.template.yml"
  - "templates/web.ratelimited.template.yml"
  ## Uncomment these two lines if you wish to add Lets Encrypt (https)
  #- "templates/web.ssl.template.yml"
  #- "templates/web.letsencrypt.ssl.template.yml"
  ## 引入国内源
  # - "templates/web.china.template.yml"

## which TCP/IP ports should this container expose?
## If you want Discourse to share a port with another webserver like Apache or nginx,
## see https://meta.discourse.org/t/17247 for details
expose:
  - "8888:80"   # http
  # - "443:443" # https

params:
  db_default_text_search_config: "pg_catalog.english"

  ## Set db_shared_buffers to a max of 25% of the total memory.
  ## will be set automatically by bootstrap based on detected RAM, or you can override
  #db_shared_buffers: "256MB"

  ## can improve sorting performance, but adds memory usage per-connection
  #db_work_mem: "40MB"

  ## Which Git revision should this container use? (default: tests-passed)
  version: stable

env:
  LC_ALL: en_US.UTF-8
  LANG: en_US.UTF-8
  LANGUAGE: en_US.UTF-8
  # DISCOURSE_DEFAULT_LOCALE: en

  ## How many concurrent web requests are supported? Depends on memory and CPU cores.
  ## will be set automatically by bootstrap based on detected CPUs, or you can override
  UNICORN_WORKERS: 2

  ## TODO: The domain name this Discourse instance will respond to
  ## Required. Discourse will not work with a bare IP number.
  DISCOURSE_HOSTNAME: 'bbs.imbhj.com'

  ## Uncomment if you want the container to be started with the same
  ## hostname (-h option) as specified above (default "$hostname-$config")
  #DOCKER_USE_HOSTNAME: true

  ## TODO: List of comma delimited emails that will be made admin and developer
  ## on initial signup example 'user1@example.com,user2@example.com'
  DISCOURSE_DEVELOPER_EMAILS: 'xxx@xxx.com'

  ## TODO: The SMTP mail server used to validate new accounts and send notifications
  # SMTP ADDRESS, username, and password are required
  # WARNING the char '#' in SMTP password can cause problems!
  DISCOURSE_SMTP_ADDRESS: smtpdm.aliyun.com
  DISCOURSE_SMTP_PORT: 25    # 587
  DISCOURSE_SMTP_USER_NAME: xxx@xxx.xxx
  DISCOURSE_SMTP_PASSWORD: xxxxxxxxx
  #DISCOURSE_SMTP_ENABLE_START_TLS: true           # (optional, default true)
  DISCOURSE_SMTP_DOMAIN: xxx@xxx.xxx    # (required by some providers)
  DISCOURSE_NOTIFICATION_EMAIL: xxx@xxx.xxx    # (address to send notifications from)

  ## If you added the Lets Encrypt template, uncomment below to get a free SSL certificate
  #LETSENCRYPT_ACCOUNT_EMAIL: me@example.com

  ## The http or https CDN address for this Discourse instance (configured to pull)
  ## see https://meta.discourse.org/t/14857 for details
  #DISCOURSE_CDN_URL: https://discourse-cdn.example.com

  ## The maxmind geolocation IP account ID and license key for IP address lookups
  ## see https://meta.discourse.org/t/-/173941 for details
  #DISCOURSE_MAXMIND_ACCOUNT_ID: 123456
  #DISCOURSE_MAXMIND_LICENSE_KEY: 1234567890123456

## The Docker container is stateless; all data is stored in /shared
volumes:
  - volume:
      host: /opt/1panel/docker/compose/discourse/standalone
      guest: /shared
  - volume:
      host: /opt/1panel/docker/compose/discourse/standalone/log/var-log
      guest: /var/log

## Plugins go here
## see https://meta.discourse.org/t/19157 for details
hooks:
  after_code:
    - exec:
        cd: $home/plugins
        cmd:
          - git clone https://github.com/discourse/docker_manager.git
          - git clone https://github.com/discourse/discourse-solved.git
          - git clone https://github.com/discourse/discourse-gamification.git
          - git clone https://github.com/discourse/discourse-saved-searches.git
          - git clone https://github.com/discourse/discourse-category-experts.git
          - git clone https://github.com/discourse/discourse-encrypt.git
          - git clone https://github.com/discourse/discourse-tooltips.git
          - git clone https://github.com/discourse/discourse-bbcode.git
          - git clone https://github.com/discourse/discourse-follow.git
          - git clone https://github.com/discourse/discourse-yearly-review.git

## Any custom commands to run after building
run:
  - exec: echo "Beginning of custom commands"
  ## If you want to set the 'From' email address for your first registration, uncomment and change:
  ## After getting the first signup email, re-comment the line. It only needs to run once.
  #- exec: rails r "SiteSetting.notification_email='info@unconfigured.discourse.org'"
  - exec: echo "End of custom commands"

主要更新了几个插件,和 git 的版本,插件功能可以访问这里:

https://www.discourse.org/plugins

或者:

20241004212550.png

20241005更新

那个配置文件如果没什么必要,还是保持默认的 app.yml 吧,方便 rebuild 失败之后查找原因和日志

新增了以下几个插件:

20241005191356.png

配置插件之后,如果 rebuild 失败,可以通过 ./discourse-doctor 命令来查看部署失败的原因(前提是配置文件为默认的 app 名字)

在安装插件过程中,发现配置文件中的 version: stable 这个配置项,最好还是注销了,会引起某些 npm 包的依赖问题,我自己最新的 app.yml 配置文件如下:

## this is the all-in-one, standalone Discourse Docker container template
##
## After making changes to this file, you MUST rebuild
## /var/discourse/launcher rebuild app
##
## BE *VERY* CAREFUL WHEN EDITING!
## YAML FILES ARE SUPER SUPER SENSITIVE TO MISTAKES IN WHITESPACE OR ALIGNMENT!
## visit http://www.yamllint.com/ to validate this file as needed

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  ## Uncomment the next line to enable the IPv6 listener
  #- "templates/web.ipv6.template.yml"
  - "templates/web.ratelimited.template.yml"
  ## Uncomment these two lines if you wish to add Lets Encrypt (https)
  #- "templates/web.ssl.template.yml"
  #- "templates/web.letsencrypt.ssl.template.yml"
  ## 引入国内源
  # - "templates/web.china.template.yml"

## which TCP/IP ports should this container expose?
## If you want Discourse to share a port with another webserver like Apache or nginx,
## see https://meta.discourse.org/t/17247 for details
expose:
  - "8888:80"   # http
  # - "443:443" # https

params:
  db_default_text_search_config: "pg_catalog.english"

  ## Set db_shared_buffers to a max of 25% of the total memory.
  ## will be set automatically by bootstrap based on detected RAM, or you can override
  #db_shared_buffers: "256MB"

  ## can improve sorting performance, but adds memory usage per-connection
  #db_work_mem: "40MB"

  ## Which Git revision should this container use? (default: tests-passed)
  # version: stable

env:
  LC_ALL: en_US.UTF-8
  LANG: en_US.UTF-8
  LANGUAGE: en_US.UTF-8
  # DISCOURSE_DEFAULT_LOCALE: en

  ## How many concurrent web requests are supported? Depends on memory and CPU cores.
  ## will be set automatically by bootstrap based on detected CPUs, or you can override
  UNICORN_WORKERS: 2

  ## TODO: The domain name this Discourse instance will respond to
  ## Required. Discourse will not work with a bare IP number.
  DISCOURSE_HOSTNAME: 'bbs.imbhj.com'

  ## Uncomment if you want the container to be started with the same
  ## hostname (-h option) as specified above (default "$hostname-$config")
  #DOCKER_USE_HOSTNAME: true

  ## TODO: List of comma delimited emails that will be made admin and developer
  ## on initial signup example 'user1@example.com,user2@example.com'
  DISCOURSE_DEVELOPER_EMAILS: 'xxx@xxx.com'

  ## TODO: The SMTP mail server used to validate new accounts and send notifications
  # SMTP ADDRESS, username, and password are required
  # WARNING the char '#' in SMTP password can cause problems!
  DISCOURSE_SMTP_ADDRESS: smtpdm.aliyun.com
  DISCOURSE_SMTP_PORT: 25    # 587
  DISCOURSE_SMTP_USER_NAME: xxx@xxx.ltd
  DISCOURSE_SMTP_PASSWORD: xxxxxxxxx
  #DISCOURSE_SMTP_ENABLE_START_TLS: true           # (optional, default true)
  DISCOURSE_SMTP_DOMAIN: xxx@xxx.ltd    # (required by some providers)
  DISCOURSE_NOTIFICATION_EMAIL: xxx@xxx.ltd    # (address to send notifications from)

  ## If you added the Lets Encrypt template, uncomment below to get a free SSL certificate
  #LETSENCRYPT_ACCOUNT_EMAIL: me@example.com

  ## The http or https CDN address for this Discourse instance (configured to pull)
  ## see https://meta.discourse.org/t/14857 for details
  #DISCOURSE_CDN_URL: https://discourse-cdn.example.com

  ## The maxmind geolocation IP account ID and license key for IP address lookups
  ## see https://meta.discourse.org/t/-/173941 for details
  #DISCOURSE_MAXMIND_ACCOUNT_ID: 123456
  #DISCOURSE_MAXMIND_LICENSE_KEY: 1234567890123456

## The Docker container is stateless; all data is stored in /shared
volumes:
  - volume:
      host: /opt/1panel/docker/compose/discourse/standalone
      guest: /shared
  - volume:
      host: /opt/1panel/docker/compose/discourse/standalone/log/var-log
      guest: /var/log

## Plugins go here
## see https://meta.discourse.org/t/19157 for details
hooks:
  after_code:
    - exec:
        cd: $home/plugins
        cmd:
          - git clone https://github.com/discourse/docker_manager.git
          - git clone https://github.com/discourse/discourse-solved.git
          - git clone https://github.com/discourse/discourse-gamification.git
          - git clone https://github.com/discourse/discourse-saved-searches.git
          - git clone https://github.com/discourse/discourse-category-experts.git
          - git clone https://github.com/discourse/discourse-encrypt.git
          - git clone https://github.com/discourse/discourse-tooltips.git
          - git clone https://github.com/discourse/discourse-bbcode.git
          - git clone https://github.com/discourse/discourse-follow.git
          - git clone https://github.com/discourse/discourse-yearly-review.git
          - git clone https://github.com/discourse/discourse-doc-categories.git
          - git clone https://github.com/discourse/discourse-docs.git
          - git clone https://github.com/discourse/discourse-cakeday.git
          - git clone https://github.com/discourse/discourse-signatures.git
          - git clone https://github.com/discourse/discourse-reactions.git
          - git clone https://github.com/discourse/discourse-math.git
          - git clone https://github.com/discourse/DiscoTOC.git

## Any custom commands to run after building
run:
  - exec: echo "Beginning of custom commands"
  ## If you want to set the 'From' email address for your first registration, uncomment and change:
  ## After getting the first signup email, re-comment the line. It only needs to run once.
  #- exec: rails r "SiteSetting.notification_email='info@unconfigured.discourse.org'"
  - exec: echo "End of custom commands"

如果 ./launcher rebuild app 命令卡在了 database system is shut down 这一步,一般也就几分钟,如果卡了十几分钟,果断结束进程,重新执行 rebuild

20241006更新

在 discourse 中,主题组件插件 是两种不同的东西,他们的区别是:

  • 组件是可以附带到 主题 中的,是针对主题进行功能补充的,且安装不需要app.yml 文件中进行配置;

  • 插件是针对整个论坛进行功能补充,必须通过 app.yml 文件进行容器重构

插件的安装方式不说了,就在上文中,要修改配置文件和重构,主题组件的安装则是在 web 的管理页面,找到主题和组件,安装组件,选择 git 仓库进行安装:

20241006131355.png

上文中的 DiscoTOC 就是一个 主题组件,所以不需要在配置文件中进行安装,故插件列表中就没有显示

还有,部分 插件 其实安装了但是插件列表也不会显示,但是在 网站所有设置 里面能够找到 生效的对应选项,这一点确实是很迷惑,所以在安装某些插件或者组件的时候,安装完成一定要检查是否成功,设置项是否存在,或者是不是一个组件而不是插件

对于如何确定是插件还是组件,一般来说,在插件/组件的 GitHub 仓库页面会有介绍,比如这就是一个 主题组件

20241006133439.png

这就是一个论坛插件:

20241006133643.png

参考资料:

https://www.isharkfly.com/t/discotoc/16384

202241006更新2

新增了几个插件:

20241006190014.png

需要注意第一个是 主题组件,直接在 web 页面的后台进行安装即可

20241008更新

如图:

20241008205809.png

注意这是一个 主题组件

新建主题的步骤如下:

来到后台管理页面,找到主题选项,选择安装 -> 新建主题:

20241008205329.png

主题命名可以自定定义,我这里命名为 Dark,

创建完成后,勾选启用主题,主题配色更改为 Dark:

20241008205523.png

然后应用即可。

如果不想多安装主题,仅实现切换黑暗模式,可以参考这个主题组件:

https://meta.discourse.org/t/dark-light-mode-toggle/215585

20241008220311.png

顺带备份以下最新的配置文件:

最新配置文件

app.yml:

## this is the all-in-one, standalone Discourse Docker container template
##
## After making changes to this file, you MUST rebuild
## /var/discourse/launcher rebuild app
##
## BE *VERY* CAREFUL WHEN EDITING!
## YAML FILES ARE SUPER SUPER SENSITIVE TO MISTAKES IN WHITESPACE OR ALIGNMENT!
## visit http://www.yamllint.com/ to validate this file as needed

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  ## Uncomment the next line to enable the IPv6 listener
  #- "templates/web.ipv6.template.yml"
  - "templates/web.ratelimited.template.yml"
  ## Uncomment these two lines if you wish to add Lets Encrypt (https)
  #- "templates/web.ssl.template.yml"
  #- "templates/web.letsencrypt.ssl.template.yml"
  ## 引入国内源
  # - "templates/web.china.template.yml"

## which TCP/IP ports should this container expose?
## If you want Discourse to share a port with another webserver like Apache or nginx,
## see https://meta.discourse.org/t/17247 for details
expose:
  - "8888:80"   # http
  # - "443:443" # https

params:
  db_default_text_search_config: "pg_catalog.english"

  ## Set db_shared_buffers to a max of 25% of the total memory.
  ## will be set automatically by bootstrap based on detected RAM, or you can override
  #db_shared_buffers: "256MB"

  ## can improve sorting performance, but adds memory usage per-connection
  #db_work_mem: "40MB"

  ## Which Git revision should this container use? (default: tests-passed)
  # version: stable

env:
  LC_ALL: en_US.UTF-8
  LANG: en_US.UTF-8
  LANGUAGE: en_US.UTF-8
  # DISCOURSE_DEFAULT_LOCALE: en

  ## How many concurrent web requests are supported? Depends on memory and CPU cores.
  ## will be set automatically by bootstrap based on detected CPUs, or you can override
  UNICORN_WORKERS: 2

  ## TODO: The domain name this Discourse instance will respond to
  ## Required. Discourse will not work with a bare IP number.
  DISCOURSE_HOSTNAME: 'bbs.imbhj.com'

  ## Uncomment if you want the container to be started with the same
  ## hostname (-h option) as specified above (default "$hostname-$config")
  #DOCKER_USE_HOSTNAME: true

  ## TODO: List of comma delimited emails that will be made admin and developer
  ## on initial signup example 'user1@example.com,user2@example.com'
  DISCOURSE_DEVELOPER_EMAILS: 'xxx@xxx.com'

  ## TODO: The SMTP mail server used to validate new accounts and send notifications
  # SMTP ADDRESS, username, and password are required
  # WARNING the char '#' in SMTP password can cause problems!
  DISCOURSE_SMTP_ADDRESS: smtpdm.aliyun.com
  DISCOURSE_SMTP_PORT: 25    # 587
  DISCOURSE_SMTP_USER_NAME: xxx@xxx.ltd
  DISCOURSE_SMTP_PASSWORD: xxxxxxxxx
  #DISCOURSE_SMTP_ENABLE_START_TLS: true           # (optional, default true)
  DISCOURSE_SMTP_DOMAIN: xxx@xxx.ltd    # (required by some providers)
  DISCOURSE_NOTIFICATION_EMAIL: xxx@xxx.ltd    # (address to send notifications from)

  ## If you added the Lets Encrypt template, uncomment below to get a free SSL certificate
  #LETSENCRYPT_ACCOUNT_EMAIL: me@example.com

  ## The http or https CDN address for this Discourse instance (configured to pull)
  ## see https://meta.discourse.org/t/14857 for details
  #DISCOURSE_CDN_URL: https://discourse-cdn.example.com

  ## The maxmind geolocation IP account ID and license key for IP address lookups
  ## see https://meta.discourse.org/t/-/173941 for details
  #DISCOURSE_MAXMIND_ACCOUNT_ID: 123456
  #DISCOURSE_MAXMIND_LICENSE_KEY: 1234567890123456

## The Docker container is stateless; all data is stored in /shared
volumes:
  - volume:
      host: /opt/1panel/docker/compose/discourse/standalone
      guest: /shared
  - volume:
      host: /opt/1panel/docker/compose/discourse/standalone/log/var-log
      guest: /var/log

## Plugins go here
## see https://meta.discourse.org/t/19157 for details
hooks:
  after_code:
    - exec:
        cd: $home/plugins
        cmd:
          - git clone https://github.com/discourse/docker_manager.git
          - git clone https://github.com/discourse/discourse-solved.git
          - git clone https://github.com/discourse/discourse-gamification.git
          - git clone https://github.com/discourse/discourse-saved-searches.git
          - git clone https://github.com/discourse/discourse-category-experts.git
          - git clone https://github.com/discourse/discourse-encrypt.git
          - git clone https://github.com/discourse/discourse-tooltips.git
          - git clone https://github.com/discourse/discourse-bbcode.git
          - git clone https://github.com/discourse/discourse-follow.git
          - git clone https://github.com/discourse/discourse-yearly-review.git
          - git clone https://github.com/discourse/discourse-doc-categories.git
          - git clone https://github.com/discourse/discourse-docs.git
          - git clone https://github.com/discourse/discourse-cakeday.git
          - git clone https://github.com/discourse/discourse-signatures.git
          - git clone https://github.com/discourse/discourse-reactions.git
          - git clone https://github.com/discourse/discourse-math.git
          # - git clone https://github.com/discourse/DiscoTOC.git
          - git clone https://github.com/discourse/discourse-calendar.git
          - git clone https://github.com/discourse/discourse-ai.git
          - git clone https://github.com/discourse/discourse-post-voting.git
          - git clone https://github.com/discourse/discourse-topic-voting.git
          # - git clone https://github.com/discourse/discourse-tag-icons.git
          # - git clone https://github.com/discourse/Discourse-nav-links-component.git
          # - git clone https://github.com/discourse/discourse-sidebar-theme-toggle.git
          # - git clone https://github.com/discourse/discourse-search-banner.git
          # - git clone https://github.com/discourse/discourse-category-icons.git

## Any custom commands to run after building
run:
  - exec: echo "Beginning of custom commands"
  ## If you want to set the 'From' email address for your first registration, uncomment and change:
  ## After getting the first signup email, re-comment the line. It only needs to run once.
  #- exec: rails r "SiteSetting.notification_email='info@unconfigured.discourse.org'"
  - exec: echo "End of custom commands"

ok