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.

14개의 좋아요

안녕하세요,

관리자 계정이 생성되지 않음

d/ 폴더의 스크립트(예: Install Discourse for development using Docker 에 지정된 대로 d/boot_dev --init)를 통해 외부에서 Docker 컨테이너를 사용할 때, 프로세스의 일부로 관리자 계정을 설정하라는 메시지가 표시됩니다.

하지만 Dev Container로 사용하고 빌드 단계(ctrl/cmd + shift + b)를 실행하면 관리자가 생성되지 않습니다.

설계 문서를 대충 살펴보니 처음에는 관리자를 만드는 것이 꽤 까다로울 것 같았지만, 결국 아래 명령어 하나면 된다는 것을 깨달았습니다. 동일한 문제를 겪는 분들을 위해 여기 남겨 둡니다:

rake admin:create

(또는 다른 rake 버전이 필요하다고 경고가 뜰 경우: bundle exec rake admin:create)

7개의 좋아요

Windows 11에서 줄바꿈 문자(line ending) 관련 문제, 예를 들어 다음과 같은 문제를 겪고 싶지 않다면:

[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

.. Clone in Volume을 반드시 사용해야 합니다.

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 Container 실행하고 Ctrl-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",

참고: GitHub Codespaces에서 정의된 것처럼 *.orb.local 호스트 이름과 컨테이너 이름을 동적으로 설정하는 방법을 아시는 분에게 알려주시면 감사하겠습니다. 값을 .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

명령어의 코드는 discourse/bin/docker/boot_dev at main · discourse/discourse · GitHub 에 있습니다.

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을 다른 파일로 변경하세요.
  • 셸에서 분리된 상태로 실행을 계속 유지하려면 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가 모두 포트 포워딩을 시도하기 때문입니다). 별도의 devcontainer-cli.json을 만들고 devcontainer --override-config .devcontainer/devcontainer-cli.json을 사용했는데, 그렇게 하니까 작동했습니다.

하지만 그제서야 깨달았습니다: 이렇게 많은 노력을 기울였지만, 기존 boot_dev 스크립트를 사용하는 것과 비교해 더 나아진 것이 없습니다. 문서화된 단계를 따르는 것이 CLI에서 devcontainer를 올바르게 작동시키려고 애쓰는 것보다 빠르고 쉽습니다.

Dev Containers는 주로 VS Code, 또는 포트 포워딩을 자동으로 관리해 주는 _무언가_와 함께 사용할 때 의도된 것입니다. devcontainer CLI는 그렇게 하지 않습니다. 따라서 VS Code를 원하지 않는다면, Dev Containers를 사용하는 것도 고려해 볼 가치가 없을 수 있습니다.

내 지시사항은 Linux용이었습니다. (제 경우에는 구체적으로 NixOS를 사용했지만) 다른 Linux 기반 시스템에서도 작동하지 않을 이유는 없습니다.

@dfabulich 님의 게시글을 읽었고, 문제를 이해한 것 같습니다. 포트 포워딩은 필요하지 않습니다. 컨테이너의 IP 주소를 사용해야 합니다. 127.0.0.1은 로컬호스트(컨테이너가 아닌 로컬 시스템)를 가리킵니다.

jq 명령어는 포트 포워딩 없이도 접근할 수 있는 로컬 LAN 서브넷 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 주소)으로 접근하면 macOS에서는 적어도 에임버(ember)까지 연결이 되지 않습니다.

macOS에서 Docker Desktop은 단순히 가상 머신을 실행할 뿐이라는 점을 유의하세요. macOS에는 "가벼운 프로세스 수준의 Docker 컨테이너"라는 개념이 없습니다.

macOS에 대해 충분히 알지 못해서 Docker가 Linux에서처럼 커널 네임스페이스를 사용하는지 모르겠습니다. 다시 테스트를 해 보았습니다(참고: 서비스가 시작되는 데 시간이 조금 걸립니다):


그렇지 않습니다. macOS용 Docker Desktop은 문자 그대로 QEMU를 실행하고 있습니다. (또는 최근까지 그랬습니다. 지금은 QEMU에 웃긴 모자와 수염을 붙인 것과 같은 새로운 것을 사용하고 있지만, 어쨌든 구현 방식은 여전히 완전한 가상 머신입니다.)

따라서 사용자의 컴퓨터에서는 작동할 것이라고 확신하지만, 제 macOS 컴퓨터에서는 작동하지 않으며, 이것이 가장 그럴듯한 이유라고 생각합니다.

1개의 좋아요