From 55bc3c1636cc96872c9c43721e2f6344fb5c4ada Mon Sep 17 00:00:00 2001 From: Lewis Nixon Date: Sun, 19 Jul 2026 21:35:36 +0100 Subject: [PATCH 1/7] Setup VS Code Dev Container configuration Add a .devcontainer configuration so contributors can develop Ghostfolio inside a containerized environment with Node.js, PostgreSQL and Redis pre-wired together, without needing to install anything locally besides Docker and VS Code. Closes #7380 --- .devcontainer/Dockerfile | 11 +++++++++++ .devcontainer/devcontainer.json | 31 +++++++++++++++++++++++++++++++ .devcontainer/docker-compose.yml | 13 +++++++++++++ DEVELOPMENT.md | 24 ++++++++++++++++++++++++ 4 files changed, 79 insertions(+) create mode 100644 .devcontainer/Dockerfile create mode 100644 .devcontainer/devcontainer.json create mode 100644 .devcontainer/docker-compose.yml diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 000000000..590a23198 --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,11 @@ +FROM node:22-slim + +# Match the build tooling used by the production Dockerfile so native +# dependencies (e.g. Prisma) compile correctly inside the Dev Container +RUN apt-get update && apt-get install -y --no-install-recommends \ + g++ \ + git \ + make \ + openssl \ + python3 \ + && rm -rf /var/lib/apt/lists/* diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 000000000..57ca346a5 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,31 @@ +{ + "name": "Ghostfolio", + "dockerComposeFile": [ + "../docker/docker-compose.dev.yml", + "docker-compose.yml" + ], + "service": "app", + "workspaceFolder": "/workspaces/ghostfolio", + "shutdownAction": "stopCompose", + "remoteUser": "node", + "forwardPorts": [3333, 4200], + "portsAttributes": { + "3333": { + "label": "API" + }, + "4200": { + "label": "Client" + } + }, + "postCreateCommand": "npm install", + "customizations": { + "vscode": { + "extensions": [ + "angular.ng-template", + "esbenp.prettier-vscode", + "firsttris.vscode-jest-runner", + "nrwl.angular-console" + ] + } + } +} diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml new file mode 100644 index 000000000..da89f4775 --- /dev/null +++ b/.devcontainer/docker-compose.yml @@ -0,0 +1,13 @@ +services: + app: + build: + context: .. + dockerfile: .devcontainer/Dockerfile + volumes: + - ..:/workspaces/ghostfolio:cached + command: sleep infinity + depends_on: + postgres: + condition: service_healthy + redis: + condition: service_healthy diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index 5b1b36afb..965ea5694 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -18,6 +18,30 @@ 1. Open https://localhost:4200/en in your browser 1. Create a new user via _Get Started_ (this first user will get the role `ADMIN`) +### Dev Container + +As an alternative to the manual _Setup_ above, [Visual Studio Code](https://code.visualstudio.com) users can develop inside a [Dev Container](https://containers.dev). It runs the application in a Docker container alongside [PostgreSQL](https://www.postgresql.org) and [Redis](https://redis.io), pre-installed with the required build tooling (Node.js 22, `g++`, `make`, `python3`). + +#### Prerequisites + +- [Docker](https://www.docker.com/products/docker-desktop) +- [Visual Studio Code](https://code.visualstudio.com) with the [Dev Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) extension +- Copy the file `.env.example` to `.env` and populate it with your data (`cp .env.example .env`) + +**Info:** Use `.env.example`, not `.env.dev`, as the base for `.env`. Inside the Dev Container, the application and the databases run as separate containers on the same Docker network, so `DATABASE_URL` and `REDIS_HOST` must point to the service names `postgres` and `redis` (as `.env.example` already does), not `localhost`. + +#### Setup + +1. Open the repository folder in Visual Studio Code +1. Run the command _Dev Containers: Reopen in Container_ (this builds the container and runs `npm install` automatically) +1. In the container's integrated terminal, run `npm run database:setup` to initialize the database schema +1. Start the [server](#start-server) +1. Start the client with `npm run start:client -- --host 0.0.0.0` instead of the usual command (see note below) +1. Open https://localhost:4200/en in your browser +1. Create a new user via _Get Started_ (this first user will get the role `ADMIN`) + +**Info:** The client dev server binds to `localhost` by default, which is only reachable from within the container itself. Passing `--host 0.0.0.0` makes it listen on all interfaces so Visual Studio Code's forwarded port reaches it from your browser on the host. This is not required for the server, which already binds to `0.0.0.0` by default. + ### Start Server #### Debug From a79be928b6aa9145e10dae993587d57d7f8f138f Mon Sep 17 00:00:00 2001 From: Lewis Nixon Date: Wed, 22 Jul 2026 20:19:18 +0100 Subject: [PATCH 2/7] Isolate node_modules in Dev Container with a named volume Bind-mounting the whole repo meant a host-installed node_modules (e.g. from macOS/Windows) shadowed the container's own install, causing native modules like Prisma's query engine to be built for the wrong platform. --- .devcontainer/docker-compose.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml index da89f4775..2d849c129 100644 --- a/.devcontainer/docker-compose.yml +++ b/.devcontainer/docker-compose.yml @@ -5,9 +5,13 @@ services: dockerfile: .devcontainer/Dockerfile volumes: - ..:/workspaces/ghostfolio:cached + - node_modules:/workspaces/ghostfolio/node_modules command: sleep infinity depends_on: postgres: condition: service_healthy redis: condition: service_healthy + +volumes: + node_modules: From 8abad7260754c65722ac261886b9e31142a20fbf Mon Sep 17 00:00:00 2001 From: Lewis Nixon Date: Wed, 22 Jul 2026 20:19:34 +0100 Subject: [PATCH 3/7] Base Dev Container .env on .env.dev instead of .env.example .env.example doesn't set NX_ADD_PLUGINS=false, so pointing Dev Container users at it silently changed their Nx task-inference behavior compared to everyone else's setup. Base on .env.dev like the manual setup does, and just override DATABASE_URL/REDIS_HOST for the containerized services. --- DEVELOPMENT.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index 965ea5694..7ec29f1c2 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -26,9 +26,9 @@ As an alternative to the manual _Setup_ above, [Visual Studio Code](https://code - [Docker](https://www.docker.com/products/docker-desktop) - [Visual Studio Code](https://code.visualstudio.com) with the [Dev Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) extension -- Copy the file `.env.example` to `.env` and populate it with your data (`cp .env.example .env`) +- Copy the file `.env.dev` to `.env` and populate it with your data (`cp .env.dev .env`) -**Info:** Use `.env.example`, not `.env.dev`, as the base for `.env`. Inside the Dev Container, the application and the databases run as separate containers on the same Docker network, so `DATABASE_URL` and `REDIS_HOST` must point to the service names `postgres` and `redis` (as `.env.example` already does), not `localhost`. +**Info:** Use `.env.dev`, not `.env.example`, as the base for `.env`, since it also sets `NX_ADD_PLUGINS=false` to keep _Nx_ behaving the same as in the manual _Setup_ above. Inside the Dev Container, the application and the databases run as separate containers on the same Docker network, so after copying, change `DATABASE_URL` and `REDIS_HOST` to point to the service names `postgres` and `redis` instead of `localhost`. #### Setup From 552becbc8e82086831c28099f97e6bd5a0f297ea Mon Sep 17 00:00:00 2001 From: Lewis Nixon Date: Wed, 22 Jul 2026 20:19:47 +0100 Subject: [PATCH 4/7] Match --no-install-suggests flag with production Dockerfile .devcontainer/Dockerfile used --no-install-recommends while the root Dockerfile uses --no-install-suggests for the same package list, contradicting the comment that claims they match. Align the flag and note that the list should stay in sync with the root Dockerfile. --- .devcontainer/Dockerfile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 590a23198..ab41d1bc7 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,8 +1,9 @@ FROM node:22-slim -# Match the build tooling used by the production Dockerfile so native +# Match the build tooling used by the production Dockerfile (keep this +# list and the --no-install-suggests flag in sync with it) so native # dependencies (e.g. Prisma) compile correctly inside the Dev Container -RUN apt-get update && apt-get install -y --no-install-recommends \ +RUN apt-get update && apt-get install -y --no-install-suggests \ g++ \ git \ make \ From 18c3743b6b5646839fa1a40f9b3f081e5e2a8aad Mon Sep 17 00:00:00 2001 From: Lewis Nixon Date: Wed, 22 Jul 2026 20:19:57 +0100 Subject: [PATCH 5/7] Sync Dev Container prerequisites list with actual Dockerfile packages The docs listed g++, make, python3 as pre-installed tooling but omitted openssl and git, which .devcontainer/Dockerfile also installs. --- DEVELOPMENT.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index 7ec29f1c2..11182b64a 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -20,7 +20,7 @@ ### Dev Container -As an alternative to the manual _Setup_ above, [Visual Studio Code](https://code.visualstudio.com) users can develop inside a [Dev Container](https://containers.dev). It runs the application in a Docker container alongside [PostgreSQL](https://www.postgresql.org) and [Redis](https://redis.io), pre-installed with the required build tooling (Node.js 22, `g++`, `make`, `python3`). +As an alternative to the manual _Setup_ above, [Visual Studio Code](https://code.visualstudio.com) users can develop inside a [Dev Container](https://containers.dev). It runs the application in a Docker container alongside [PostgreSQL](https://www.postgresql.org) and [Redis](https://redis.io), pre-installed with the required build tooling (Node.js 22, `g++`, `git`, `make`, `openssl`, `python3`). #### Prerequisites From f5f05154a8b93ffeef4d611c95c5ea8d16184bba Mon Sep 17 00:00:00 2001 From: Lewis Nixon Date: Wed, 22 Jul 2026 21:11:41 +0100 Subject: [PATCH 6/7] Note that start:client's -o flag is a no-op in the Dev Container The script tries to auto-open a browser, which doesn't exist inside the container; document that the resulting failure is harmless rather than leaving contributors to wonder about it. --- DEVELOPMENT.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index 11182b64a..670856a47 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -40,7 +40,7 @@ As an alternative to the manual _Setup_ above, [Visual Studio Code](https://code 1. Open https://localhost:4200/en in your browser 1. Create a new user via _Get Started_ (this first user will get the role `ADMIN`) -**Info:** The client dev server binds to `localhost` by default, which is only reachable from within the container itself. Passing `--host 0.0.0.0` makes it listen on all interfaces so Visual Studio Code's forwarded port reaches it from your browser on the host. This is not required for the server, which already binds to `0.0.0.0` by default. +**Info:** The client dev server binds to `localhost` by default, which is only reachable from within the container itself. Passing `--host 0.0.0.0` makes it listen on all interfaces so Visual Studio Code's forwarded port reaches it from your browser on the host. This is not required for the server, which already binds to `0.0.0.0` by default. The `start:client` script also passes `-o` to open a browser automatically; since there is no browser inside the container, this will harmlessly fail and can be ignored. ### Start Server From 16b72c0e4450ba83afd0e5618a9ad35854bdd235 Mon Sep 17 00:00:00 2001 From: Lewis Nixon Date: Wed, 22 Jul 2026 21:24:07 +0100 Subject: [PATCH 7/7] Simplify .env.dev info note in DEVELOPMENT.md Trim the rationale so the note doesn't reference an implementation detail (NX_ADD_PLUGINS) that could drift out of sync if it changes. --- DEVELOPMENT.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index 670856a47..2e0fbbb60 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -28,7 +28,7 @@ As an alternative to the manual _Setup_ above, [Visual Studio Code](https://code - [Visual Studio Code](https://code.visualstudio.com) with the [Dev Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) extension - Copy the file `.env.dev` to `.env` and populate it with your data (`cp .env.dev .env`) -**Info:** Use `.env.dev`, not `.env.example`, as the base for `.env`, since it also sets `NX_ADD_PLUGINS=false` to keep _Nx_ behaving the same as in the manual _Setup_ above. Inside the Dev Container, the application and the databases run as separate containers on the same Docker network, so after copying, change `DATABASE_URL` and `REDIS_HOST` to point to the service names `postgres` and `redis` instead of `localhost`. +**Info:** Use `.env.dev`, not `.env.example`, as the base for `.env`. After copying, change `DATABASE_URL` and `REDIS_HOST` to point to the service names `postgres` and `redis` instead of `localhost`. #### Setup