diff --git a/roles/cleanuri/README.md b/roles/cleanuri/README.md
new file mode 100644
index 0000000..9ea7a75
--- /dev/null
+++ b/roles/cleanuri/README.md
@@ -0,0 +1,27 @@
+# ansible-role cleanuri
+
+> Set up the [cleanURI](https://github.com/penguineer/cleanURI) service.
+
+## Dependencies
+
+This role uses the [setup-http-site-proxy](../setup-http-site-proxy) role.
+
+## Use
+
+```yaml
+  roles:
+    - role: cleanuri
+      vars:
+        # Make sure to set up HTTPS ingress
+        cleanuri_ui_domain: …
+        cleanuri_ui_host_port: …
+        cleanuri_api_domain: …
+        cleanuri_api_host_port: …
+        # These values need to be set up in RabbitMQ
+        cleanuri_amqp_host: …
+        cleanuri_amqp_user: …
+        cleanuri_amqp_pass: …
+        cleanuri_amqp_vhost: …  # default "/"
+```
+
+Please check [defaults/main.yml](defaults/main.yml) for a complete list of variables.
diff --git a/roles/cleanuri/defaults/main.yml b/roles/cleanuri/defaults/main.yml
new file mode 100644
index 0000000..a8602f3
--- /dev/null
+++ b/roles/cleanuri/defaults/main.yml
@@ -0,0 +1,25 @@
+# Defaults for the cleanuri role
+---
+
+# HTTPS ingress
+# cleanuri_ui_domain:
+# cleanuri_ui_host_port:
+# cleanuri_api_domain:
+# cleanuri_api_host_port:
+
+# Credentials for RabbitMQ
+# cleanuri_amqp_host:
+# cleanuri_amqp_user:
+# cleanuri_amqp_pass:
+
+# Change these if they are different in your environment
+cleanuri_amqp_vhost: "/"
+cleanuri_amqp_results: "results"
+cleanuri_amqp_canonizer: "canonizer"
+cleanuri_amqp_retrieval: "extractor"
+
+# Docker images
+cleanuri_image_webui: mrtux/cleanuri-webui:0.1.1
+cleanuri_image_apigateway: mrtux/cleanuri-apigateway:0.3.0
+cleanuri_image_canonizer: mrtux/cleanuri-canonizer:0.3.0
+cleanuri_image_extractor: mrtux/cleanuri-extractor:0.3.0
diff --git a/roles/cleanuri/tasks/main.yml b/roles/cleanuri/tasks/main.yml
new file mode 100644
index 0000000..60c414e
--- /dev/null
+++ b/roles/cleanuri/tasks/main.yml
@@ -0,0 +1,79 @@
+# Tasks for the cleanuri role
+---
+- name: Ensure CleanURI WebUI is running
+  docker_container:
+    name: cleanuri-webui
+    image: "{{ cleanuri_image_webui }}"
+    pull: true
+    state: started
+    detach: yes
+    ports:
+      - "127.0.0.1:{{ cleanuri_ui_host_port }}:80"
+    restart_policy: unless-stopped
+    env:
+      REACT_APP_API_GATEWAY: "https://{{ cleanuri_api_domain }}"
+
+- name: Setup proxy site for the CleanURI WebUI
+  include_role:
+    name: setup-http-site-proxy
+  vars:
+    site_name: "{{ cleanuri_ui_domain }}"
+    proxy_port: "{{ cleanuri_ui_host_port }}"
+
+
+- name: Ensure CleanURI API Gateway is running
+  docker_container:
+    name: cleanuri-apigateway
+    image: "{{ cleanuri_image_apigateway }}"
+    pull: true
+    state: started
+    detach: yes
+    ports:
+      - "127.0.0.1:{{ cleanuri_api_host_port }}:8080"
+    restart_policy: unless-stopped
+    env:
+      AMQP_HOST: "{{ cleanuri_amqp_host }}"
+      AMQP_USER: "{{ cleanuri_amqp_user  }}"
+      AMQP_PASS: "{{ cleanuri_amqp_pass }}"
+      AMQP_VHOST: "{{ cleanuri_amqp_vhost }}"
+      GATEWAY_RESULT_QUEUE: "{{ cleanuri_amqp_results }}"
+      GATEWAY_TASK_RK: "{{ cleanuri_amqp_canonizer }}"
+
+- name: Ensure CleanURI Canonizer is running
+  docker_container:
+    name: cleanuri-canonizer
+    image: "{{ cleanuri_image_canonizer }}"
+    pull: true
+    state: started
+    detach: yes
+    restart_policy: unless-stopped
+    env:
+      AMQP_HOST: "{{ cleanuri_amqp_host }}"
+      AMQP_USER: "{{ cleanuri_amqp_user  }}"
+      AMQP_PASS: "{{ cleanuri_amqp_pass }}"
+      AMQP_VHOST: "{{ cleanuri_amqp_vhost }}"
+      CANONIZER_TASK_QUEUE: "{{ cleanuri_amqp_canonizer }}"
+      EXTRACTOR_TASK_RK: "{{ cleanuri_amqp_retrieval }}"
+
+- name: Ensure CleanURI Extractor is running
+  docker_container:
+    name: cleanuri-extractor
+    image: "{{ cleanuri_image_extractor }}"
+    pull: true
+    state: started
+    detach: yes
+    restart_policy: unless-stopped
+    env:
+      AMQP_HOST: "{{ cleanuri_amqp_host }}"
+      AMQP_USER: "{{ cleanuri_amqp_user  }}"
+      AMQP_PASS: "{{ cleanuri_amqp_pass }}"
+      AMQP_VHOST: "{{ cleanuri_amqp_vhost }}"
+      EXTRACTION_TASK_QUEUE: "{{ cleanuri_amqp_retrieval }}"
+
+
+- name: Setup proxy site the CleanURI API Gateway
+  include_role:
+    name: setup-http-site-proxy
+  vars:
+    site_name: "{{ cleanuri_api_domain }}"
+    proxy_port: "{{ cleanuri_api_host_port }}"