🦄 2024 独立开发者训练营,一起创业!查看介绍 / 立即报名(剩余8个优惠名额) →

Discourse + Docker + 阿里云的痛苦经历

Discourse 论坛我遇到两次资源占满的情况,第一次通过升级解决了问题,过年以后又遇到了占满 CPU 与内存的情况。即使没人访问一样会占满服务器的所有资源。 这次原因可能是之前服务器磁盘满了,Discourse 会在后台循环处理一些任务,比如给用户发送邮件,如果任务无法执行,会不断的重试。这应该就是导致占满资源的原因。在下面这个页面上你会看到重试的任务。访问地址:

sidekiq/retries

导致任务不断重试是因为我的邮件配置有问题。可以使用阿里云的邮件推送服务,宁皓网有相关的课程。

我折腾了一圈,升级 Discourse,升级 Docker,更新 Docker 配置,更换服务器,恢复备份。但实际上,只需要几步就能解决:

cd /var/discourse
./launcher enter app
redis-cli flushall

折腾过程

我用了一台 1 核 2G 的阿里云 ECS 服务器。遇到问题以后,重新启动应用可以维持一段时间,越往后就越严重。最开始想到的是升级 Discourse。

cd /var/discourse
git pull
./launcher rebuild app

升级完以后,遇到了问题,在用 Discourse 提供的 launcher 工具的时候,有下面的提示:

Your Docker installation is not using a supported storage driver. If we were to proceed you may have a broken install.
aufs is the recommended storage driver, although zfs/btrfs/overlay and overlay2 may work as well.
Other storage drivers are known to be problematic.
You can tell what filesystem you are using by running "docker info" and looking at the 'Storage Driver' line.

If you wish to continue anyway using your existing unsupported storage driver,
read the source code of launcher and figure out how to bypass this check.

我的 Discourse 是在 Docker 里运行的,上面提示我的 Docker 的文件系统,跟应用推荐使用的文件系统不相符。检查 Docker 的存储系统:

docker info

返回(摘取的内容):

Storage Driver: devicemapper

显示我的存储引擎是 devicemapper,Discourse 推荐使用 aufs,或 overlay。所以我想会不会是因为 Docker 的这个问题导致的。我用的 Docker  版本比较低,所以把它升级成了最新版,但在处理 Discourse 应用的时候仍然会遇到上面的提示。

其实上面提示是 Discourse 检查环境以后的结果,我们可以跳过检查,在命令后面加上 --skip-prereqs 就可以了,比如:

./launcher start app --skip-prereqs

使用这个选项虽然可以处理 Discourse 应用了,但问题仍然没有解决。

升级后的 Docker 不能启动

升级 Docker 以后,我遇到了一个 Docker 不能启动的问题,这是因为旧的 Docker 配置与新的 Docker 配置有区别,或者我之前做过的 Docker 配置跟新版 Docker 不相符。

下面是我的 Docker 服务配置文件,这个配置文件应该是我之前从另一个地方复制到这里的,然后手工修改了一下这个配置文件,我改了镜像加速地址:

/etc/systemd/system/docker.service

把上面的文件删除掉,然后执行:

sudo systemctl daemon-reload
sudo systemctl start docker

Docker 可以启动了。

修改 Docker 存储引擎

Docker 的配置文件位置:

ls /lib/systemd/system | grep docker

或者:

ls /usr/lib/systemd/system | grep docker

在上面这两个位置,你可以找到 docker.service  配置文件。编辑这个文件,添加一个启动选项,可以设置 Docker 的存储引擎:

--storage-driver=存储引擎的名字

比如

--storage-driver=overlay

把上面的选项放在 ExecStart= 这行的后面。然后再:

sudo systemctl daemon-reload

这样系统就可以使用新的配置了。当我启动 Docker 的时候,又遇到了不能启动的问题,原因是我的系统不支持我指定的存储引擎。可以用下面这个脚本检查一下:

https://raw.githubusercontent.com/docker/docker/master/contrib/check-config.sh

执行检查以后,我看到了系统里少了一些模块,所以不能用我指定的存储引擎。我想干脆换个新的服务器吧。

新服务器

买了一台新的服务器,之前 Discourse 所在的服务器也快到期了。新服务器比老的贵点,因为配置优化,硬盘是 SSD,带宽我选择的按量付费,因为我的论坛流量不大,按量付费应该能省点钱,不省也可以去再换成固定带宽。

服务器操作系统是 CentOS 7.2,安装了新的 Docker 以后,默认的存储引擎是 Overlay。我为服务器单独买了一个云盘,也是按量付费的,40G,购买的时候可以选择一个快照,我选择了一个之前在老服务器上为数据盘打的快照,这样我新买的云盘里面就会包含我需要的数据。

把新的云盘挂载到新的服务器上,登录到服务器,需要再去挂载一下,就是把数据盘挂载到某个目录下面。

sudo fdisk -l

上面可以检查你的数据盘的名字,我看到一个:

/dev/vdb1

这是我新买的数据盘,里面包含了我在老服务器上打的快照里面的数据。把这个设备挂载到某个目录的下面就能看到老的数据了。比如:

sudo mount /dev/vdb1 /var/discourse

查看一下 /var/discourse,你能看到你的数据。

让挂载在重启服务器以后也有效的话,你可以把挂载添加到 /etc/fstab 文件里,像这样:

echo "/dev/xdb1 /var/discourse ext3 defaults 1 2" >> /etc/fstab

注意 ext3 是文件系统,现在很可能是 ext4,你要确定一下,这样做:

df -TH

我这返回(摘取的内容):

/dev/xdb1 ext3 43G 6.5G 34G 17% /var/discourse

重新编译 Discourse

换了新的服务器以后,要重新编译 Discourse 应用,它会下载 Discourse 需要的 Docker 镜像,编译自己的镜像,生成容器等等。执行:

cd /var/discourse
./launcher rebuild app

完成以后,我的论坛可以打开了。

HTTPS

我想为 Discourse 启用 HTTPS,它本身支持 Let's Encrypt(一个免费的 SSL 证书提供商),你只需要配置一下就行了,在应用的 containers 下面,会包含配置,比如 app.yml,编辑一下这个文件你会看到 Let's Encrypt 的配置选项。如果看不到,可能是因为你的这个 app.yml 是之前生成的,使用 Discourse 新的 discourse-setup 生成的配置会包含 Let's Encrypt 的选项。

先重命名一下你的 app.yml,然后在应用的根目录下,执行:

./discourse-setup

会提示生成新的配置,打开新的配置,对比跟你之前的配置的区别。

我没有用 Let's Encrypt,我想用我在阿里云申请的证书。

NGINX 代理

在服务器里面安装一下 NGINX,然后配置一个代理,这样就可以在同一台服务器上运行多个在 80 端口访问的网站,包括 Discourse。在 NGINX 的配置文件,我们还可以配置一下 SSL 证书。

下面是我为 Discourse 准备的 NGINX 配置(/etc/nginx/conf.d/ssl.talk.ninghao.net.conf):

upstream discourse {
  server 127.0.0.1:8080;
}
server {
  listen       443;
  server_name  talk.ninghao.net;
  ssl          on;
  index index.html; 

  ssl_certificate   /etc/nginx/ssl/talk.ninghao.net/213977054090706.pem;
  ssl_certificate_key  /etc/nginx/ssl/talk.ninghao.net/213977054090706.key;
  ssl_session_timeout 5m;
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  ssl_ciphers AESGCM:ALL:!DH:!EXPORT:!RC4:+HIGH:!MEDIUM:!LOW:!aNULL:!eNULL;
  ssl_prefer_server_ciphers on;

  location / {
    proxy_set_header  X-Forwarded-Host $host;
    proxy_set_header  X-Forwarded-Proto $scheme;
    proxy_set_header  X-Real-IP  $remote_addr;
    proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    expires off;    
    sendfile off;
    proxy_pass http://discourse;
  }
}

我先把 Discourse 的端口设置成了 8080,可以配置 app.yml,像这样:

expose:
  - "8080:80"

8080 是服务器上的端口,后面的 80 是 Discourse 容器里的端口,在它的容器里也有一个 NGINX。修改以后,你又需要重新编译 Discourse。

让 HTTP 重定向到 HTTPS ,可以再准备一个 NGINX 配置(/etc/nginx/conf.d/talk.ninghao.net.conf):

server {
  listen      80; 
  server_name   talk.ninghao.net;
  return 301    https://$host$request_uri;
}

相关课程

宁皓网有几个课程包可以帮助你解决遇到类似的问题:DockerLinux阿里云 。

Docker

评论

看着晕晕的~
按量付费应该能省点钱,不省也可以去再换成固定带宽。 这个台还是阿里云?阿里云。好像不能随时切换。计费方式。
论坛还是discuz的省心~

咦,还真是,我再确认一下。

我确认了一下,可以变更带宽的计费方式,不过要在下一个付费周期变更,所以最好服务器的费用按月交。在后面选择 升降配 - 降配续费。

嗯~~不过按月交比较贵!~~这次我有台买了3年~~

嗯,要么就在服务器前面放一台负载均衡。

443 端口的配置和 80 端口的配置可以写在同一个配置文件里面的,像这样:
server {
listen 80;
listen 443 ssl http2;
server_name talk.ninghao.net
}

这样写就不用配置重定向了。当然,这要求 Nginx 的版本比较新,好像要 1.10 以上(?)

又学一招,不过这样是不是要访问 http 与 https 都可以打开同一个页面?我想当用户访问 http 的时候跳转到 https 。

Nginx 会自动判断浏览器是否支持 https。支持的话,即使你输入的网站不带 https,都会自动跳转到 https 的页面。试试访问我的博客就知道了:www.loyalsoldier.me

阿里云的1G内存1核服务器能跑几个docker容器啊?

1G 不大够用,再加 1G。

要是出一些Discourse的课程就好了,准备搭建一个社区平台,想用Discourse来搭建

微信好友

用微信扫描二维码,
加我好友。

微信公众号

用微信扫描二维码,
订阅宁皓网公众号。

240746680

用 QQ 扫描二维码,
加入宁皓网 QQ 群。

统计

15260
分钟
0
你学会了
0%
完成

社会化网络

关于

微信订阅号

扫描微信二维码关注宁皓网,每天进步一点