From c2e33e54c5592bc753de3f850805bd26aafa640b Mon Sep 17 00:00:00 2001 From: Dan Fabulich Date: Fri, 19 Jun 2026 13:59:12 -0700 Subject: [PATCH 1/5] Makefile: Remove `build` dependency from `dev-docker` targets Fixes #3098 --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 5f82cf54f..c05dda8b7 100644 --- a/Makefile +++ b/Makefile @@ -121,7 +121,7 @@ release: # Build local docker images for development. .PHONY: build-dev-docker -build-dev-docker: build ## Build docker containers for the entire suite (Front/Core/PG). +build-dev-docker: ## Build docker containers for the entire suite (Front/Core/PG). cd dev; \ docker compose build ; \ @@ -138,7 +138,7 @@ run-backend-docker: # Tear down the complete local development docker suite. .PHONY: rm-dev-docker -rm-dev-docker: build ## Delete the docker containers including DB volumes. +rm-dev-docker: ## Delete the docker containers including DB volumes. cd dev; \ docker compose down -v ; \ From 6b61486e9ff5d322c1f6a6b47339563f41cc0df1 Mon Sep 17 00:00:00 2001 From: Dan Fabulich Date: Fri, 19 Jun 2026 14:00:13 -0700 Subject: [PATCH 2/5] Upgrade to Node 24 (latest LTS version) Fixes #3099 --- dev/app.Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/app.Dockerfile b/dev/app.Dockerfile index 3afcc8c42..8f22a358b 100644 --- a/dev/app.Dockerfile +++ b/dev/app.Dockerfile @@ -1,6 +1,6 @@ FROM golang:1.24.1 AS go -FROM node:16 AS node +FROM node:24 AS node COPY --from=go /usr/local/go /usr/local/go ENV GOPATH /go From 947ff335820023efb5544e9504136922b1bbea46 Mon Sep 17 00:00:00 2001 From: Dan Fabulich Date: Fri, 19 Jun 2026 14:00:55 -0700 Subject: [PATCH 3/5] Fix forwarding Vite port 8080 for `dev-docker` environments Inside the frontend service, we're running `yarn dev` which runs `vite`, which binds to `http://localhost:8080`, but to forward the port from Docker, we need to run `vite --host` or `host: true` in Vite configuration, causing it to bind to `0.0.0.0:8080`, allowing Docker to forward the port to the host. Fixes #3100 --- dev/docker-compose.yml | 1 + frontend/.env.sample | 2 ++ frontend/vite.config.js | 1 + 3 files changed, 4 insertions(+) diff --git a/dev/docker-compose.yml b/dev/docker-compose.yml index 080c98d1a..919adf9aa 100644 --- a/dev/docker-compose.yml +++ b/dev/docker-compose.yml @@ -42,6 +42,7 @@ services: - "8080:8080" environment: - LISTMONK_API_URL=http://backend:9000 + - LISTMONK_VITE_HOST=true depends_on: - db volumes: diff --git a/frontend/.env.sample b/frontend/.env.sample index 367c37a82..91f253079 100644 --- a/frontend/.env.sample +++ b/frontend/.env.sample @@ -1,2 +1,4 @@ LISTMONK_FRONTEND_PORT=8080 LISTMONK_API_URL="http://127.0.0.1:9000" +# Bind Vite to 0.0.0.0 (required for Docker port publishing). Set by dev/docker-compose.yml. +# LISTMONK_VITE_HOST=true diff --git a/frontend/vite.config.js b/frontend/vite.config.js index 4a45f7e5c..f3e19a7cf 100644 --- a/frontend/vite.config.js +++ b/frontend/vite.config.js @@ -21,6 +21,7 @@ export default defineConfig(({ _, mode }) => { }, server: { port: env.LISTMONK_FRONTEND_PORT || 8080, + host: env.LISTMONK_VITE_HOST === 'true', proxy: { '^/$': { target: env.LISTMONK_API_URL || 'http://127.0.0.1:9000', From be5c82a1c0a615702aaac8cb6960062787e42fe3 Mon Sep 17 00:00:00 2001 From: Dan Fabulich Date: Fri, 19 Jun 2026 14:07:39 -0700 Subject: [PATCH 4/5] Initialize `dev-docker` automatically `init-dev-docker` ran `make dist && ./listmonk --install`, and was an explicit manual step that users would have to do to get the `dev-docker` environment up and running. For users of the `dev-docker` development environment, this commit simplifies setup; users just have to `make dev-docker` without having to remember to `make init-dev-docker`. But, more importantly, this fixes the broken `devcontainer.json`, which gave users no opportunity to `init-dev-docker` before it automatically tries to start the `backend` container. Now, `backend` depends on a new `init` container, which runs `make init-docker` and exits. `make init-docker` runs `make build-frontend` (we never needed a production `make dist` build for development), builds `listmonk`, and runs `./listmonk --install --idempotent`. On my machine, this imperceptibly slows down `dev-docker` startup, running `./listmonk --install --idempotent` before starting the `backend`. Fixes #3101 --- .devcontainer/devcontainer.json | 3 +-- Makefile | 11 +++++++++-- dev/docker-compose.yml | 20 +++++++++++++++++++- docs/docs/content/developer-setup.md | 3 +-- 4 files changed, 30 insertions(+), 7 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 26e4786a3..9d31c2c60 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -3,6 +3,5 @@ "dockerComposeFile": "../dev/docker-compose.yml", "service": "backend", "workspaceFolder": "/app", - "forwardPorts": [9000], - "postStartCommand": "make dist && ./listmonk --install --idempotent --yes --config dev/config.toml" + "forwardPorts": [9000] } diff --git a/Makefile b/Makefile index c05dda8b7..eedb439a5 100644 --- a/Makefile +++ b/Makefile @@ -136,6 +136,13 @@ dev-docker: build-dev-docker ## Build and spawns docker containers for the entir run-backend-docker: CGO_ENABLED=0 go run -ldflags="-s -w -X 'main.buildString=${BUILDSTR}' -X 'main.versionString=${VERSION}' -X 'main.frontendDir=frontend/dist'" ./cmd --config=dev/config.toml +# Build assets and install the DB schema for the docker dev suite. +.PHONY: init-docker +init-docker: + @test -d frontend/dist || $(MAKE) build-frontend + @test -f $(BIN) || $(MAKE) build + ./listmonk --install --idempotent --yes --config dev/config.toml + # Tear down the complete local development docker suite. .PHONY: rm-dev-docker rm-dev-docker: ## Delete the docker containers including DB volumes. @@ -144,6 +151,6 @@ rm-dev-docker: ## Delete the docker containers including DB volumes. # Setup the db for local dev docker suite. .PHONY: init-dev-docker -init-dev-docker: build-dev-docker ## Delete the docker containers including DB volumes. +init-dev-docker: build-dev-docker ## Build assets and install the DB schema in docker. cd dev; \ - docker compose run --rm backend sh -c "make dist && ./listmonk --install --idempotent --yes --config dev/config.toml" + docker compose run --rm init diff --git a/dev/docker-compose.yml b/dev/docker-compose.yml index 919adf9aa..522f24442 100644 --- a/dev/docker-compose.yml +++ b/dev/docker-compose.yml @@ -33,6 +33,21 @@ services: source: listmonk-dev-db target: /var/lib/postgresql/data + init: + build: + context: ../ + dockerfile: dev/app.Dockerfile + command: ["make", "init-docker"] + depends_on: + db: + condition: service_started + volumes: + - ../:/app + - ${GOPATH:-${HOME}/go}/pkg/mod/cache:/go/pkg/mod/cache + networks: + - listmonk-dev + restart: "no" + front: build: context: ../ @@ -58,7 +73,10 @@ services: ports: - "9000:9000" depends_on: - - db + db: + condition: service_started + init: + condition: service_completed_successfully volumes: - ../:/app - ${GOPATH:-${HOME}/go}/pkg/mod/cache:/go/pkg/mod/cache diff --git a/docs/docs/content/developer-setup.md b/docs/docs/content/developer-setup.md index 58137329c..0de551367 100644 --- a/docs/docs/content/developer-setup.md +++ b/docs/docs/content/developer-setup.md @@ -30,8 +30,7 @@ After setting up the dev environment, you can visit `http://localhost:8080`. 2. Inside containers (Using Makefile) - - Run `make init-dev-docker` to setup container for db. - - Run `make dev-docker` to setup docker container suite. + - Run `make dev-docker` to build and start the docker container suite. - Run `make rm-dev-docker` to clean up docker container suite. 3. Inside containers (Using devcontainer) From 2f83c87e385058b53b9b0c23e99005b417d2d770 Mon Sep 17 00:00:00 2001 From: Dan Fabulich Date: Fri, 19 Jun 2026 15:40:35 -0700 Subject: [PATCH 5/5] Run the devcontainer in its own container Fixes #3104 --- .devcontainer/devcontainer.json | 7 +++++-- Makefile | 5 ++++- dev/docker-compose.yml | 18 ++++++++++++++++++ 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 9d31c2c60..37ea98417 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,7 +1,10 @@ { "name": "listmonk", "dockerComposeFile": "../dev/docker-compose.yml", - "service": "backend", + "service": "devcontainer", "workspaceFolder": "/app", - "forwardPorts": [9000] + "runServices": ["adminer", "mailhog", "db", "backend", "front"], + "features": { + "ghcr.io/devcontainers/features/docker-outside-of-docker:1": {} + } } diff --git a/Makefile b/Makefile index eedb439a5..e2a5684e4 100644 --- a/Makefile +++ b/Makefile @@ -119,6 +119,9 @@ release-dry: release: goreleaser release --parallelism 1 --clean +# App services for `make dev-docker` (excludes the devcontainer workspace). +DEV_DOCKER_SERVICES = adminer mailhog db backend front + # Build local docker images for development. .PHONY: build-dev-docker build-dev-docker: ## Build docker containers for the entire suite (Front/Core/PG). @@ -129,7 +132,7 @@ build-dev-docker: ## Build docker containers for the entire suite (Front/Core/PG .PHONY: dev-docker dev-docker: build-dev-docker ## Build and spawns docker containers for the entire suite (Front/Core/PG). cd dev; \ - docker compose up + docker compose up $(DEV_DOCKER_SERVICES) # Run the backend in docker-dev mode. The frontend assets in dev mode are loaded from disk from frontend/dist. .PHONY: run-backend-docker diff --git a/dev/docker-compose.yml b/dev/docker-compose.yml index 522f24442..c5f0b696a 100644 --- a/dev/docker-compose.yml +++ b/dev/docker-compose.yml @@ -83,6 +83,24 @@ services: networks: - listmonk-dev + # Workspace container for VS Code / Cursor devcontainers. Omitted from + # `make dev-docker`; the editor starts this service when reopening in container. + devcontainer: + image: dev-devcontainer + build: + context: ../ + dockerfile: dev/app.Dockerfile + command: ["sleep", "infinity"] + volumes: + - ../:/app + - ${GOPATH:-${HOME}/go}/pkg/mod/cache:/go/pkg/mod/cache + - /var/run/docker.sock:/var/run/docker.sock + depends_on: + db: + condition: service_started + networks: + - listmonk-dev + volumes: listmonk-dev-db: