Silicon's blog

Menu
  • Home
  • Kadena
  • Solana
  • Ethereum
  • Bot Automation
  • Proxmox
  • Nginx Proxy Manager
  • Others
  • Contact
Menu

How to combine Dashy with Authelia to protect your personal homepage

Posted on January 22, 2023May 17, 2023 by Silicon
Sharing is Caring:
Twitter 0
Copy 0

 

As mentioned in the previous article, Dashy is a perfect fit for people who have purchased dozens of SaaS apps / self-hosting services like me.

However, it seems there is a minor bug that you have to enable guest mode in order to use the basic auth. It may lead to security issues.

Instead of using the basic auth provided by Dashy, using Authelia seems to be a more secure option.

This article will teach you how to set up Authelia for authentication.

Step 1: Move to your home directory and clone the Authelia project from GitHub.

cd ~
git clone https://github.com/authelia/authelia.git

Step 2: Move to the Authelia folder and modify the docker-compose.yml

cd authelia/examples/compose/lite
sudo nano docker-compose.yml

---
version: '3.3'

services:
  authelia:
    image: authelia/authelia
    container_name: authelia
    hostname: authelia
    restart: unless-stopped
    volumes:
      - ./authelia:/config
    ports:
       - 9091:9091
    networks:
      - npm

  redis:
    image: redis:alpine
    container_name: redis
    volumes:
      - ./redis:/data
    ports:
      - 6379:6379
    restart: unless-stopped
    networks:
      - npm
networks:
  npm:
    name: npm_network

---

Step 3: Generate a hash for your password. Replace your_password with your password.

sudo docker run authelia/authelia:latest authelia crypto hash generate argon2 --password 'your_password'

In my case, it will output

Digest: $argon2id$v=19$m=65536,t=3,p=4$oNNZOjKz6opLBgE30INXJQ$2suPPCr+4icbELbF9KqF9keagAAWlF3YkMSi6uwfVmk

Jot your digest down.

Step 4: Edit your user database.

cd authelia
sudo nano users_database.yml

Replace your_username with your username.

Substitute password with your previously generated digest.

Alter your_email to your email.


---
###############################################################
#                         Users Database                      #
###############################################################

# This file can be used if you do not have an LDAP set up.

# List of users
users:
  your_username:
    disabled: false
    displayname: "Authelia User"
    # Password is authelia
    password: "$6$rounds=50000$BpLnfgDsc2WD8F2q$Zis.ixdg9s/UOJYrs56b5QEZFiZECu0qZVNsIYxBaNJ7ucIL.nlxVCT5tqh8KHG8X4KHG8X4tlwCFm5r6NTOZZ5qRFN/"  # yamllint disable-line rule:line-length
    email: [email protected]
    groups:
      - admins
      - dev
...

In my case, it is


---
###############################################################
#                         Users Database                      #
###############################################################

# This file can be used if you do not have an LDAP set up.

# List of users
users:
  silicon:
    disabled: false
    displayname: "Authelia User"
    # Password is your_password
    password: "$argon2id$v=19$m=65536,t=3,p=4$oNNZOjKz6opLBgE30INXJQ$2suPPCr+4icbELbF9KqF9keagAAWlF3YkMSi6uwfVmk"  # yamllint disable-line rule:line-length
    email: [email protected]
    groups:
      - admins
      - dev
...

Press Ctrl + X to save the file.

Step 5: Generate a 64-word password for jwt_secret, authelia_session, and encryption_key. You may generate a 64-word password here.

Avoid using any Symbols.

Edit configuration.yml

sudo nano configuration.yml

Replace your_jwt_secret with the generated jwt_secret.

Substitute your_session_secret with the generated authelia_session.

Alter your_encryption_key to the generated encryption_key.

Modify your_domain with your subdomain.

Change your_root_domain with your domain.

 

If you want to use the notifier, you need to enter your email & password for authentication.

Check out my article on how to generate a Google App password if you are using Gmail.

Replace your_email with your email.

Replace your_google_app_password with your Google app password.


---
###############################################################
#                   Authelia configuration                    #
###############################################################

jwt_secret: your_jwt_secret
#a_very_important_secret
default_redirection_url: https://your_domain

server:
  host: 0.0.0.0
  port: 9091

log:
  level: debug
# This secret can also be set using the env variables AUTHELIA_JWT_SECRET_FILE

totp:
  issuer: your_root_domain

authentication_backend:
  file:
    path: /config/users_database.yml
  ## Password Reset Options.
  password_reset:
    ## Disable both the HTML element and the API for reset password functionality.
    disable: false

access_control:
  default_policy: deny
  rules:
    # Rules applied to everyone
    - domain: your_domain
      policy: one_factor

session:
  name: authelia_session
  # This secret can also be set using the env variables AUTHELIA_SESSION_SECRET_FILE
  secret: your_session_secret
#unsecure_session_secret
  expiration: 3600  # 1 hour
  inactivity: 300  # 5 minutes
  domain: your_root_domain # Should match whatever your root protected domain is

  redis:
    host: redis
    port: 6379
    # This secret can also be set using the env variables AUTHELIA_SESSION_REDIS_PASSWORD_FILE
    # password: authelia

regulation:
  max_retries: 3
  find_time: 120
  ban_time: 300

storage:
  encryption_key: your_encryption_key
  local:
    path: /config/db.sqlite3

notifier:
  smtp:
    username: your_email
    # This secret can also be set using the env variables AUTHELIA_NOTIFIER_SMTP_PASSWORD_FILE
    password: your_google_app_password
    host: smtp.gmail.com
    port: 587
    sender: your_email
...

In my case, it is


---
###############################################################
#                   Authelia configuration                    #
###############################################################

jwt_secret: WcZ7uwXXhMH8vjA5asICh6HALuB5sEQy9sVy2DSFyXm5JGBwcXXvW2a7Dy632EjE
#a_very_important_secret
default_redirection_url: https://auth.silicon.blog

server:
  host: 0.0.0.0
  port: 9091

log:
  level: debug
# This secret can also be set using the env variables AUTHELIA_JWT_SECRET_FILE

totp:
  issuer: silicon.blog

authentication_backend:
  file:
    path: /config/users_database.yml
  ## Password Reset Options.
  password_reset:
    ## Disable both the HTML element and the API for reset password functionality.
    disable: false

access_control:
  default_policy: deny
  rules:
    # Rules applied to everyone
    - domain: dashy.silicon.blog
      policy: one_factor

session:
  name: authelia_session
  # This secret can also be set using the env variables AUTHELIA_SESSION_SECRET_FILE
  secret: ICZeSdKQkHHsCQ24cIdaAugGuq5eDUDQKZPeqePUQcgxczscmNWWpWPs4QYUqXzv
#unsecure_session_secret
  expiration: 3600  # 1 hour
  inactivity: 300  # 5 minutes
  domain: silicon.blog # Should match whatever your root protected domain is

  redis:
    host: redis
    port: 6379
    # This secret can also be set using the env variables AUTHELIA_SESSION_REDIS_PASSWORD_FILE
    # password: authelia

regulation:
  max_retries: 3
  find_time: 120
  ban_time: 300

storage:
  encryption_key: LpJJDcjvcjX9KJnw9utrVFsYQgRwaakK9WIRSXDS93ayaFt4UnVf4555EjXDwEQr
  local:
    path: /config/db.sqlite3

notifier:
  smtp:
    username: [email protected]
    # This secret can also be set using the env variables AUTHELIA_NOTIFIER_SMTP_PASSWORD_FILE
    password: itsasecretXD
    host: smtp.gmail.com
    port: 587
    sender: [email protected]
...

Press Ctrl + X to save the file.

Step 6: Execute the container in the background.

cd ..
sudo docker compose up -d

Step 7: Log in to your Nginx Proxy Manager. Read my previous article about how to set up Nginx Proxy Manager using Docker Compose if you have not set it up.

Step 8: Bind authelia to your domain name.

Add this to your Advance section to allow Control Allow Origin (CORS).


location / {
     if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Allow-Origin' '*';
        #
        # Om nom nom cookies
        #
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        #
        # Custom headers and headers various browsers *should* be OK with but aren't
        #
        add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
        #
        # Tell client that this pre-flight info is valid for 20 days
        #
        add_header 'Access-Control-Max-Age' 1728000;
        add_header 'Content-Type' 'text/plain charset=UTF-8';
        add_header 'Content-Length' 0;
        return 204;
     }
     if ($request_method = 'POST') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
     }
     if ($request_method = 'GET') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
     }
    set $upstream_authelia http://authelia:9091; 
    proxy_pass $upstream_authelia;
    client_body_buffer_size 128k;

    #Timeout if the real server is dead
    proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;

    # Advanced Proxy Config
    send_timeout 5m;
    proxy_read_timeout 360;
    proxy_send_timeout 360;
    proxy_connect_timeout 360;

    # Basic Proxy Config
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-Host $host;
    proxy_set_header X-Forwarded-Uri $request_uri;
    proxy_set_header X-Forwarded-Ssl on;
    proxy_redirect  http://  $scheme://;
    proxy_http_version 1.1;
    proxy_set_header Connection "";
    proxy_cache_bypass $cookie_session;
    proxy_no_cache $cookie_session;
    proxy_buffers 64 256k;

    set_real_ip_from 172.0.0.0/8; 
    set_real_ip_from 10.0.0.0/24;

    real_ip_header X-Forwarded-For;
    real_ip_recursive on;
}

Press Save button to take effect.

Step 9: Bind Dashy to your domain name.

 

Add this to your Advance section to add an authentication function to Dashy.

Moreover, this can avoid a minor bug triggered by Dashy. That is, whenever you switch to another page, it will add a /home/ to your directory. If you refresh the page, it will show a 404 error.

I will introduce a method redirecting you to the Dashy homepage when a 404 error occurs.

 

Replace your_authelia_subdomain with your Authelia subdomain.

Replace your_dashy_subdomain with your Dashy subdomain.


location /authelia {
     if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Allow-Origin' '*';
        #
        # Om nom nom cookies
        #
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        #
        # Custom headers and headers various browsers *should* be OK with but aren't
        #
        add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
        #
        # Tell client that this pre-flight info is valid for 20 days
        #
        add_header 'Access-Control-Max-Age' 1728000;
        add_header 'Content-Type' 'text/plain charset=UTF-8';
        add_header 'Content-Length' 0;
        return 204;
     }
     if ($request_method = 'POST') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
     }
     if ($request_method = 'GET') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
     }
    internal;
    set $upstream_authelia http://authelia:9091/api/verify; 
    proxy_pass_request_body off;
    proxy_pass $upstream_authelia;    
    proxy_set_header Content-Length "";
 
    # Timeout if the real server is dead
    proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
    client_body_buffer_size 128k;
    proxy_set_header Host $http_host;
    proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $remote_addr; 
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-Host $http_host;
    proxy_set_header X-Forwarded-Uri $request_uri;
    proxy_set_header X-Forwarded-Ssl on;
    proxy_redirect  http://  $scheme://;
    proxy_http_version 1.1;
    proxy_set_header Connection "";
    proxy_cache_bypass $cookie_session;
    proxy_no_cache $cookie_session;
    proxy_buffers 4 32k;
 
    send_timeout 5m;
    proxy_read_timeout 240;
    proxy_send_timeout 240;
    proxy_connect_timeout 240;
}

 
location / {
     if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Allow-Origin' '*';
        #
        # Om nom nom cookies
        #
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        #
        # Custom headers and headers various browsers *should* be OK with but aren't
        #
        add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
        #
        # Tell client that this pre-flight info is valid for 20 days
        #
        add_header 'Access-Control-Max-Age' 1728000;
        add_header 'Content-Type' 'text/plain charset=UTF-8';
        add_header 'Content-Length' 0;
        return 204;
     }
     if ($request_method = 'POST') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
     }
     if ($request_method = 'GET') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
     }
	set $upstream_d http://dashy;  
	proxy_pass $upstream_d;  

	auth_request /authelia;
	auth_request_set $target_url $scheme://$http_host$request_uri;
	auth_request_set $user $upstream_http_remote_user;
	auth_request_set $groups $upstream_http_remote_groups;
	proxy_set_header Remote-User $user;
	proxy_set_header Remote-Groups $groups;
	error_page 401 =302 https://your_authelia_subdomain; 

	client_body_buffer_size 128k;

	proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;

	send_timeout 5m;
	proxy_read_timeout 360;
	proxy_send_timeout 360;
	proxy_connect_timeout 360;

	proxy_set_header Host $http_host;
	proxy_set_header X-Real-IP $remote_addr;
	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
	proxy_set_header X-Forwarded-Proto $scheme;
	proxy_set_header X-Forwarded-Host $http_host;
	proxy_set_header X-Forwarded-Uri $request_uri;
	proxy_set_header X-Forwarded-Ssl on;
	proxy_redirect  http://  $scheme://;
	proxy_http_version 1.1;
	proxy_set_header Connection "";
	proxy_cache_bypass $cookie_session;
	proxy_no_cache $cookie_session;
	proxy_buffers 64 256k;

	set_real_ip_from 172.0.0.0/8;
	set_real_ip_from 10.0.0.0/24;

	real_ip_header X-Forwarded-For;
	real_ip_recursive on;
}

location ~ ^/home(/?)(.*)$ {
    return  https://your_dashy_subdomain;
}

In my case, it is


location /authelia {
     if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Allow-Origin' '*';
        #
        # Om nom nom cookies
        #
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        #
        # Custom headers and headers various browsers *should* be OK with but aren't
        #
        add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
        #
        # Tell client that this pre-flight info is valid for 20 days
        #
        add_header 'Access-Control-Max-Age' 1728000;
        add_header 'Content-Type' 'text/plain charset=UTF-8';
        add_header 'Content-Length' 0;
        return 204;
     }
     if ($request_method = 'POST') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
     }
     if ($request_method = 'GET') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
     }
    internal;
    set $upstream_authelia http://authelia:9091/api/verify; 
    proxy_pass_request_body off;
    proxy_pass $upstream_authelia;    
    proxy_set_header Content-Length "";
 
    # Timeout if the real server is dead
    proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
    client_body_buffer_size 128k;
    proxy_set_header Host $http_host;
    proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $remote_addr; 
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-Host $http_host;
    proxy_set_header X-Forwarded-Uri $request_uri;
    proxy_set_header X-Forwarded-Ssl on;
    proxy_redirect  http://  $scheme://;
    proxy_http_version 1.1;
    proxy_set_header Connection "";
    proxy_cache_bypass $cookie_session;
    proxy_no_cache $cookie_session;
    proxy_buffers 4 32k;
 
    send_timeout 5m;
    proxy_read_timeout 240;
    proxy_send_timeout 240;
    proxy_connect_timeout 240;
}

 
location / {
     if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Allow-Origin' '*';
        #
        # Om nom nom cookies
        #
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        #
        # Custom headers and headers various browsers *should* be OK with but aren't
        #
        add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
        #
        # Tell client that this pre-flight info is valid for 20 days
        #
        add_header 'Access-Control-Max-Age' 1728000;
        add_header 'Content-Type' 'text/plain charset=UTF-8';
        add_header 'Content-Length' 0;
        return 204;
     }
     if ($request_method = 'POST') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
     }
     if ($request_method = 'GET') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
     }
	set $upstream_d http://dashy;  
	proxy_pass $upstream_d;  

	auth_request /authelia;
	auth_request_set $target_url $scheme://$http_host$request_uri;
	auth_request_set $user $upstream_http_remote_user;
	auth_request_set $groups $upstream_http_remote_groups;
	proxy_set_header Remote-User $user;
	proxy_set_header Remote-Groups $groups;
	error_page 401 =302 https://auth.silicon.blog; 

	client_body_buffer_size 128k;

	proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;

	send_timeout 5m;
	proxy_read_timeout 360;
	proxy_send_timeout 360;
	proxy_connect_timeout 360;

	proxy_set_header Host $http_host;
	proxy_set_header X-Real-IP $remote_addr;
	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
	proxy_set_header X-Forwarded-Proto $scheme;
	proxy_set_header X-Forwarded-Host $http_host;
	proxy_set_header X-Forwarded-Uri $request_uri;
	proxy_set_header X-Forwarded-Ssl on;
	proxy_redirect  http://  $scheme://;
	proxy_http_version 1.1;
	proxy_set_header Connection "";
	proxy_cache_bypass $cookie_session;
	proxy_no_cache $cookie_session;
	proxy_buffers 64 256k;

	set_real_ip_from 172.0.0.0/8;
	set_real_ip_from 10.0.0.0/24;

	real_ip_header X-Forwarded-For;
	real_ip_recursive on;
}

location ~ ^/home(/?)(.*)$ {
    return  https://dashy.silicon.blog;
}

 

Step 10: Move to Cloudflare, and add A records to your Dashy & Authelia subdomains if you are using a static IP.

Instead, if you are using a dynamic IP address and you want to use a DDNS. Create a CName record.

Step 11: Ensure you have forwarded port 80/443 to Nginx Proxy Manager on your router/ switch. Since different brands will have different configurations, you may need to Google it and set it up yourself.

If you are using Oracle Cloud, remember to configure your firewall to allow incoming traffic by

sudo iptables -I INPUT -j ACCEPT
sudo su
iptables-save > /etc/iptables/rules.v4
exit

Try to connect to your Dashy subdomain after some time. It may take at most 1 day to update the DNS record.

Troubleshooting

If you cannot connect to Dashy through your Dashy subdomain. Have a look at all of your docker containers

sudo docker ps

CONTAINER ID   IMAGE                             COMMAND                  CREATED          STATUS                    PORTS                                                                                  NAMES
3f8f41c97315   redis:alpine                      "docker-entrypoint.s…"   25 minutes ago   Up 25 minutes             0.0.0.0:6379->6379/tcp, :::6379->6379/tcp                                              redis
7e3afc21c4cd   authelia/authelia                 "/app/entrypoint.sh …"   25 minutes ago   Up 25 minutes (healthy)   0.0.0.0:9091->9091/tcp, :::9091->9091/tcp                                              authelia
d9f30e6bf832   lissy93/dashy:latest              "yarn build-and-start"   2 hours ago      Up 2 hours (healthy)      0.0.0.0:4000->80/tcp, :::4000->80/tcp                                                  Dashy
e44fb1098270   jc21/nginx-proxy-manager:latest   "/init"                  7 hours ago      Up 7 hours                0.0.0.0:80-81->80-81/tcp, :::80-81->80-81/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp   nginx-app-1

Check out your container IP

sudo docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' nginx-app-1
172.18.0.2
sudo docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' Dashy
172.19.0.2

If they are not on the same network, change the port number of Dashy to 4000 on Nginx Proxy Manager. If it still does not work, enter the Nginx Proxy Manager terminal.

sudo docker exec -it nginx-app-1 bash

Try to fetch Dashy by

curl http://dashy:4000

If it says it could not resolve the host, you shall add it to the end of each container.

    networks:
      - npm

Also, add,

networks:
  npm:
    name: npm_network

to the end of the docker-compose.yml

Step 12: Enter your Dashy subdomain on a browser. It will redirect you to your Authelia subdomain. Log in with the username & password.

Step 13: After authentication, move to your Dashy subdomain again. This time you will be able to access Dashy.

Try to create a new page. Switch between different pages. You will find an additional “home/” path. It is a minor bug on this Dashy version (Commit: 3c5177dd704821286d51830abe2c2840a92b7f54).

Press F5 to refresh the page, and it will redirect you to the homepage of Dashy. We have set up the 404 redirections on the Nginx Proxy Manager before.

   

If you reach here without any error, congratulation, you have already set up Authelia. It will provide an extra security layer to the Dashy dashboard.

Leave a Reply Cancel reply


The reCAPTCHA verification period has expired. Please reload the page.

©2025 Silicon's blog
Click to Copy