diff --git a/README.md b/README.md
index b0982f5408..f49d037bee 100644
--- a/README.md
+++ b/README.md
@@ -109,6 +109,34 @@ Zigbee2MQTT uses TypeScript (partially for now). Therefore after making changes
 Before running any of the commands, you'll first need to run `pnpm install --include=dev`.
 Before submitting changes run `pnpm run test:coverage`, `pnpm run pretty:check` and `pnpm run eslint`
 
+#### Developing in docker
+
+You can use the development container with the corresponding `compose.dev.yml` to quickly spin up your development environment.
+
+Before starting you need to run `docker compose -f docker/compose.dev.yml run zigbee2mqtt pnpm install --include=dev` to get the node_modules.
+
+Also make sure to create your `configuration.yaml` under `data/configuration.yaml`
+
+Then run `docker compose -f docker/compose.dev.yml up -d` from the repository-root to start zigbee2mqtt, it will then be accessible from `http://localhost:8080`.
+
+Any commands can be prefixed with `docker compose -f docker/compose.dev.yml run zigbee2mqtt` to automatically run inside the container. For example to run the prettier linter:
+
+```shell
+docker compose -f docker/compose.dev.yml run zigbee2mqtt pnpm pretty:write
+```
+
+##### To add adapter
+
+Open and edit the `compose.dev.yml` and input your device to map.
+
+```yaml
+services:
+    zigbee2mqtt:
+        # Other fields not shown
+        devices:
+            - /dev/serial/by-id/usb-ZEPHYR_Zigbee_NCP_DEADBEEF0000-if0:/dev/ttyACM0 # Note that you need to add /dev/ttyACM0 to config
+```
+
 ## Supported devices
 
 See [Supported devices](https://www.zigbee2mqtt.io/supported-devices) to check whether your device is supported. There is quite an extensive list, including devices from vendors like [Xiaomi](https://www.zigbee2mqtt.io/supported-devices/#v=Xiaomi), [Ikea](https://www.zigbee2mqtt.io/supported-devices/#v=IKEA), [Philips](https://www.zigbee2mqtt.io/supported-devices/#v=Philips), [OSRAM](https://www.zigbee2mqtt.io/supported-devices/#v=OSRAM) and more.
diff --git a/docker/Dockerfile.dev b/docker/Dockerfile.dev
new file mode 100644
index 0000000000..7b7e9f5ccf
--- /dev/null
+++ b/docker/Dockerfile.dev
@@ -0,0 +1,33 @@
+ARG TARGETPLATFORM
+
+# Need to use Alpine 3.18.4 which uses Node 18 for arm/v6 and arm/v7, otherwise the build hangs.
+# See https://github.com/nodejs/docker-node/issues/2077
+FROM alpine:3.18.4 AS linux-arm-alpine
+FROM alpine:3.21 AS linux-arm64-alpine
+FROM alpine:3.21 AS linux-amd64-alpine
+FROM alpine:3.21 AS linux-riscv64-alpine
+FROM alpine:3.21 AS linux-386-alpine
+
+FROM linux-${TARGETARCH}-alpine AS base
+
+#ENV NODE_ENV=production
+WORKDIR /app
+RUN apk add --no-cache tzdata eudev tini nodejs
+
+# Dependencies and build
+
+COPY package.json pnpm-lock.yaml ./
+# Make and such are needed to compile serialport for riscv64
+RUN apk add make gcc g++ python3 linux-headers npm git && \
+    npm install -g pnpm@10.4.1 && \
+    pnpm install --include=dev && \
+    # serialport has outdated prebuilds that appear to fail on some archs, force build on target platform
+    rm -rf `find ./node_modules/.pnpm/ -wholename "*/@serialport/bindings-cpp/prebuilds" -type d` && \
+    pnpm rebuild @serialport/bindings-cpp
+
+COPY docker/docker-entrypoint.sh /usr/local/bin/
+RUN chmod +x /usr/local/bin/docker-entrypoint.sh
+
+COPY . /app
+RUN pnpm build
+CMD pnpm start
diff --git a/docker/compose.dev.yml b/docker/compose.dev.yml
new file mode 100644
index 0000000000..e3d37fc17f
--- /dev/null
+++ b/docker/compose.dev.yml
@@ -0,0 +1,15 @@
+services:
+    zigbee2mqtt:
+        build:
+            context: ../
+            dockerfile: docker/Dockerfile.dev
+        volumes:
+            - ../:/app
+        #    devices:
+        #      - /dev/serial/by-id/<YOUR-DEVICE-ID>:/dev/ttyACM0
+        ports:
+            - 127.0.0.1:8080:8080
+    mqtt:
+        image: eclipse-mosquitto:2.0
+        container_name: mqtt
+        command: 'mosquitto -c /mosquitto-no-auth.conf'