diff --git a/roles/archmanweb/defaults/main.yml b/roles/archmanweb/defaults/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..7f3e0e2814d49cbed975faab31c5a15ec9872942
--- /dev/null
+++ b/roles/archmanweb/defaults/main.yml
@@ -0,0 +1,15 @@
+---
+archmanweb_dir: '/srv/http/archmanweb'
+archmanweb_cache_dir: '{{ archmanweb_dir }}/cache'
+archmanweb_domain: 'man.archlinux.org'
+archmanweb_allowed_hosts: ["{{ archmanweb_domain }}"]
+archmanweb_nginx_conf: '/etc/nginx/nginx.d/archmanweb.conf'
+archmanweb_repository: 'https://github.com/lahwaacz/archmanweb.git'
+archmanweb_version: deployment
+archmanweb_django_settings_module: production.settings
+#archmanweb_pgp_key: ['932BA3FA0C86812A32D1F54DAB5964AEB9FEDDDC']   # Jakub Klinkovský (lahwaacz)
+archmanweb_forced_deploy: false
+
+archmanweb_db: 'archmanweb'
+archmanweb_db_host: 'localhost'
+archmanweb_db_user: 'archmanweb'
diff --git a/roles/archmanweb/tasks/main.yml b/roles/archmanweb/tasks/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..9d4029e89ccce2bd91d11f05049a579d1e011129
--- /dev/null
+++ b/roles/archmanweb/tasks/main.yml
@@ -0,0 +1,89 @@
+---
+
+- name: install required packages
+  pacman:
+    state: present
+    name:
+      - git
+      - mandoc
+      - pyalpm
+      - python-chardet
+      - python-django
+      - python-psycopg2
+      - python-requests
+      - python-xtarfile
+      - uwsgi-plugin-python
+
+- name: make archmanweb user
+  user: name=archmanweb shell=/bin/false home="{{ archmanweb_dir }}"
+
+- name: fix home permissions
+  file: state=directory owner=archmanweb group=archmanweb mode=0755 path="{{ archmanweb_dir }}"
+
+- name: set archmanweb groups
+  user: name=archmanweb groups=uwsgi
+
+- name: set up nginx
+  template: src=nginx.d.conf.j2 dest="{{ archmanweb_nginx_conf }}" owner=root group=root mode=644
+  notify: reload nginx
+  tags: ['nginx']
+
+- name: make nginx log dir
+  file: path=/var/log/nginx/{{ archmanweb_domain }} state=directory owner=root group=root mode=0755
+
+- name: clone archmanweb repo
+  git: >
+    repo={{ archmanweb_repository }}
+    dest="{{ archmanweb_dir }}/repo"
+    version={{ archmanweb_version }}
+# TODO
+#    verify_commit=true
+#    gpg_whitelist={{ archmanweb_pgp_key }}
+  become: true
+  become_user: archmanweb
+  register: release
+
+- name: configure archmanweb
+  template: src=local_settings.py.j2 dest={{ archmanweb_dir }}/repo/production/local_settings.py owner=archmanweb group=archmanweb mode=0660
+  register: config
+  no_log: true
+
+- name: create archmanweb db user
+  postgresql_user: name={{ archmanweb_db_user }} password={{ vault_archmanweb_db_password }} login_host="{{ archmanweb_db_host }}" login_password="{{ vault_postgres_users.postgres }}" encrypted=yes
+  no_log: true
+
+- name: create archmanweb db
+  postgresql_db: name="{{ archmanweb_db }}" login_host="{{ archmanweb_db_host }}" login_password="{{ vault_postgres_users.postgres }}" owner="{{ archmanweb_db_user }}"
+  register: db_created
+
+- name: add pg_trgm extension to the archmanweb db
+  postgresql_ext: name="pg_trgm" db="{{ archmanweb_db }}" login_host="{{ archmanweb_db_host }}" login_password="{{ vault_postgres_users.postgres }}"
+  when: db_created.changed or archmanweb_forced_deploy
+
+- name: run Django management tasks
+  django_manage: app_path="{{ archmanweb_dir }}/repo" command="{{ item }}"
+  with_items:
+    - migrate
+    - collectstatic
+    - man_drop_cache
+  environment:
+    DJANGO_SETTINGS_MODULE: "{{ archmanweb_django_settings_module }}"
+  become: true
+  become_user: archmanweb
+  when: db_created.changed or release.changed or config.changed or archmanweb_forced_deploy
+
+- name: configure UWSGI for archmanweb
+  template: src=archmanweb.ini.j2 dest=/etc/uwsgi/vassals/archmanweb.ini owner=archmanweb group=http mode=0640
+
+- name: deploy new release
+  file: path=/etc/uwsgi/vassals/archmanweb.ini state=touch owner=archmanweb group=http mode=0640
+  when: release.changed or config.changed or archmanweb_forced_deploy
+
+- name: install systemd units
+  template: src="{{ item }}.j2" dest="/etc/systemd/system/{{ item }}" owner=root group=root mode=0644
+  with_items:
+    - archmanweb_update.service
+    - archmanweb_update.timer
+
+- name: start and enable archmanweb update timer
+  systemd: name="archmanweb_update.timer" enabled=yes state=started daemon_reload=yes
diff --git a/roles/archmanweb/templates/archmanweb.ini.j2 b/roles/archmanweb/templates/archmanweb.ini.j2
new file mode 100644
index 0000000000000000000000000000000000000000..29e95a3adae16a15d448e394f245c1dc8f27b79f
--- /dev/null
+++ b/roles/archmanweb/templates/archmanweb.ini.j2
@@ -0,0 +1,15 @@
+[uwsgi]
+plugins = python
+chdir = {{ archmanweb_dir }}/repo
+env = DJANGO_SETTINGS_MODULE={{ archmanweb_django_settings_module }}
+module = wsgi:application
+socket = /run/uwsgi/archmanweb.sock
+chmod-socket = 660
+processes = 4
+threads = 1
+master = true
+uid = archmanweb
+gid = http
+thunder-lock = true
+daemonize = /var/log/uwsgi/archmanweb.log
+stats = /run/uwsgi/archmanweb-stats.sock
diff --git a/roles/archmanweb/templates/archmanweb_update.service.j2 b/roles/archmanweb/templates/archmanweb_update.service.j2
new file mode 100644
index 0000000000000000000000000000000000000000..94ff1b921662a2970be91013ed5c5f91f1001d52
--- /dev/null
+++ b/roles/archmanweb/templates/archmanweb_update.service.j2
@@ -0,0 +1,23 @@
+[Unit]
+Description=Update archmanweb database
+
+[Service]
+Type=oneshot
+User=archmanweb
+WorkingDirectory={{ archmanweb_dir }}/repo/
+Environment=DJANGO_SETTINGS_MODULE="{{ archmanweb_django_settings_module }}"
+ExecStart=/usr/bin/python3 manage.py man_update --cache-dir {{ archmanweb_cache_dir }}
+
+ProtectSystem=full
+PrivateTmp=true
+PrivateDevices=true
+
+ProtectHostname=true
+ProtectKernelTunables=true
+ProtectKernelModules=true
+ProtectKernelLogs=true
+ProtectControlGroups=true
+
+NoNewPrivileges=true
+RestrictRealtime=true
+MemoryDenyWriteExecute=true
diff --git a/roles/archmanweb/templates/archmanweb_update.timer.j2 b/roles/archmanweb/templates/archmanweb_update.timer.j2
new file mode 100644
index 0000000000000000000000000000000000000000..3aa8001300893bd98f89730ecedd52ffba1fff18
--- /dev/null
+++ b/roles/archmanweb/templates/archmanweb_update.timer.j2
@@ -0,0 +1,10 @@
+[Unit]
+Description=Timer for the archmanweb update
+
+[Timer]
+OnCalendar=daily
+Persistent=true
+RandomizedDelaySec=1h
+
+[Install]
+WantedBy=timers.target
diff --git a/roles/archmanweb/templates/local_settings.py.j2 b/roles/archmanweb/templates/local_settings.py.j2
new file mode 100644
index 0000000000000000000000000000000000000000..2513be3f9bd4ac30d9911e03b83b487d0584b9b3
--- /dev/null
+++ b/roles/archmanweb/templates/local_settings.py.j2
@@ -0,0 +1,26 @@
+DEBUG = False
+
+# Make this unique, and don't share it with anybody.
+SECRET_KEY = '{{ vault_archmanweb_secret_key }}'
+
+# Hostnames we allow this site to be served under
+ALLOWED_HOSTS = [{% for host in archmanweb_allowed_hosts %}'{{ host }}', {% endfor -%}]
+
+DATABASES = {
+    'default': {
+        'ENGINE'  : 'django.db.backends.postgresql_psycopg2',
+        'PORT'    : 5432,
+{% if archmanweb_db_host != 'localhost' %}
+        'HOST'    : '{{ archmanweb_db_host }}',
+{% endif %}
+        'NAME'    : '{{ archmanweb_db }}',
+        'USER'    : '{{ archmanweb_db_user }}',
+        'PASSWORD': '{{ vault_archmanweb_db_password }}',
+        'OPTIONS' : {
+            'application_name': 'archmanweb',
+{% if archmanweb_db_host != 'localhost' %}
+            'sslmode': 'require',
+{% endif %}
+        }
+    },
+}
diff --git a/roles/archmanweb/templates/nginx.d.conf.j2 b/roles/archmanweb/templates/nginx.d.conf.j2
new file mode 100644
index 0000000000000000000000000000000000000000..f373771e6fa039474422518bae982b83c486f911
--- /dev/null
+++ b/roles/archmanweb/templates/nginx.d.conf.j2
@@ -0,0 +1,50 @@
+upstream archmanweb {
+    server unix:///run/uwsgi/archmanweb.sock;
+}
+
+server {
+    listen       80;
+    listen       [::]:80;
+    server_name  {{ archmanweb_domain }};
+
+    access_log   /var/log/nginx/{{ archmanweb_domain }}/access.log reduced;
+    error_log    /var/log/nginx/{{ archmanweb_domain }}/error.log;
+
+    include snippets/letsencrypt.conf;
+
+    location / {
+        access_log off;
+        return 301 https://$server_name$request_uri;
+    }
+}
+
+server {
+    listen       443 ssl http2;
+    listen       [::]:443 ssl http2;
+    server_name  {{ archmanweb_domain }};
+
+    access_log   /var/log/nginx/{{ archmanweb_domain }}/access.log reduced;
+    error_log    /var/log/nginx/{{ archmanweb_domain }}/error.log;
+
+    ssl_certificate      /etc/letsencrypt/live/{{ archmanweb_domain }}/fullchain.pem;
+    ssl_certificate_key  /etc/letsencrypt/live/{{ archmanweb_domain }}/privkey.pem;
+    ssl_trusted_certificate /etc/letsencrypt/live/{{ archmanweb_domain }}/chain.pem;
+
+    location /favicon.ico {
+        alias {{ archmanweb_dir }}/repo/collected_static/favicon.ico;
+    }
+
+    # Client-cache for Django's static assets
+    location /static {
+        expires 30d;
+        add_header Pragma public;
+        add_header Cache-Control "public";
+        alias {{ archmanweb_dir }}/repo/collected_static;
+    }
+
+    location / {
+        access_log   /var/log/nginx/{{ archmanweb_domain }}/access.log main;
+        include uwsgi_params;
+        uwsgi_pass archmanweb;
+    }
+}