如何在同一服务器上安装多个Discourse容器

时间:2020-03-05 15:29:01  来源:igfitidea点击:

当服务器上只有一个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服务器。

在本教程中,我已经使用theitroad.com作为示例域名。
请确保根据我们自己的域或者子域进行更改。

1.更改域的DNS记录

在域名提供商的DNS记录面板中,确保域和子域(包括www)都指向服务器的IP地址。

例如,对于根域,请将主机名字段保留为空白(或者@),对于子域,请在设置服务器IP时使用“ *”通配符。

2.交换空间

为确保所有容器应用程序都放心使用,并且在部署它们后不会耗尽内存,至关重要的是,系统上必须有必要的交换空间。

我们始终可以根据系统上的可用内存来调整交换。

我们可以根据单个服务器上的应用程序容器捆绑确定交换空间,并估计它们的累积内存使用量。
话语还会为我们检查并配置交换。

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的配套容器负责使用Let's Encrypt设置SSL证书。

我们将在最终设置Discourse容器时看到。

6.通过Nginx进行WWW重定向(不需要CNAME,使用子域的可选步骤)

为确保将theitroad.com请求重定向到www.theitroad.com,就像其他任何一样,我们需要执行另一步骤。

输入nginx-proxy容器:

docker exec -ti nginx-proxy /bin/bash

我们现在将看到如下所示的根提示:

Hyman@theitroad:/app#

还记得我在第4步中提到的/etc/nginx/vhost.d位置吗?
在此处创建一个与根域名相同的新文件。
我们这里没有vim或者nano。
不要使用Vim或者Nano,而应使用cat命令。

cat >> /etc/nginx/vhost.d/theitroad.com

在下一个提示符下,无论我们写什么,都将编辑该文件。
因此,请确保在下一行中将www.theitroad.com替换为我们自己的域:

rewrite ^/(.*)$https://www.theitroad.com/ permanent;

按Enter,然后按Ctrl + D进行保存。
输入exit退出容器。

Hyman@theitroad:/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镜像

按照官方教程,将官方discourse 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已被同一端口使用。
我们还已经拥有我们的letencrypt容器,并且必须向Discourse显示要放入的现有Docker网络。

在此处设置域时,我们还需要一个邮件服务器来配置论坛通知电子邮件(我在这里使用了Sendgrid)。

请注意,如果需要,LETSENCRYPT_EMAIL(用于通知SSL更新)和DISCOURSE_DEVELOPER_EMAILS(用于管理员)可以不同。

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 http://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 内存, 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: 'theitroad.com'
   VIRTUAL_HOST: 'theitroad.com,www.theitroad.com'
   LETSENCRYPT_HOST: 'theitroad.com,www.theitroad.com'
   LETSENCRYPT_EMAIL: 'Hyman@theitroad'
 ## 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 'Hyman@theitroad,Hyman@theitroad'
   DISCOURSE_DEVELOPER_EMAILS: 'Hyman@theitroad'
 ## 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: Hyman@theitroad
 ## 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='Hyman@theitroad'"
 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管理员dashbaird中,转到settings> security并启用“ force 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。