当服务器上只有一个 Discourse 实例时,安装 Discourse 真的很容易。 当您想在同一台服务器上安装多个 Discourse 实例以降低成本时,事情会变得复杂。
官方 Discourse 安装不遵循常规的 Docker 实践。 Discourse 安装程序首先会执行一些称为引导的操作,这将在您看来是一个主机安装过程。 引导过程结束后,启动器会根据在第一次安装期间从您那里获得的反馈启动一个名为“app”的容器。
当与其他 Web 服务和应用程序(如 WordPress)一起设置时,这种混合安装过程是不同的。
在本教程中,我将向您展示如何在单个 Linux 服务器上安装多个 Discourse 安装以及其他基于 docker 的应用程序。 如果您熟悉 Docker 和 Linux 命令行的基础知识,这一点也不难。
在同一台服务器上安装多个 Discourse 论坛
一般来说,多重话语配置被理解为 多站点配置 并且已经说明了该过程 这里.
正式地,Discourse 没有提供在单个服务器上安装多个 Discourse 的文档。 但不要担心。 我将向您展示运行在 3-5 个独立容器下的安装过程 Nginx 每个独立容器对应于其各自的域。
我在本教程中使用的是 Ubuntu 18.04。 请确保您在 Ubuntu 或您使用的任何 Linux 发行版上安装了 Docker。
我建议使用像 Linode 这样的云服务器提供商在云中快速部署 Linux 服务器。
我使用 domain.com 作为 example 教程中的域名。 请确保根据您自己的域或子域进行更改。
1. 更改您域的 DNS 记录
在您的域名提供商的 DNS 记录面板中,确保域和子域(包括 www)都指向您服务器的 IP 地址。
为了 example,对于根域,将主机名字段保留为空白(或 @),对于子域,在设置服务器 IP 时使用“*”通配符。
2.交换空间
为了确保您的所有容器应用程序在部署后都不会出现内存不足的情况,您必须在系统上拥有必要的交换空间。
您始终可以根据系统上的可用 RAM 调整交换。 您可以根据单个服务器上的应用程序容器包并估计它们的累积 RAM 使用量来决定交换空间。 Discourse 还为您检查和配置交换。
3. 创建一个 Docker 网络
这 码头工人网络 将使容器能够根据需要相互通信。 为了便于理解,我们称它为链。
在配置所有容器时,您将使用此网络。
docker network create chain
4.设置Nginx反向代理
现在继续设置 Nginx 反向代理。 请注意,这充当了一个接口,它将映射所有不同的容器端口,以便您可以通过 URL 访问它们。 您也可以将其称为“母容器”。
docker run --name nginx-proxy --net chain -p 80:80 -p 443:443 -v ~/certs:/etc/nginx/certs -v /etc/nginx/vhost.d -v /usr/share/nginx/html -v /var/run/docker.sock:/tmp/docker.sock:ro --label com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy -d --restart always jwilder/nginx-proxy
5. 设置 Let’s Encrypt Nginx 代理伴侣
请注意,我们告诉 docker 使用已经在第一个 nginx-proxy 容器上声明的卷。 它使用您在步骤 3 中创建的相同“链”网络。
docker run --name letsencrypt-nginx-proxy-companion --net chain -v ~/certs:/etc/nginx/certs:rw -v /var/run/docker.sock:/var/run/docker.sock:ro --volumes-from nginx-proxy -d --restart always jrcs/letsencrypt-nginx-proxy-companion
这个 nginx-proxy 的配套容器负责设置 SSL 证书 Let’s Encrypt. 您将在最终设置 Discourse 容器时看到这一点。
6. 通过 Nginx 进行 WWW 重定向(不需要 CNAME,使用子域的可选步骤)
要确保 domain.com 请求像任何其他站点一样重定向到 www.domain.com,您需要执行一个额外的步骤。
Enter nginx-proxy 容器:
docker exec -ti nginx-proxy /bin/bash
您现在会看到这样的 root 提示:
[email protected]:/app#
还记得我在第 4 步中提到的 /etc/nginx/vhost.d 位置吗? 在此处创建一个与您的根域名相同的新文件。 你这里没有 vim 或 nano。 不要安装 Vim 或 Nano,而是使用 cat 命令。
cat >> /etc/nginx/vhost.d/domain.com
在下一个提示符下,无论您写什么,都将编辑该文件。 所以请确保您 将 www.domain.com 替换为您自己的域 在下一行:
rewrite ^/(.*)$ https://www.domain.com/$1 permanent;
按回车键,然后按 Ctrl+D 保存。 Enter exit 离开容器。
[email protected]:/app# exit
让我们停止到目前为止您创建的所有上述容器(按给定顺序)。 您不会使用重新启动,只需重新启动它们,因为您不希望其他容器在重新启动每个容器时进行监听。
docker stop nginx-proxy
docker stop letsencrypt-nginx-proxy-companion
docker start nginx-proxy
docker start letsencrypt-nginx-proxy-companion
7. 克隆官方 Discourse Docker 镜像
根据官方指南,克隆 官方话语docker镜像 进入 /var/discourse 目录。 这是 Discourse 在设置后可以存储属于其各自容器的所有 Docker 卷的地方。
sudo -s
git clone https://github.com/discourse/discourse_docker.git /var/discourse
cd /var/discourse
8.复制独立配置
现在下一步是确保在根据您的要求进行编辑之前将文件 /var/discourse/standalone.yml 复制到 /var/discourse/containers/ 作为 app.yml。
cp /var/discourse/samples/standalone.yml /var/discourse/containers/app.yml
一个典型的standalone.yml 看起来像 这.
9.准备独立配置
您现在需要编辑此文件,因为您的配置将基于 nginx。
端口 80 和 443 已被其使用。 你也已经有了我们的letsencrypt容器,你必须向Discourse展示你想要放入的现有Docker网络。
在此处设置您的域时,您还需要一个邮件服务器来配置您的论坛通知电子邮件(我使用过 发送网格 这里)。
请注意,LETSENCRYPT_EMAIL(用于通知 SSL 更新)和 DISCOURSE_DEVELOPER_EMAILS(用于 admin) 如果需要可以不同。
nano /var/discourse/containers/app.yml
10.自定义独立配置
以下是我为演示目的而重命名为 app.yml 的编辑文件。 建议编辑您自己的 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 https://www.yamllint.com/ to validate this file as needed
templates:
"templates/postgres.template.yml"
"templates/redis.template.yml"
"templates/web.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"
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:
- "80"
#- "80:80" # http
#- "443:443" # https
docker_args:
- "--net chain"
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:
LANG: 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
#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:
LANG: 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: 'domain.com'
VIRTUAL_HOST: 'domain.com,www.domain.com'
LETSENCRYPT_HOST: 'domain.com,www.domain.com'
LETSENCRYPT_EMAIL: '[email protected]'
## 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 '[email protected],[email protected]'
DISCOURSE_DEVELOPER_EMAILS: '[email protected]'
## 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: smtp.sendgrid.net
DISCOURSE_SMTP_PORT: 587
DISCOURSE_SMTP_USER_NAME: apikey
DISCOURSE_SMTP_PASSWORD: yourpassword
DISCOURSE_SMTP_ENABLE_START_TLS: true # (optional, default true)
## If you added the Lets Encrypt template, uncomment below to get a free SSL certificate
#LETSENCRYPT_ACCOUNT_EMAIL: [email protected]
## 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 Docker container is stateless; all data is stored in /shared
volumes:
volume:
host: /var/discourse/shared/standalone
guest: /shared
volume:
host: /var/discourse/shared/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="[email protected]""
exec: echo "End of custom commands"
仔细检查以下详细信息:
端口配置应为:
expose:
- "80"
# - "80:80" # http
# - "443:443" # https
如上所示,在文件中正确配置了现有网络名称。
docker_args:
- "--net chain"
否则,您在安装后检查域时会看到一个空白页面。
12. 引导和启动
保存上述文件后,运行以下命令:
cd /var/discourse
./launcher bootstrap app
这将花费大量时间。 在引导过程结束时,您将被要求:
./launcher start app
请注意,如果您将文件命名为 xyz.yml,则命令将相应更改(./launcher start xyz)。
它是正在运行的容器的名称,您可以使用“docker ps”进行检查。 现在,当您在浏览器中访问该域时,您将看到以下页面:
13. SSL 设置
从这一点开始,注册过程非常简单。 完成注册后,在 Docker 中 admin dashbaird,转到设置>安全并启用“强制 https”。

保存后,停止容器并重新启动它:
./launcher stop app
./launcher start app
片刻之后,SSL 将开始在您的论坛上运行。 确保你也 照顾 https 的依赖关系.
14. 在更多独立容器中安装更多 Discourse 实例
对于更多 Discourse 容器,您必须 从第 8 步开始再次重复相同的过程.
最初,您使用的是 app. 现在您应该使用其他名称,例如 app2、app3 等。
cp /var/discourse/samples/standalone.yml /var/discourse/containers/app2.yml
他们每个人还需要一个额外的步骤来在他们各自的 yml 文件中为 Docker 卷指定一个新位置(比如standalone2、standalone3 等等)(检查步骤 10)。 当然,您还必须更改域名。
## The Docker container is stateless; all data is stored in /shared
volumes:
volume:
host: /var/discourse/shared/standalone2
guest: /shared
volume:
host: /var/discourse/shared/standalone2/log/var-log
guest: /var/log
有了这个,按照其余的步骤,你将在同一台服务器上安装更多的 Discourse。
希望这篇文章对使用各自的 Docker 容器设置多个 Discourse 论坛很有用。
如果您有任何问题或建议,请随时在下面发表评论。