diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 63bc02ddbc474c6a43ed4622a47689aa2e58d3f4..e5184dfaa0142d2bfd29356c21e37b081b07949a 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,11 +1,35 @@
 stages:
+  - test
   - deploy
 
+variables:
+  LATEST_VERSION_URL: https://docs.funkwhale.audio/latest.txt
+
+test-install-script:
+  stage: test
+  image: debian:10
+  interruptible: true
+  before_script:
+    - apt-get update && apt-get install -y curl
+    - |
+      echo "Retrieving latest version from $LATEST_VERSION_URL"
+      funkwhale_version=$(curl -sfL $LATEST_VERSION_URL || true)
+      if [ -z "$funkwhale_version" ]; then
+          echo "Could not retrieve latest version!"
+          exit 1
+      fi
+    - echo "Latest version is $funkwhale_version"
+    - sed -i "0,/funkwhale_version_placeholder/{s/funkwhale_version_placeholder/$funkwhale_version/}" install.sh
+  script:
+    - |
+      set -x
+      export ANSIBLE_FUNKWHALE_ROLE_PATH=$(pwd)
+      printf 'test.deployment\ntest\ncontact@test.deployment\nY\nN\n\n\n\N\n\n\n' | bash install.sh
+  tags:
+    - docker
 pages:
   stage: deploy
   image: buildpack-deps
-  variables:
-    LATEST_VERSION_URL: https://docs.funkwhale.audio/latest.txt
   script:
     - |
       echo "Retrieving latest version from $LATEST_VERSION_URL"
diff --git a/README.md b/README.md
index ab269db7185a09e76a65d1c2461533765b9c0aaf..5eef47bcf35b40a424258b3a4158fd3c0a5427be 100644
--- a/README.md
+++ b/README.md
@@ -138,6 +138,7 @@ Role Variables
 | `funkwhale_ssl_cert_path`               | ``                            | Path to an existing SSL certificate to use (use in combination with `funkwhale_letsencrypt_enabled: false`) |
 | `funkwhale_ssl_key_path`                | ``                            | Path to an existing SSL key to use (use in combination with `funkwhale_letsencrypt_enabled: false`) |
 | `funkwhale_static_path`                 | `/srv/funkwhale/data/static`  | Path were Funkwhale static files should be stored |
+| `funkwhale_systemd_managed`             | `true`                        | If `true`, will configure Funkwhale systemd services   |
 | `funkwhale_systemd_after`               | `redis.service postgresql.service` | Configuration used for Systemd `After=` directive. Modify it if you have a database or redis server on a separate host   |
 | `funkwhale_systemd_service_name`        | `funkwhale`                   | Name of the generated Systemd service, e.g when calling `systemctl start <xxx>` |
 | `funkwhale_username`                    | `funkwhale`                   | Username of the system user and owner of Funkwhale data, files and configuration |
diff --git a/defaults/main.yml b/defaults/main.yml
index a07a6f4a8ea6b0ca3cc16b59d48cb09d7e13a13b..d46d71064bfbc21ddce08074a185aee292d157e0 100644
--- a/defaults/main.yml
+++ b/defaults/main.yml
@@ -21,6 +21,7 @@ funkwhale_web_workers: 1
 funkwhale_protocol: https
 funkwhale_settings_module: config.settings.production
 funkwhale_env_vars: []
+funkwhale_systemd_managed: true
 funkwhale_systemd_after: redis.service postgresql.service
 funkwhale_systemd_service_name: funkwhale
 funkwhale_letsencrypt_certbot_flags:
diff --git a/handlers/main.yml b/handlers/main.yml
index f4b7666be378b863b331874842b67913a4a3c67e..2117c8f4ba9d0ec2796723139fa1e3b87ab3ea37 100644
--- a/handlers/main.yml
+++ b/handlers/main.yml
@@ -1,12 +1,14 @@
 ---
 - name: restart funkwhale
   become: true
+  when: funkwhale_systemd_managed
   service:
     name: "{{ funkwhale_systemd_service_name }}.target"
     state: restarted
 
 - name: reload funkwhale
   become: true
+  when: funkwhale_systemd_managed
   shell: |
     systemctl kill -s HUP {{ funkwhale_systemd_service_name }}-server
     systemctl kill -s HUP {{ funkwhale_systemd_service_name }}-worker
diff --git a/install.sh b/install.sh
index 34dbd988ec44adaa00c0417130ca5ce99d8317a4..f89d08d533c89514222be7249217de1eec4bc1b7 100644
--- a/install.sh
+++ b/install.sh
@@ -7,7 +7,6 @@ set -eu
 # If Ansible step fails with ascii decore error, ensure you have a locale properly set on
 # your system e.g apt-get install -y locales locales-all
 export LANG="en_US.UTF-8"
-
 funkwhale_version="${FUNKWHALE_VERSION-funkwhale_version_placeholder}"
 funkwhale_hostname="${FUNKWHALE_DOMAIN-}"
 funkwhale_admin_email="${FUNKWHALE_ADMIN_EMAIL-}"
@@ -23,6 +22,7 @@ base_path="/srv/funkwhale"
 ansible_conf_path="$base_path/ansible"
 ansible_bin_path="$HOME/.local/bin"
 ansible_funkwhale_role_version="${ANSIBLE_FUNKWHALE_ROLE_VERSION-master}"
+ansible_funkwhale_role_path="${ANSIBLE_FUNKWHALE_ROLE_PATH-}"
 funkwhale_systemd_after=""
 total_steps="4"
 
@@ -89,12 +89,14 @@ setup() {
             read -p "Enter your redis configuration, (e.g redis://127.0.0.1:6379/0): "  funkwhale_redis_url
             funkwhale_systemd_after="funkwhale_systemd_after: "
         fi
+        yesno_prompt funkwhale_systemd_managed 'Install and manage systemd services files?' 'yes'
         yesno_prompt funkwhale_disable_django_admin 'Disable access to API admin dashboard?' 'no'
     else
         funkwhale_nginx_managed="true"
         funkwhale_database_managed="true"
         funkwhale_redis_managed="true"
         funkwhale_disable_django_admin="false"
+        funkwhale_systemd_managed="true"
     fi
 
 
@@ -107,6 +109,7 @@ setup() {
     echo "- Admin email: $funkwhale_admin_email"
     echo "- Manage nginx and certbot: $funkwhale_nginx_managed"
     echo "- Manage redis: $funkwhale_redis_managed"
+    echo "- Manage systemd unit files: $funkwhale_systemd_managed"
     if [ "$funkwhale_redis_managed" = "false" ]; then
         echo "  - Custom redis configuration: $funkwhale_redis_url"
     fi
@@ -220,17 +223,25 @@ init_ansible() {
     echo "[2/$total_steps] Creating ansible configuration files in $ansible_conf_path..."
     mkdir -p "$ansible_conf_path"
     cd "$ansible_conf_path"
-    cat <<EOF >requirements.yml
-- src: git+https://dev.funkwhale.audio/funkwhale/ansible
-  name: funkwhale
-  version: $ansible_funkwhale_role_version
-EOF
     cat <<EOF >ansible.cfg
 [defaults]
 # Needed to use become with unprevileged users,
 # see https://docs.ansible.com/ansible/latest/user_guide/become.html#becoming-an-unprivileged-user
 #allow_world_readable_tmpfiles=true
 EOF
+    if [ "$ansible_funkwhale_role_path" = '' ]; then
+    cat <<EOF >requirements.yml
+- src: git+https://dev.funkwhale.audio/funkwhale/ansible
+  name: funkwhale
+  version: $ansible_funkwhale_role_version
+EOF
+    else
+        mkdir -p "$ansible_conf_path/roles"
+        echo "roles_path = $ansible_conf_path/roles" >> ansible.cfg
+        echo "Symlinking local version of the ansible role: $ansible_funkwhale_role_path to $ansible_conf_path/roles/funkwhale"
+        rm -f "$ansible_conf_path/roles/funkwhale"
+        ln -s "$ansible_funkwhale_role_path" "$ansible_conf_path/roles/funkwhale"
+    fi
     cat <<EOF >playbook.yml
 - hosts: funkwhale_servers
   roles:
@@ -238,17 +249,34 @@ EOF
       funkwhale_hostname: $funkwhale_hostname
       funkwhale_version: $funkwhale_version
       funkwhale_letsencrypt_email: $funkwhale_admin_email
-      funkwhale_nginx_managed: $funkwhale_nginx_managed
-      funkwhale_redis_managed: $funkwhale_redis_managed
-      funkwhale_redis_url: $funkwhale_redis_url
-      funkwhale_database_managed: $funkwhale_database_managed
-      funkwhale_database_url: $funkwhale_database_url
       # Add any environment variables to the generated .env by uncommenting and editing the lines below
       # then execute ./reconfigure
       # funkwhale_env_vars:
       #   - "EMAIL_CONFIG=smtp+tls://user@:password@youremail.host:587"
       #   - "MYCUSTOM_ENV_VAR=test"
 EOF
+    if [ "$funkwhale_nginx_managed" = "false" ]; then
+      cat <<EOF >>playbook.yml
+      funkwhale_nginx_managed: false
+EOF
+    fi
+    if [ "$funkwhale_database_managed" = "false" ]; then
+      cat <<EOF >>playbook.yml
+      funkwhale_database_managed: false
+      funkwhale_database_url: $funkwhale_database_url
+EOF
+    fi
+    if [ "$funkwhale_redis_managed" = "false" ]; then
+      cat <<EOF >>playbook.yml
+      funkwhale_redis_managed: false
+      funkwhale_redis_url: $funkwhale_redis_url
+EOF
+    fi
+    if [ "$funkwhale_systemd_managed" = "false" ]; then
+      cat <<EOF >>playbook.yml
+      funkwhale_systemd_managed: false
+EOF
+    fi
     cat <<EOF >reconfigure
 #!/bin/sh
 # reapply playbook with existing parameter
@@ -270,14 +298,12 @@ EOF
 [funkwhale_servers]
 127.0.0.1 ansible_connection=local ansible_python_interpreter=/usr/bin/python3
 EOF
-    if [ "$funkwhale_disable_django_admin" = "true" ]; then
-        cat <<EOF >>playbook.yml
-      funkwhale_disable_django_admin: true
-EOF
+    if [ "$ansible_funkwhale_role_path" = '' ]; then
+        echo "[2/$total_steps] Downloading Funkwhale playbook dependencies"
+        $ansible_bin_path/ansible-galaxy install -r requirements.yml -f
+    else
+        echo "[2/$total_steps] Skipping playbook dependencies, using local role instead"
     fi
-    echo "[2/$total_steps] Downloading Funkwhale playbook dependencies"
-    $ansible_bin_path/ansible-galaxy install -r requirements.yml -f
-
 }
 run_playbook() {
     cd "$ansible_conf_path"
diff --git a/tasks/services.yml b/tasks/services.yml
index f682f7d34c03deeca531f9d71cc07b9e8e2e9148..d07b6f6876d366e6c5f16cb4b304372aca5647ab 100644
--- a/tasks/services.yml
+++ b/tasks/services.yml
@@ -2,6 +2,7 @@
 
 - name: "Create {{ funkwhale_systemd_service_name }}-* systemd file"
   become: true
+  when: funkwhale_systemd_managed
   template:
     src: "funkwhale-process.service.j2"
     dest: "/etc/systemd/system/{{ funkwhale_systemd_service_name }}-{{ item.name }}.service"
@@ -21,6 +22,7 @@
 
 - name: "Create {{ funkwhale_systemd_service_name }} systemd target file"
   become: true
+  when: funkwhale_systemd_managed
   template:
     src: "{{ funkwhale_systemd_service_name }}.target.j2"
     dest: "/etc/systemd/system/{{ funkwhale_systemd_service_name }}.target"
@@ -30,6 +32,7 @@
 
 - name: "Start and enable {{ funkwhale_systemd_service_name }}-* services"
   become: true
+  when: funkwhale_systemd_managed
   systemd:
     name: "{{ item }}"
     enabled: true