diff --git a/filter_plugins/tailscale_to_dashboard.py b/filter_plugins/tailscale_to_dashboard.py
new file mode 100644
index 0000000..c398d68
--- /dev/null
+++ b/filter_plugins/tailscale_to_dashboard.py
@@ -0,0 +1,24 @@
+class FilterModule(object):
+    def filters(self):
+        return {
+            'tailscale_to_dashboard': self.tailscale_to_dashboard,
+        }
+
+    def tailscale_to_dashboard(self, tailscale):
+        ts_key = tailscale["key"]
+        machines = tailscale["machines"]
+
+        result = []
+        for (key, props) in machines.items():
+            result.append({
+                key: {
+                    "href": "https://login.tailscale.com/admin/machines/" + props["ip"],
+                    "widget": {
+                        "type": "tailscale",
+                        "deviceid": props["id"],
+                        "key": ts_key
+                        }
+                    }
+                })
+
+        return result
diff --git a/inventory/serguzim.net.yml b/inventory/serguzim.net.yml
index c16c5fe..b641194 100644
--- a/inventory/serguzim.net.yml
+++ b/inventory/serguzim.net.yml
@@ -3,7 +3,7 @@ all:
     local-dev:
       ansible_connection: local
     node001:
-      ansible_host: node001.vpn.serguzim.net
+      ansible_host: node001.serguzim.net
       ansible_port: "{{ vault_node001.ansible_port }}"
       ansible_user: "{{ vault_node001.ansible_user }}"
       host_vpn:
@@ -16,7 +16,7 @@ all:
           - minecraft-2_data
 
     node002:
-      ansible_host: node002.vpn.serguzim.net
+      ansible_host: node002.serguzim.net
       ansible_port: "{{ vault_node002.ansible_port }}"
       ansible_user: "{{ vault_node002.ansible_user }}"
       host_vpn:
@@ -41,7 +41,7 @@ all:
           - vikunja_data
 
     node003:
-      ansible_host: node003.vpn.serguzim.net
+      ansible_host: node003.serguzim.net
       ansible_port: "{{ vault_node003.ansible_port }}"
       ansible_user: "{{ vault_node003.ansible_user }}"
       host_vpn:
diff --git a/node002.yml b/node002.yml
index a3234ab..f218d5a 100644
--- a/node002.yml
+++ b/node002.yml
@@ -29,6 +29,8 @@
       tags: [forgejo, git, development]
     - role: forgejo_runner
       tags: [forgejo-runner, ci, development]
+    - role: gethomepage
+      tags: [gethomepage, dashboard]
     - role: harbor
       tags: [harbor, registry, development]
     - role: healthcheck
diff --git a/roles/_TEMPLATE/tasks/main.yml b/roles/_TEMPLATE/tasks/main.yml
deleted file mode 100644
index 53f2d27..0000000
--- a/roles/_TEMPLATE/tasks/main.yml
+++ /dev/null
@@ -1,12 +0,0 @@
----
-- name: Set common facts
-  ansible.builtin.import_tasks: tasks/set-default-facts.yml
-
-- name: Deploy {{ svc.name }}
-  vars:
-    svc: "{{ NAME_svc }}"
-    env: "{{ NAME_env }}"
-    compose: "{{ NAME_compose }}"
-  block:
-    - name: Import tasks to deploy common service
-      ansible.builtin.import_tasks: tasks/deploy-common-service.yml
diff --git a/roles/_TEMPLATE/vars/main.yml b/roles/_TEMPLATE/vars/main.yml
deleted file mode 100644
index a1db2a8..0000000
--- a/roles/_TEMPLATE/vars/main.yml
+++ /dev/null
@@ -1,17 +0,0 @@
----
-NAME_svc:
-  domain: NAME.serguzim.me
-  name: NAME
-  port: 80
-
-NAME_env:
-  EXAMPLE: value
-
-NAME_compose:
-  watchtower: true
-  image: 
-  volumes:
-    - data:/data
-  file:
-    volumes:
-      data:
diff --git a/roles/gethomepage/tasks/main.yml b/roles/gethomepage/tasks/main.yml
new file mode 100644
index 0000000..0ea2756
--- /dev/null
+++ b/roles/gethomepage/tasks/main.yml
@@ -0,0 +1,69 @@
+---
+- name: Set common facts
+  ansible.builtin.import_tasks: tasks/set-default-facts.yml
+
+- name: Deploy {{ svc.name }}
+  vars:
+    svc: "{{ gethomepage_svc }}"
+    compose: "{{ gethomepage_compose }}"
+  block:
+    - name: Import prepare tasks for common service
+      ansible.builtin.import_tasks: tasks/prepare-common-service.yml
+
+    - name: Set 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 settings
+      ansible.builtin.template:
+        src: yml.j2
+        dest: "{{ (config_path, 'settings.yaml') | path_join }}"
+        mode: "0644"
+      vars:
+        yml: "{{ gethomepage_settings_yml }}"
+      register: cmd_result_settings
+
+    - name: Template services
+      ansible.builtin.template:
+        src: yml.j2
+        dest: "{{ (config_path, 'services.yaml') | path_join }}"
+        mode: "0644"
+      vars:
+        yml: "{{ gethomepage_services_yml }}"
+      register: cmd_result_services
+
+    - name: Template booksmarks
+      ansible.builtin.template:
+        src: yml.j2
+        dest: "{{ (config_path, 'booksmarks.yaml') | path_join }}"
+        mode: "0644"
+      vars:
+        yml: "{{ gethomepage_bookmarks_yml }}"
+      register: cmd_result_booksmarks
+
+    - name: Template widgets
+      ansible.builtin.template:
+        src: yml.j2
+        dest: "{{ (config_path, 'widgets.yaml') | path_join }}"
+        mode: "0644"
+      vars:
+        yml: "{{ gethomepage_widgets_yml }}"
+      register: cmd_result_widgets
+
+    - name: Set the docker force-recreate flag
+      ansible.builtin.set_fact:
+        docker_force_recreate: --force-recreate
+      when: | # noqa: no-handler We need to handle the restart per service. Handlers don't support variables.
+        cmd_result_settings.changed
+        or cmd_result_services.changed
+        or cmd_result_booksmarks.changed
+        or cmd_result_widgets.changed
+
+    - name: Import start tasks for common service
+      ansible.builtin.import_tasks: tasks/start-common-service.yml
diff --git a/roles/gethomepage/vars/main.yml b/roles/gethomepage/vars/main.yml
new file mode 100644
index 0000000..ced8481
--- /dev/null
+++ b/roles/gethomepage/vars/main.yml
@@ -0,0 +1,117 @@
+---
+gethomepage_svc:
+  domain: dashboard.serguzim.me
+  name: gethomepage
+  port: 3000
+  caddy_extra: import auth_serguzim_me
+
+gethomepage_settings_yml:
+  title: serguzim.net Dashboard
+  startUrl: https://{{ gethomepage_svc.domain }}
+
+  useEqualHeights: true
+
+  layout:
+    - Infrastructure:
+        style: row
+        columns: 4
+    - Services:
+        style: row
+        columns: 4
+    - External:
+        style: row
+        columns: 4
+    - VPN:
+        style: row
+        columns: 4
+
+gethomepage_services_yml:
+  - Infrastructure:
+      - reverse-proxy@node002.serguzim.net:
+          widget:
+            type: caddy
+            url: http://node002.vpn.serguzim.net:2019
+      - faas.serguzim.me:
+          href: https://faas.serguzim.me
+      - s3.serguzim.me:
+          href: https://s3.serguzim.me
+  - Services:
+      - analytics.serguzim.me:
+          href: https://analytics.serguzim.me
+      - auth.serguzim.me:
+          href: https://auth.serguzim.me
+          widget:
+            type: authentik
+            url: https://auth.serguzim.me
+            key: "{{ vault_gethomepage.authentik.key }}"
+      - coder.serguzim.me:
+          href: https://coder.serguzim.me
+      - gallery.serguzim.me:
+          href: https://gallery.serguzim.me
+      - git.serguzim.me:
+          href: https://git.serguzim.me
+      - inventory.serguzim.me:
+          href: https://inventory.serguzim.me
+      - mail.serguzim.me:
+          href: https://mail.serguzim.me
+      - media.serguzim.me:
+          href: https://media.serguzim.me
+      - push.serguzim.me:
+          href: https://push.serguzim.me
+      - recipes.serguzim.me:
+          href: https://recipes.serguzim.me
+      - registry.serguzim.me:
+          href: https://registry.serguzim.me
+      - rss.serguzim.me:
+          href: https://rss.serguzim.me
+      - status.serguzim.me:
+          href: https://status.serguzim.me
+          widget:
+            type: uptimekuma
+            url: https://status.serguzim.me
+            slug: serguzim-net
+      - tick.serguzim.me:
+          href: https://tick.serguzim.me
+      - todo.serguzim.me:
+          href: https://todo.serguzim.me
+      - wiki.serguzim.me:
+          href: https://wiki.serguzim.me
+  - External:
+      - Nextdns:
+          href: https://my.nextdns.io
+          widget:
+            type: nextdns
+            profile: "{{ vault_gethomepage.nextdns.profile }}"
+            key: "{{ vault_gethomepage.nextdns.key }}"
+  - VPN: "{{ vault_tailscale | tailscale_to_dashboard }}"
+
+gethomepage_bookmarks_yml:
+  - Developer:
+      - Github:
+          - abbr: GH
+            href: https://github.com/
+  - Social:
+      - Reddit:
+          - abbr: RE
+            href: https://reddit.com/
+  - Entertainment:
+      - YouTube:
+          - abbr: YT
+            href: https://youtube.com/
+
+gethomepage_widgets_yml:
+  - resources:
+      cpu: true
+      memory: true
+      disk: /
+
+  - search:
+      provider: duckduckgo
+      target: _blank
+
+gethomepage_compose:
+  watchtower: true
+  image: ghcr.io/gethomepage/homepage
+  volumes:
+    - /var/run/docker.sock:/var/run/docker.sock
+    - ./config:/app/config/
diff --git a/roles/healthcheck/files/data/matrix b/roles/healthcheck/files/data/matrix
index f2e4ac9..ad1bfd6 100755
--- a/roles/healthcheck/files/data/matrix
+++ b/roles/healthcheck/files/data/matrix
@@ -34,12 +34,21 @@ async def main():
         print(e)
 
         print("exception during login or sending")
-        send_ping(False, str(e))
+        send_ping(False)
         sys.exit(1)
     await client.close()
 
+    url = "https://federationtester.matrix.org/api/report?server_name=" \
+        + os.environ['MATRIX_SERVER_FEDTESTER']
+    resp = requests.get(url)
+    data = resp.json() # Check the JSON Response Content documentation below
+    if data["FederationOK"] != True:
+        send_ping(False)
+        sys.exit(1)
+
     send_ping(True)
     sys.exit(0)
 
 
+
 asyncio.new_event_loop().run_until_complete(main())
diff --git a/roles/healthcheck/vars/main.yml b/roles/healthcheck/vars/main.yml
index 4dd4f9e..cd15cab 100644
--- a/roles/healthcheck/vars/main.yml
+++ b/roles/healthcheck/vars/main.yml
@@ -11,7 +11,7 @@ healthcheck_env:
 
   HTTP_HC_UID: "{{ vault_healthcheck.hc_uid.http }}"
 
-  MATRIX_SERVER: https://matrix.serguzim.me
+  MATRIX_SERVER: https://matrix.msrg.cc
   MATRIX_SERVER_FEDTESTER: msrg.cc
   MATRIX_HC_UID: "{{ vault_healthcheck.hc_uid.matrix }}"
   MATRIX_TOKEN: "{{ vault_healthcheck.matrix.token }}"
diff --git a/roles/synapse/vars/main.yml b/roles/synapse/vars/main.yml
index 3e615d6..8379f00 100644
--- a/roles/synapse/vars/main.yml
+++ b/roles/synapse/vars/main.yml
@@ -1,7 +1,7 @@
 ---
 synapse_svc:
   name: synapse
-  domain: matrix.serguzim.me
+  domain: matrix.msrg.cc
   docker_host: synapse-admin
   port: 80
   caddy_extra: |
@@ -12,9 +12,9 @@ synapse_svc:
         reverse_proxy synapse:8008
     }
   extra_svcs:
-    - domain: matrix.serguzim.me:8448
+    - domain: matrix.msrg.cc:8448
       additional_domains:
-        - serguzim.me:8448
+        - msrg.cc:8448
       docker_host: synapse
       port: 8008
   db:
@@ -26,12 +26,12 @@ synapse_svc:
 
 synapse_env:
   SYNAPSE_CONFIG_PATH: "{{ ('/', svc.config_path) | path_join }}"
-  REACT_APP_SERVER: https://matrix.serguzim.me
+  REACT_APP_SERVER: https://matrix.msrg.cc
 
 synapse_yml:
   server_name: msrg.cc
   pid_file: "{{ (svc.config_path, 'homeserver.pid') | path_join }}"
-  public_baseurl: https://matrix.serguzim.me/
+  public_baseurl: https://matrix.msrg.cc/
   allow_public_rooms_without_auth: true
   allow_public_rooms_over_federation: true