diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..714cb76
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,5 @@
+FROM python:3.11-alpine
+
+RUN apk --no-cache add wireguard-tools-wg
+ADD announce.py /
+CMD ["python", "./announce.py"] 
diff --git a/README.md b/README.md
index cb1f57d..ba66a1a 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,8 @@
 # bambulab-wireguard-proxy
 
+```
+docker run --rm -it --network container:firezone-firezone-1 --cap-add NET_ADMIN python:3.11-alpine /bin/sh
+```
+
 Send SSDP announcements that imitate the Bambulab printer to each wireguard peer.
-This allows using OrcaSlicer via VPN
\ No newline at end of file
+This allows using OrcaSlicer via VPN
diff --git a/announce.py b/announce.py
new file mode 100755
index 0000000..1d06614
--- /dev/null
+++ b/announce.py
@@ -0,0 +1,36 @@
+#!/usr/bin/python3
+
+import socket
+import time
+import subprocess
+
+UDP_PORT = 2021
+MESSAGE = b"""NOTIFY * HTTP/1.1
+HOST: 239.255.255.250:1900
+Server: Buildroot/2018.02-rc3 UPnP/1.0 ssdpd/1.8
+Location: 10.73.37.29
+NT: urn:bambulab-com:device:3dprinter:1
+USN: 01S00C321501449
+Cache-Control: max-age=1800
+DevModel.bambu.com: C11
+DevName.bambu.com: Nerdberg Bambu P1P
+DevSignal.bambu.com: -41
+DevConnect.bambu.com: lan
+DevBind.bambu.com: free
+Devseclink.bambu.com: secure
+
+""".replace(b"\n", b"\r\n")
+
+while True:
+	for pl in subprocess.check_output(["wg", "show", "wg-firezone", "dump"]).decode().strip().split("\n")[1:]:
+		ips = pl.split("\t")[3]
+		for ip in ips.split(","):
+			if ip.endswith("/32"):
+				print(ip[:-3])
+				print(f"{ip}:{UDP_PORT} {MESSAGE=}" % MESSAGE)
+				sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
+				sock.bind(('0.0.0.0', 1900)) # 1900 is SSDP src port
+				sock.sendto(MESSAGE, (ip, UDP_PORT))
+				sock.close()
+	time.sleep(10)
+