diff --git a/playbooks/roles/deploy/files/deploy-reitanlage_oranienburg b/playbooks/roles/deploy/files/deploy-reitanlage_oranienburg
new file mode 100755
index 0000000..ccaddf3
--- /dev/null
+++ b/playbooks/roles/deploy/files/deploy-reitanlage_oranienburg
@@ -0,0 +1,6 @@
+#!/usr/bin/env sh
+
+if [ -n "$WEBHOOK_DATA" ]
+then
+  docker exec -i reitanlage_oranienburg-app-1 sh < "$WEBHOOK_DATA"
+fi
diff --git a/playbooks/roles/deploy/tasks/main.yml b/playbooks/roles/deploy/tasks/main.yml
new file mode 100644
index 0000000..d906df3
--- /dev/null
+++ b/playbooks/roles/deploy/tasks/main.yml
@@ -0,0 +1,37 @@
+---
+- name: Set common facts
+  ansible.builtin.import_tasks: tasks/set-default-facts.yml
+
+- name: Deploy {{ role_name }}
+  vars:
+    svc: "{{ deploy_svc }}"
+    yml: "{{ deploy_yml }}"
+    compose: "{{ deploy_compose }}"
+  block:
+    - name: Import prepare tasks for common service
+      ansible.builtin.import_tasks: tasks/prepare-common-service.yml
+
+    - name: Set webhook config path
+      ansible.builtin.set_fact:
+        config_path: "{{ (service_path, 'config') | path_join }}"
+
+    - name: Create config directory
+      ansible.builtin.file:
+        path: "{{ config_path }}"
+        state: directory
+        mode: "0755"
+
+    - name: Template main config
+      ansible.builtin.template:
+        src: yml.j2
+        dest: "{{ (config_path, 'hooks.yml') | path_join }}"
+        mode: "0644"
+
+    - name: Copy the deploy-reitanlage_oranienburg script
+      ansible.builtin.copy:
+        src: deploy-reitanlage_oranienburg
+        dest: "{{ (config_path, 'deploy-reitanlage_oranienburg') | path_join }}"
+        mode: "0755"
+
+    - name: Import start tasks for common service
+      ansible.builtin.import_tasks: tasks/start-common-service.yml
diff --git a/playbooks/roles/deploy/vars/main.yml b/playbooks/roles/deploy/vars/main.yml
new file mode 100644
index 0000000..c1ac4bd
--- /dev/null
+++ b/playbooks/roles/deploy/vars/main.yml
@@ -0,0 +1,33 @@
+---
+deploy_svc:
+  domain: "{{ all_services | service_get_domain(role_name) }}"
+  port: 9000
+
+deploy_yml:
+  - id: deploy-reitanlage_oranienburg
+    trigger-rule-mismatch-http-response-code: 400
+    execute-command: /config/deploy-reitanlage_oranienburg
+    pass-file-to-command:
+      - source: payload
+        name: data
+        envname: WEBHOOK_DATA
+        base64decode: true
+    trigger-rule:
+      and:
+        - match:
+            type: value
+            value: "{{ vault_deploy.reitanlage_oranienburg_token }}"
+            parameter:
+              source: header
+              name: X-Webhook-Token
+
+deploy_compose:
+  watchtower: update
+  image: lwlook/webhook
+  volumes:
+    - ./config:/config:ro
+    - /var/run/docker.sock:/var/run/docker.sock
+  file:
+    services:
+      app:
+        command: ["-verbose", "-hooks=/config/hooks.yml", "-hotreload"]
\ No newline at end of file
diff --git a/scripts/visualize.py b/scripts/visualize.py
index c6c382b..dacec8f 100755
--- a/scripts/visualize.py
+++ b/scripts/visualize.py
@@ -9,6 +9,7 @@ import hcl2
 icon_overrides = {
     "acme_dns": "lets-encrypt",
     "backup": "restic",
+    "deploy": "webhook",
     "extra_services": None,
     "forgejo_runner": "forgejo",
     "healthcheck": "healthchecks",
diff --git a/services.auto.tfvars b/services.auto.tfvars
index 205ee8f..409ce14 100644
--- a/services.auto.tfvars
+++ b/services.auto.tfvars
@@ -99,6 +99,21 @@ services = {
     s3 = false
   },
 
+  "deploy" = {
+    host = "node001"
+    dns = [
+      {
+        domain = "deploy.serguzim.me"
+      },
+    ]
+    monitoring = {
+      group = "7-support"
+    }
+    auth = false
+    database = false
+    s3 = false
+  }
+
   "dokku" = {
     host = "node001"
     dns = [