diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile
new file mode 100644
index 0000000000..e83165a7af
--- /dev/null
+++ b/.devcontainer/Dockerfile
@@ -0,0 +1,2 @@
+ARG BASEIMAGE=mcr.microsoft.com/devcontainers/typescript-node:22
+FROM ${BASEIMAGE}
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
new file mode 100644
index 0000000000..b297f9a2d8
--- /dev/null
+++ b/.devcontainer/devcontainer.json
@@ -0,0 +1,20 @@
+{
+	"name": "Immich devcontainers",
+	"build": {
+		"dockerfile": "Dockerfile",
+		"args": {
+			"BASEIMAGE": "mcr.microsoft.com/devcontainers/typescript-node:22"
+		}
+	},
+	"customizations": {
+		"vscode": {
+			"extensions": [
+				"svelte.svelte-vscode"
+			]
+		}
+	},
+	"forwardPorts": [],
+	"postCreateCommand": "make install-all",
+	"remoteUser": "node"
+}
+
diff --git a/Makefile b/Makefile
index 2096cf86df..0899d82d24 100644
--- a/Makefile
+++ b/Makefile
@@ -39,7 +39,7 @@ attach-server:
 renovate:
   LOG_LEVEL=debug npx renovate --platform=local --repository-cache=reset
 
-MODULES = e2e server web cli sdk
+MODULES = e2e server web cli sdk docs
 
 audit-%:
 	npm --prefix $(subst sdk,open-api/typescript-sdk,$*) audit fix
@@ -48,11 +48,9 @@ install-%:
 build-cli: build-sdk
 build-web: build-sdk
 build-%: install-%
-	npm --prefix $(subst sdk,open-api/typescript-sdk,$*) run | grep 'build' >/dev/null \
-		&& npm --prefix $(subst sdk,open-api/typescript-sdk,$*) run build || true
+	npm --prefix $(subst sdk,open-api/typescript-sdk,$*) run build
 format-%:
-	npm --prefix $(subst sdk,open-api/typescript-sdk,$*) run | grep 'format:fix' >/dev/null \
-		&& npm --prefix $(subst sdk,open-api/typescript-sdk,$*) run format:fix || true
+	npm --prefix $* run format:fix
 lint-%:
 	npm --prefix $* run lint:fix
 check-%:
@@ -79,14 +77,14 @@ test-medium:
 test-medium-dev:
 	docker exec -it immich_server /bin/sh -c "npm run test:medium"
 
-build-all: $(foreach M,$(MODULES),build-$M) ;
+build-all: $(foreach M,$(filter-out e2e,$(MODULES)),build-$M) ;
 install-all: $(foreach M,$(MODULES),install-$M) ;
-check-all: $(foreach M,$(MODULES),check-$M) ;
-lint-all: $(foreach M,$(MODULES),lint-$M) ;
-format-all: $(foreach M,$(MODULES),format-$M) ;
+check-all: $(foreach M,$(filter-out sdk cli docs,$(MODULES)),check-$M) ;
+lint-all: $(foreach M,$(filter-out sdk docs,$(MODULES)),lint-$M) ;
+format-all: $(foreach M,$(filter-out sdk,$(MODULES)),format-$M) ;
 audit-all:  $(foreach M,$(MODULES),audit-$M) ;
 hygiene-all: lint-all format-all check-all sql audit-all;
-test-all: $(foreach M,$(MODULES),test-$M) ;
+test-all: $(foreach M,$(filter-out sdk docs,$(MODULES)),test-$M) ;
 
 clean:
 	find . -name "node_modules" -type d -prune -exec rm -rf '{}' +
diff --git a/docs/docs/developer/pr-checklist.md b/docs/docs/developer/pr-checklist.md
index d2e7fbee40..6015694976 100644
--- a/docs/docs/developer/pr-checklist.md
+++ b/docs/docs/developer/pr-checklist.md
@@ -1,5 +1,9 @@
 # PR Checklist
 
+A minimal devcontainer is supplied with this repository. All commands can be executed directly inside this container to avoid tedious installation of the environment.
+:::warning
+The provided devcontainer isn't complete at the moment. At least all dockerized steps in the Makefile won't work (`make dev`, ....). Feel free to contribute!
+:::
 When contributing code through a pull request, please check the following:
 
 ## Web Checks