diff --git a/.gitlab/issue_templates/release.md b/.gitlab/issue_templates/release.md
index 6048a94007445134c18d82ae9aff65cc579c0605..db25c145f1c5e2326983aa41bbbdb6aa1022253b 100644
--- a/.gitlab/issue_templates/release.md
+++ b/.gitlab/issue_templates/release.md
@@ -11,3 +11,4 @@
 * [ ] commit (signed)
 * [ ] create signed tag (`git tag -s 0.2.0 -m 'Release 0.2.0'`)
 * [ ] Push to MR, including tag
+* [ ] Log into readthedocs.org and update documentation for tagged versions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0c4e0fe130510dbcdb1f887afb8cab4196392710..a5a13ec7c4f9398bc6b2978314d35df553914770 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,8 +1,15 @@
 # Changelog
 
-## [Unreleased]
+## [0.3.1] - 2020-03-18
 
-No unreleased changes yet.
+* Repair rocket chat installation
+* Rocket Chat supports e2e encryption by default
+* Upgrade Nextcloud chart version
+* Single Sign-on related Jobs are now cleaned up after a successful installation
+
+Known issues:
+
+* Same as 0.3.0
 
 ## [0.3.0] - 2020-01-20
 
diff --git a/VERSION b/VERSION
index 0d91a54c7d439e84e3dd17d3594f1b2b6737f430..9e11b32fcaa96816319e5d0dcff9fb2873f04061 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.3.0
+0.3.1
diff --git a/ansible/roles/apps/files/local-storage.yaml b/ansible/roles/apps/files/local-storage.yaml
new file mode 120000
index 0000000000000000000000000000000000000000..06a8699c2591e1738d4108d7aef02f45bca97e5d
--- /dev/null
+++ b/ansible/roles/apps/files/local-storage.yaml
@@ -0,0 +1 @@
+../../../../flux/local-storage.yaml
\ No newline at end of file
diff --git a/ansible/roles/apps/tasks/flux.yml b/ansible/roles/apps/tasks/flux.yml
index 4138fc5aec1743429496d7733c8ad729e2d2f9b7..7419bab0ab71b625ce3f41bbb8ef60273e260d94 100644
--- a/ansible/roles/apps/tasks/flux.yml
+++ b/ansible/roles/apps/tasks/flux.yml
@@ -1,5 +1,51 @@
 ---
+- name: Install helm-operator
+  tags:
+    - flux
+  # Commented version of below shell command:
+  # helm upgrade
+  #   # Install a new release if it doesn't yet exist.
+  #   --install
+  #   --repo "https://charts.fluxcd.io"
+  #   --namespace oas
+  #   --version 0.3.0
+  #   --set createCRD=true
+  #   # Reconcile actual helm releases with HelmRelease objects with this
+  #   # interval.
+  #   --set chartsSyncInterval=20m
+  #   # Update HelmRelease objects' status with this interval.
+  #   --set statusUpdateInterval=30s
+  #   # Helm release name
+  #   helm-operator
+  #   # Chart name
+  #   helm-operator
+  shell: helm upgrade --install --repo "https://charts.fluxcd.io" --namespace oas --version 0.3.0 --set createCRD=true --set chartsSyncInterval=20m --set statusUpdateInterval=30s helm-operator helm-operator
 
+- name: Create Kubernetes secret with local-storage settings
+  tags:
+    - config
+    - flux
+    - local-storage
+  vars:
+    flux:
+      name: "local-storage-settings"
+      namespace: "oas"
+  include_tasks:
+    file: flux_secret.yml
+    apply:
+      tags:
+        - config
+        - flux
+        - local-storage
+
+- name: Create local-storage HelmResource
+  tags:
+    - config
+    - flux
+    - local-storage
+  k8s:
+    state: present
+    resource_definition: "{{ lookup('file', 'local-storage.yaml') | from_yaml }}"
 
 - name: Install flux
   tags:
@@ -40,28 +86,6 @@
   #   flux
   shell: helm upgrade --install --repo "https://charts.fluxcd.io" --namespace oas --version 0.16.0 --set git.url="{{ git_url }}" --set git.branch="{{ git_branch }}" --set git.path="{{ git_path }}" --set git.readonly=true --set registry.excludeImage='*' --set sync.state="secret" --set syncGarbageCollection.enabled=true --set git.pollInterval=1h flux flux
 
-- name: Install helm-operator
-  tags:
-    - flux
-  # Commented version of below shell command:
-  # helm upgrade
-  #   # Install a new release if it doesn't yet exist.
-  #   --install
-  #   --repo "https://charts.fluxcd.io"
-  #   --namespace oas
-  #   --version 0.3.0
-  #   --set createCRD=true
-  #   # Reconcile actual helm releases with HelmRelease objects with this
-  #   # interval.
-  #   --set chartsSyncInterval=20m
-  #   # Update HelmRelease objects' status with this interval.
-  #   --set statusUpdateInterval=30s
-  #   # Helm release name
-  #   helm-operator
-  #   # Chart name
-  #   helm-operator
-  shell: helm upgrade --install --repo "https://charts.fluxcd.io" --namespace oas --version 0.3.0 --set createCRD=true --set chartsSyncInterval=20m --set statusUpdateInterval=30s helm-operator helm-operator
-
 - name: Install fluxctl via snap
   tags:
     - flux
diff --git a/ansible/roles/apps/tasks/local-storage.yml b/ansible/roles/apps/tasks/local-storage.yml
deleted file mode 100644
index 22e9c132505d781c73ca56e5bc273f22e111a090..0000000000000000000000000000000000000000
--- a/ansible/roles/apps/tasks/local-storage.yml
+++ /dev/null
@@ -1,17 +0,0 @@
----
-- name: Create Kubernetes secret with local-storage settings
-  tags:
-    - config
-    - flux
-    - local-storage
-  vars:
-    flux:
-      name: "local-storage-settings"
-      namespace: "oas"
-  include_tasks:
-    file: flux_secret.yml
-    apply:
-      tags:
-        - config
-        - flux
-        - local-storage
diff --git a/ansible/roles/apps/tasks/main.yml b/ansible/roles/apps/tasks/main.yml
index 8e43e01e196ca08e9aff0ce766acd42ac6a2dbde..814454ecccd35fc1501431b31ea5b8ba42e02302 100644
--- a/ansible/roles/apps/tasks/main.yml
+++ b/ansible/roles/apps/tasks/main.yml
@@ -1,11 +1,8 @@
 ---
 
-- name: Install flux
+- name: Install helm operator, local-storage and flux
   import_tasks: flux.yml
 
-- name: Perform tasks necessary for local-storage
-  import_tasks: local-storage.yml
-
 - name: Tasks pertaining to cert-manager
   import_tasks: cert-manager.yml
 
diff --git a/ansible/roles/apps/templates/rocketchat-settings.yaml b/ansible/roles/apps/templates/rocketchat-settings.yaml
index 406a004e7181856abd4be2b3ed848db900bfbf23..6b82c6090e2e557ed0dceb3e7f8b388e4921fc63 100644
--- a/ansible/roles/apps/templates/rocketchat-settings.yaml
+++ b/ansible/roles/apps/templates/rocketchat-settings.yaml
@@ -14,6 +14,8 @@ extraEnv: |
     # create a different admin user, gets skipped.
   - name: OVERWRITE_SETTING_Show_Setup_Wizard
     value: completed
+  - name: E2E_Enable
+    value: "true"
 
 livenessProbe:
   initialDelaySeconds: 180
diff --git a/ansible/roles/apps/templates/wordpress-settings.yaml b/ansible/roles/apps/templates/wordpress-settings.yaml
index a7d39822cf69134fe3dcc794e26e3fa3e103e197..2b28d66ce53f7f8f6d1941f78bbb10647018e858 100644
--- a/ansible/roles/apps/templates/wordpress-settings.yaml
+++ b/ansible/roles/apps/templates/wordpress-settings.yaml
@@ -1,7 +1,7 @@
 image:
-  tag: 34-add-openid-connect-plugin-and-configuration
+  tag: master
 initImage:
-  tag: 34-add-openid-connect-plugin-and-configuration
+  tag: master
 
 wordpress:
   config:
@@ -12,8 +12,6 @@ wordpress:
       pssw: "{{ wordpress_admin_password }}"
   site:
     alt_path: openappstack-login
-    # NOTE: Use a theme *slug* here
-    theme: twentynineteen
     # NOTE: Make sure you use underscore and that the localisation is in full caps
     locale: en_US
     version: 5.3.2
@@ -37,6 +35,8 @@ openid_connect_settings:
   http_request_timeout: "15"
   enable_logging: "1"
   scope: email profile openid openappstack_roles offline_access
+  role_mapping_enabled: true
+  role_key: openappstack_roles
 
 database:
   db:
diff --git a/docs/installation_instructions.md b/docs/installation_instructions.md
index dc975734e9173f5c31a3aa6efecd7933da97346a..6f826ed2ef53be1ece2d0764ddf3d4fc6fa9e3cb 100644
--- a/docs/installation_instructions.md
+++ b/docs/installation_instructions.md
@@ -57,9 +57,9 @@ guide][https://openappstack.net/contact.html).
 ## Getting the installation script
 
 On your **provisioning machine**, clone the OpenAppStack git repository and
-checkout the latest tagged version (currently `0.3.0`):
+checkout the latest tagged version (currently `0.3.1`):
 
-    $ git clone -b 0.3.0 https://open.greenhost.net/openappstack/openappstack.git
+    $ git clone -b 0.3.1 https://open.greenhost.net/openappstack/openappstack.git
     $ cd openappstack
 
 > **NOTE:** Git will display a warning after you use the `git` command
diff --git a/flux/nextcloud.yaml b/flux/nextcloud.yaml
index b6706b4b7c10d60786f9219bccc4a9796ef0f071..33ac7b0865e5ce8aaeebe1f79c472cdcbd8741f7 100644
--- a/flux/nextcloud.yaml
+++ b/flux/nextcloud.yaml
@@ -11,7 +11,7 @@ spec:
   releaseName: nc
   chart:
     git: https://open.greenhost.net/openappstack/nextcloud
-    ref: 7a493d320b7a41b08ca78c1b785365239a23ed62
+    ref: b5f54e09a0fc29d3c041ecea0d9310c8283d4dae
     path: .
   valuesFrom:
     - secretKeyRef:
diff --git a/flux/wordpress.yaml b/flux/wordpress.yaml
index 5d9a34ca33d134b4c52e890f35f2cb88739f26e6..2ad8b3d5d493c38235f5154a2a3b844f91db40b9 100644
--- a/flux/wordpress.yaml
+++ b/flux/wordpress.yaml
@@ -9,7 +9,7 @@ spec:
   releaseName: wordpress
   chart:
     git: https://code.greenhost.net/open/wordpress-helm
-    ref: 858527ebcdc57401939491ca1a4d7bf7823818df
+    ref: f262679bbe3de3660e8b2d70f2f5b27955bd9472
     path: .
   valuesFrom:
     - secretKeyRef:
diff --git a/requirements-stable.txt b/requirements-stable.txt
index 3e560257d067b0b4356cdafd28fb2f8eb20ea378..1f3c615181340c370f2061916cdce83e65ac7443 100644
--- a/requirements-stable.txt
+++ b/requirements-stable.txt
@@ -1,54 +1,54 @@
-ansible==2.9.2
+ansible==2.9.6
 attrs==19.3.0
 bcrypt==3.1.7
 behave==1.2.6
 behave-webdriver==0.3.0
 cachetools==4.0.0
 certifi==2019.11.28
-cffi==1.13.2
+cffi==1.14.0
 chardet==3.0.4
 cryptography==2.8
 dictdiffer==0.8.1
-google-auth==1.10.0
+google-auth==1.11.3
 -e git+https://open.greenhost.net/greenhost/cloud-api@c174bc27f7f149786a14b40f782df399cde32f8e#egg=greenhost_cloud
-idna==2.8
-importlib-metadata==1.3.0
-Jinja2==2.10.3
-kubernetes==10.0.1
+idna==2.9
+importlib-metadata==1.5.0
+Jinja2==2.11.1
+kubernetes==10.1.0
 MarkupSafe==1.1.1
-more-itertools==8.0.2
+more-itertools==8.2.0
 -e git+https://open.greenhost.net/openappstack/oas_behave@72c7154545d8cc0084267734469c4dae5ef6b85a#egg=oas_behave
 oauthlib==3.1.0
-openshift==0.10.1
-packaging==19.2
+openshift==0.10.3
+packaging==20.3
 paramiko==2.7.1
-parse==1.12.1
+parse==1.15.0
 parse-type==0.5.2
 pluggy==0.13.1
-psutil==5.6.7
-py==1.8.0
+psutil==5.7.0
+py==1.8.1
 pyasn1==0.4.8
-pyasn1-modules==0.2.7
-pycparser==2.19
+pyasn1-modules==0.2.8
+pycparser==2.20
 PyNaCl==1.3.0
 pyOpenSSL==19.1.0
-pyparsing==2.4.5
-pytest==5.3.2
-pytest-rerunfailures==8.0
+pyparsing==2.4.6
+pytest==5.4.1
+pytest-rerunfailures==9.0
 python-dateutil==2.8.1
-python-string-utils==0.6.0
+python-string-utils==1.0.0
 pytz==2019.3
-PyYAML==5.2
-requests==2.22.0
+PyYAML==5.3
+requests==2.23.0
 requests-oauthlib==1.3.0
 rsa==4.0
-ruamel.yaml==0.16.5
+ruamel.yaml==0.16.10
 ruamel.yaml.clib==0.2.0
 selenium==3.141.0
-six==1.13.0
+six==1.14.0
 tabulate==0.8.6
-testinfra==3.3.0
-urllib3==1.25.7
-wcwidth==0.1.7
-websocket-client==0.56.0
-zipp==0.6.0
+testinfra==5.0.0
+urllib3==1.25.8
+wcwidth==0.1.8
+websocket-client==0.57.0
+zipp==3.1.0