Developing Discourse using a Dev Container

Dev Containers is an open standard for configuring a development environment inside a container. This almost entirely eliminates the need to install/configure Discourse-specific tools/dependencies on your local machine, and makes it very easy to keep up-to-date as Discourse evolves over time.

Dev Containers can be used in a number of different IDEs, or directly using their reference CLI. This guide will describe the setup process for VSCode.

Getting started

  1. Download and install VSCode

  2. Install the Dev Containers extension in VSCode

  3. Clone the Discourse repository onto your machine

    git clone https://github.com/discourse/discourse
    
  4. In VSCode, use FileOpen Folder, then choose the Discourse directory

  5. Open the folder in its Dev Container. This can be done via the popup prompt, or by opening the command palette (Cmd/Ctrl + Shift + P) and searching for “Open folder in container…”

  6. If this is your first time launching a container, you will be prompted to install and start Docker Desktop. Once complete, go back to VSCode re-run “Open folder in container…”

  7. Wait for the container to download and start. When it’s done, the README will appear, and you’ll see the Discourse filesystem in the sidebar.

  8. Run the default build task using Cmd/Ctrl + Shift + B.

    This will install dependencies, migrate the database, and start the server. It’ll take a few minutes, especially on the lower-end machines. You’ll see “Build successful” in the terminal when it’s done.

  9. Run the dev/admin/create task. Open the command palette and search for “Tasks: Run Tasks”. It will present a menu of tasks; select dev/admin/create off of that list. You’ll be prompted to enter an email address and a password for your admin user.

  10. Visit http://localhost:3000 in your browser to see your new Discourse instance

  11. All done! You can now make changes to Discourse’s source code and see them reflected in the preview.

Running tests

The first time you run tests, you’ll need to install testing dependencies, including Playwright and the discourse_test DB. You can run the deps/testing task to install those. Open the command palette, select “Tasks: Run Tasks”. It will present a menu of tasks; select deps/testing off of that list.

Once the test dependencies are installed, you can run bin/lint, bin/qunit, or the system specs

Applying config/container updates

Every so often, the devcontainer config and the associated container image will be updated. VSCode should prompt you to “rebuild” to apply the changes. Alternatively, you can run “Dev Containers: Rebuild Container” from the VSCode command palette. The working directory, and your Redis/Postgres data will be preserved across rebuilds.

If you’d like to start from scratch with fresh database, you’ll need to delete the discourse-pg and discourse-redis docker volumes. This can be done from the “Remote Explorer” tab of the VSCode sidebar.

Discourse’s sample vscode .vscode/settings.json and .vscode/tasks.json will be copied when you first boot the codespace. From that point forward, if you want to use the latest sample config, you’ll need to manually copy .vscode/settings.json.sample to .vscode/settings.json.

References


This document is version controlled - suggest changes on github.

13 个赞

您好,

未创建管理员帐户

当通过 d/ 中的脚本从外部使用 docker 容器时(例如,按照 Install Discourse for development using Docker 中的说明运行 d/boot_dev --init),它会要求我在过程中设置一个管理员帐户。

但是,当将其用作开发容器并运行构建步骤(Ctrl/Cmd + Shift + B)时,它不会创建管理员。

从快速浏览说明来看,我最初认为创建管理员非常困难;但随后我意识到,只需执行此命令即可,在此留下给遇到相同问题的人:

rake admin:create

(或者,如果它抱怨需要不同的 rake 版本:bundle exec rake admin:create

7 个赞

在 Windows 11 上,如果你不想遇到行尾符问题,例如:

[23963 ms] Start: Run in container: /bin/sh -c ./.devcontainer/scripts/start.rb
/usr/bin/env: ‘ruby\r’: No such file or directory
/usr/bin/env: use -[v]S to pass options in shebang lines

..请确保 \u003ckbd\u003e在卷中克隆\u003c/kbd\u003e

6 个赞

也许有更好的方法,但在插件上工作时,我有一个与我的主 discourse 存储库文件夹并排的 discourse-plugins 文件夹。这会挂载到 /workspace/plugins,因此我可以在容器内创建符号链接。

这是我添加到 devcontainer.json 中 mounts 的内容:
\"source=${localWorkspaceFolder}/../${localWorkspaceFolderBasename}-plugins,target=/workspace/plugins,type=bind\"

2 个赞

这确实有用,感谢。

1 个赞

… 或者只需 git reset --hard
对我有效
然后 Dev Container: Rebuild ContainerCtrl-Shift-B

如果您正在本地 macOS 环境中使用 OrbStack(非官方),并且希望使用自定义域名以 HTTPS 运行 Discourse,请在您的 devcontainer.json 中进行以下更新:

  1. 为容器命名。
  2. RAILS_DEVELOPMENT_HOSTS 环境变量中添加 .orb.local 通配符域名(主机名必须用逗号分隔)。
--- a/.devcontainer/devcontainer.json
+++ b/.devcontainer/devcontainer.json
@@ -13,10 +13,11 @@
   ],
   "remoteUser": "discourse",
   "remoteEnv": {
-    "RAILS_DEVELOPMENT_HOSTS": ".app.github.dev",
+    "RAILS_DEVELOPMENT_HOSTS": ".app.github.dev,.orb.local", // 步骤 2
     "PGUSER": "discourse",
     "SELENIUM_FORWARD_DEVTOOLS_TO_PORT": "9229",
   },
+  "runArgs": ["--name","discourse"], // 步骤 1
   "mounts": [
     "source=${localWorkspaceFolderBasename}-node_modules,target=${containerWorkspaceFolder}/node_modules,type=volume",
     "source=${localWorkspaceFolderBasename}-pg,target=/shared/postgres_data,type=volume",

附注:如果您知道如何动态设置 *.orb.local 主机名和容器名称(如 GitHub Codespaces 中所定义),请告诉我。对我来说,将值设置为 .app.github.dev,.orb.local 并未奏效。

更新: 不知何故,我的 /etc/hosts 文件中缺少一个记录。添加此行后,我便能够使用步骤 2 中的 .orb.local 通配符域名。

通过对 devcontainer.json 文件进行这些更改,我现在可以在 https://discourse.orb.local/ 上运行我的本地 Discourse 实例。

/etc/hosts

如果您的 /etc/hosts 文件中还没有,请添加此行。

##
# Docker and OrbStack
##
127.0.0.1 host.docker.internal

奖励提示 1
如果您的网络设置或公司 VPN 网络等与 OrbStack 的容器 IP 地址范围发生冲突,请在 OrbStack 中更新为不同的范围。

奖励提示 2
如果省略步骤 1,OrbStack 将创建一个随机命名的容器,但您仍然可以使用 HTTPS,而无需附加任何端口号。缺点是容器名称(因此域名)会在每次重建容器时刷新。

1 个赞

看来 Orbstack 可以运行 Docker 镜像。如果你正尝试用于生产环境,你可能想参考:

如果是用于开发,我认为 Discourse 使用的是 discourse/discourse_dev - Docker Image 镜像。但你可能需要自己进行设置。

供你参考,我相信 Docker

命令的代码位于 https://github.com/discourse/discourse/blob/main/bin/docker/boot_dev。

1 个赞

对于不习惯使用 VSCode 的用户,以下是仅通过 devcontainers CLI 运行 devcontainers 的流程。
假设您已经安装了 devcontainers:

构建容器

git clone https://github.com/discourse/discourse && cd discourse
devcontainer build
devcontainer up --workspace-folder .
devcontainer exec bash

进入容器后,您需要构建依赖项:

pnpm install
bundle install
SKIP_MULTISITE=1 SKIP_TEST_DATABASE=1 bin/rake db:create db:migrate
DISCOURSE_DEV_ALLOW_ANON_TO_IMPERSONATE=1 bin/ember-cli -u > /dev/null 2>&1 &
  • 如果需要查看日志,请将 /dev/null 替换为其他文件
  • 如果希望在断开 shell 连接后让进程继续运行,请执行 disown

访问 Discourse

docker inspect <name> | jq '.[0].NetworkSettings.Networks.bridge.IPAddress'

这将显示分配给容器的 IP 地址。
在浏览器中打开 http://<ipaddress>:4200

清理

删除您的 devcontainer(目前尚未开发 down/delete 选项)
获取容器名称:
docker ps
停止并删除容器:
docker stop <name> && docker rm <name>
删除卷:
docker volume rm discourse-node_modules discourse-pg discourse-redis

4 个赞

那些非 VS Code 的说明刚才在 macOS 上对我并不奏效。我推荐希望在与 VS Code 无关的情况下与 Discourse Docker 镜像交互的 macOS 用户,改用传统的 boot_dev Docker 脚本。

通过 docker ps,我找到了容器名称(一个随机生成的滑稽名称,例如 peaceful_lumiere)。我运行了 docker inspect peaceful_lumiere | jq '.[0].NetworkSettings.Networks.bridge.IPAddress',它输出了一个 IP 地址。我在浏览器中访问 http://<ip>:4200,但它一直转圈,永远无法加载。

我认为这是因为 ember-cli 开发服务器并未监听所有网络接口;它仅在容器内部监听 http://127.0.0.1:4200

最终,我通过向 .devcontainer/devcontainer.json 添加一个 runArgs 部分解决了问题,如下所示:

     8025, // mailhog
     9229  // chrome remote debug
   ],
+  "runArgs": [
+    "-p",
+    "127.0.0.1:4200:4200",
+    "-p",
+    "127.0.0.1:3000:3000",
+    "-p",
+    "127.0.0.1:9292:9292",
+    "-p",
+    "127.0.0.1:8025:8025",
+    "-p",
+    "127.0.0.1:9229:9229"
+  ],
   "remoteUser": "discourse",
   "remoteEnv": {
     "RAILS_DEVELOPMENT_HOSTS": ".app.github.dev",

……但如果你这样做,它在 VS Code 中将无法工作(因为 VS Code 和开发容器都会尝试转发端口)。我创建了一个单独的 devcontainer-cli.json 文件,并使用 devcontainer --override-config .devcontainer/devcontainer-cli.json 命令,结果成功了。

但随后我恍然大悟:我折腾了这么多,结果却并不比直接使用现有的传统 boot_dev 脚本更好。按照文档步骤操作,比试图通过 CLI 强行让 devcontainer 做正确的事情要更快、更简单。

开发容器(Dev Containers)主要是为在 VS Code 或某种能自动管理端口转发的工具中使用而设计的;devcontainer CLI 并不具备此功能。因此,如果你不想使用 VS Code,或许就不要折腾开发容器了。

我应提及我的说明是针对 Linux 的(在我的情况下具体是 NixOS),但它在其他基于 Linux 的系统上运行也没有问题。

@dfabulich 我读了你的帖子,我认为我理解问题了。端口转发是不必要的。你需要容器的 IP 地址。127.0.0.1 是 localhost(你的本地系统,而不是容器)。

jq 命令本应输出一个本地局域网子网 IP,你无需端口转发即可访问该 IP。

不,是我做的。jq 输出了 "172.17.0.2",而 http://172.17.0.2:4200 一直卡在那里无限加载。

在容器内部,ember-cli 并没有监听 0.0.0.0:4200,而是监听 127.0.0.1:4200。因此,如果你通过 172.17.0.2:4200(或你的实际 IP)访问它,请求永远无法到达 Ember,至少在 macOS 上是这样。

请注意,在 macOS 上,Docker Desktop 只是运行在一个虚拟机中。在 macOS 上不存在所谓的“轻量级进程级 Docker 容器”。

我对 macOS 了解不够,无法确定 Docker 是否像 Linux 那样使用内核命名空间。我再次进行了测试(注意:服务启动需要一点时间):


并不是。macOS 上的 Docker Desktop 实际上是在运行 QEMU。(或者说,直到最近还是这样;现在他们采用了一种新方案,本质上就像是戴了滑稽帽子和假胡子的 QEMU;无论如何,它仍然是在运行一个完整的虚拟机作为其实现方式。)

所以,我敢肯定它在你的机器上能运行,但在我的 macOS 机器上却无法运行,我认为这很可能就是原因所在。

1 个赞