Discourse 是否可以频繁发布无需引导的 Docker 镜像?

Rebuilds are far from a common or regular practice. Most upgrades can be performed from /admin/upgrade

And for sites where any server error is a problem there are guides on how to present a holding page during the upgrade process.

I have to perform rebuilds when I add or remove plugins, and when they are mandated by the occasional upgrade (several times a year). But yes, it’s not a showstopper for a local community forum like mine, and /admin/upgrade works very well for regular updates.

I present a holding page during my rebuild upgrades for the benefit of users, but how would the Googlebot perceive this? To the bot, my homepage suddenly has no intra-site links, and all the pages the bot has previously indexed have their content replaced with the holding page.

If you’re catching all requests with a 302 to show the holding page there should be zero impact. Google confirmed a couple of years back that redirects don’t impact SEO/pagerank:

Gary is the “House Elf and Chief of Sunshine and Happiness at Google” (Webmaster Trends Analyst)

If you’ve just rebranded the 502 error page then yes, it will have an impact.

What you don’t understand is that most of the people deploying discourse don’t know what docker is, much less care about best practices.

If you want a docker image, just use pups to generate it yourself. Is that what you guys do, @sam? Do create a separate container image for each enterprise client with their plugins?

If you want to avoid downtime when you need to rebuild, make a 2 container configuration. You can search here or look in discourse-setup for a command line option that will build one for you. Then downtime is limited to the time it takes for the new container to boot up.

If you want zero downtime, configure haproxy with multiple web containers.

There’s a very large number of people running their own servers who are looking for this exactly. I know personally dozens of hobbyists who are looking for a forum which is truly self-hosted, not on a droplet or other VPS. Many self-hosting enthusiasts run multiple apps (think Nextcloud, Plex, Wikis, CMS/Blogs, etc.), whether they actually host them or run them on a VPS. Here’s my situation: I’m running docker swarm for dozens of apps. It seems to me at least that the way the tool works now it can’t be incorporated into a docker swarm with Traefik or HAProxy reverse-proxying requests.

Maybe (hopefully!) I’m mistaken and you can explain or point me to instructions on how to take your final, single completed container, reference it in a new docker-compose and run it in a swarm?

I understand that. But the developers of Discourse do, and they depend on it for their deployments. I apologize, I don’t know what pups is. Looks like it’s related to Ansible, which I don’t know.

Debt in the deployment management code & process. It is very complicated right now with lots of moving parts and things that are difficult to understand and support. One of docker’s primary draws is the encapsulation of prerequisite code and builds which complete prerequisite work with less risk of a user messing something up, especially if the whole thing is ultimately wrapped in a script to create/upgrade the installation. That gives those who don’t (and don’t need to) understand docker well a good solution, and gives engineers or “hobbyists” a solution as they could skip the wrapper and compose things the way they want.

One of the things I think overlooked here is that a major reason for self-hosting is control over data and backups, etc. Docker makes this especially convenient since you can bind volumes and back those up, and even run a container in the stack whose role is backing up the DB to a flat file in the backup location. When you can’t self-host it along with other docker apps, it effectively means you cannot self-host on your server, you need to purchase a VPS just for Discourse, rather than reusing the same hardware and ecosystem that works for the vast majority of apps which use docker in their deployment.

By way of disclaimer, I am not employed or compensated by any hardware vendor, Saas provider, or forum software developers.

Think about how many potentially unnecessary Digital Ocean, Linode, and VULTR subscriptions Discourse has been responsible for launching. Then consider that there are companies making a revenue stream hosting Discourse for others in part because it is too complex for them:

The Discourse forum software is fantastic, but quite hard to install and host it yourself. We think it’s too great a product to be limited to a technical audience only.

Then again, the way you’ve modeled your revenue-stream, it makes zero sense making things easier to install and run in simple to use containers which expose only necessary ports and bind mounts, using environment variables for everything else so that deployment is as simple as docker stack deploy or docker-compose up. Like I said - maybe and hopefully I’m the one mistaken, and there’s a way to take the final docker container and deploy it in a swarm or other compose environment with other apps and a reverse proxy.

This is exactly the point many folks have been making in this lengthy thread: Is there a solution for those who do know what nano is and can exit VI / VIM just fine? I trust you know your customer base better than I, but I have to imagine that such basic knowledge of Linux is the case for the overwhelming majority of those wanting to self-host open-source software on Linux.

Yes. Create a web_only.yml (there is a sample in discourse_docker) and use that to build your docker image with your plugins. Then add it to your swarm. Everything can be configured via environment variables; you can see them in the last line when you to a ./launcher start web_only. It’s not that hard, but you’re not going to get free support here to help you figure it out (and it’s not just you but a whole bunch of people with a zillion different definitions of Best Practices who would need much, much more help than you would).

I can probably help you figure out what you need to know in an hour or two of my time.

Recently I found the commands to fast forward a git clone depth 1:

git checkout --detach #avoid tangle with git tree state
git fetch --depth 1 -f -origin [branch|commit]
git checkout -f [branch|commit]

Thanks to archive.org team.

So would running ./launcher bootstrap mybase that had the bundle exec rake db:migrate; bundle exec rake assets:precompile added to the init script do something like that? Just run it against a test database, or maybe strip those rake tasks out of web.template.yml?

EDIT: Found this comment:

  # this allows us to bootstrap on one machine and then run on another

which might answer my question.

这是否意味着您仍然会为每次部署基于基础镜像加上 precompile assets 所做的更改来引导生成新镜像,还是您只使用单个镜像,并在启动时进行预编译?

我们在技术上会进行两次预编译。第一次是针对基础镜像及其中的更改进行预编译,第二次是在部署特定站点并加载特定插件时进行预编译。

不过,我们的设置方式并不适合普通用户,除非你是以商业目的托管 Discourse。

我非常想使用 Discourse,但开发者使用容器技术的方式让我无法接受。我从未见过有哪个项目能把容器安装做得如此不可移植。其实有更好的方法来解决这个问题。在我看来,这个项目似乎是“自然演化”到了容器化,但却并不真正懂得如何正确使用容器。结果,项目现在被这种过于复杂且不可移植的方案所困住。而且,受限于时间,恐怕也难以构建一个真正可移植的容器方案。

请提供一个 Dockerfile,使其能够构建出状态一致的环境。同时,请文档化用户应使用哪些环境变量来调整容器行为。只需使用一个入口点脚本,确保所有服务在运行时正确启动即可。容器组合完全可以通过 Docker Compose 或 Kubernetes 来实现,而不是像现在这样——这真的让人很无语。

我尝试在 Fedora CoreOS、CentOS 8 或 Fedora 32 等系统上运行它,但都无法实现。容器标准本应允许这样的部署,但当前的做法实际上只是精心适配了 Ubuntu LTS,从而限制了其他系统的支持。尽管已有一些人开始弃用 Docker(尤其是在以 root 身份运行服务时),但容器技术本身是标准化的,用户本可以选择使用 Docker 或 Podman。然而,这种“弗兰肯斯坦”式的实现让这一切变得异常困难,这与容器技术的理念以及现代容器安全原则背道而驰。

不妨看看 2014 年的情况。当该项目启动时,docker-compose 尚未真正问世。

确实如此!也许你可以修复它。你只需要彻底改变构建和启动容器的所有方式,并确保这不会导致成千上万个正常运行的网站出现故障。

或者,你可以调整你的容器,使其能够配合任何工具启动,从而让那些懂得如何正确使用容器的人感到满意。Bitnami 似乎已经做到了这一点。你可以在这里搜索,会发现许多曾遇到麻烦却求助无门的人。

我知道这并不容易。但容器的目的是实现一致且可移植的状态。因此,如果容器按预期使用,并且对你有效,那么对于所有使用该容器的人而言,它有效的可能性也相当高。

如果将引导过程(bootstrap)直接移入容器内部,而不是在主机上运行,你已经在实现可移植性方面取得了很大进展。等完成其他项目后,我可以查看一下。我也不是容器专家,但我构建过几个。不过,缺点是缺乏安装文档,对吧?目前只是“给你,运行这个脚本”。我可以尝试复现脚本的功能,但这几乎没有留下提出改进建议的空间。

因此,如果社区(尤其是那些深度参与并了解安装应如何运作的人员)愿意提供建议或帮助,我乐意发起这项倡议。否则,质量将无法达到预期。

基本目标大致如下:

  • 一个 Dockerfile,实现设置的原子化构建(容器外部无本地引导过程)
  • 无需以 root 身份运行容器,最佳方案是使用 fakeroot 并添加 capabilities(这些是命令行参数,用户仍可选择以 root 身份启动容器……)
  • 创建一个可由环境变量影响的入口点脚本,这些变量必须清晰文档化
  • 使用 podman-generate-systemd 或类似工具创建 systemd 单元,以(重新)启动容器或在启动时自动运行容器(Podman 功能,Docker 可能有类似功能,但更侧重于集成化)

这适用于基本安装。对于可扩展方案,则需要 docker-compose 和 Kubernetes 解决方案。坦白说,我认为寻找“一刀切”的解决方案并非 Discourse 社区的责任。因为这些方案可以根据具体需求进行精细定制,尤其是在 Kubernetes 上。因此,我认为一个基础的 Compose 方案足以帮助人们快速上手。

这将提供一个可移植且更安全的解决方案,从而整体提高采用率和质量。在此期间,我会看看 Discourse 是否真的符合我社区的需求。如果需要,我目前将使用 Ubuntu LTS 系统。等我有更多时间后,我会投入精力构建这样的环境。

你好 @AquaL1te

我已经按照你的建议做了一些工作。它支持使用 Podman、K8s 或 Docker。支持无根(rootless)模式(并非 fakeroot)。它采用四容器架构,包含 Nginx、Sidekiq、Redis 和 Ruby 守护进程。

一般来说,可以参照开发者安装文档进行操作。

需要注意的是,Discourse 在处理资源文件方面存在一些复杂之处。

啊,是的。我之前对术语有些混淆,最近我一直在大量使用 Singularity,它使用的是 --fakeroot 标志。

我会去查看一下,听起来非常棒!因为我更倾向于在此场景下使用 Fedora CoreOS,以最大化容器化环境的安全潜力。不过,在当前的设置中,这还不容易实现。

主要解决方案缺乏可移植性这一点仍让我感到困扰,而且目前也看不到向现代化方案发展的迹象。我会更详细地研究您的设置,未来或许会联系您共同维护该项目(当然,如果需要的话)。感谢您的工作和建议!

我刚读完这条超长的讨论串,尤其对 Gkoerk 的需求感同身受。他曾在 2018 年 10 月 19 日发表评论,寻求在 Docker Swarm 中自行托管 Discourse 的帮助——据说是为了将其纳入他那堪称集大成的 docker-swarm-cookbook。哇,这真是一个令人惊叹的合集!据报道,Gkoerk 年仅 40 岁便离世。太遗憾了。他看起来是一位真正出色的伙伴和贡献者。