this post was submitted on 11 Jan 2025
-12 points (25.0% liked)

Self Hosted - Self-hosting your services.

11760 readers
1 users here now

A place to share alternatives to popular online services that can be self-hosted without giving up privacy or locking you into a service you don't control.

Rules

Important

Beginning of January 1st 2024 this rule WILL be enforced. Posts that are not tagged will be warned and if not fixed within 24h then removed!

Cross-posting

If you see a rule-breaker please DM the mods!

founded 3 years ago
MODERATORS
 

Hi #SelfHosted community. I've figured out a lot of my setup. I now have a new domain, laniesplace.us, just for #HomeServer stuff. It's set up through Porkbun with Dynu for #DDNS. I've now got #Traefik, #TailscaleVPN, #Linkding, #Forgejo, #Dokuwiki, Code-Server, #Portainer, #Netdata, #Watchtower, #Cockpit, #Pihole, #MiniFlux, #TheLounge, #Filebrowser, #UptimeKuma, and the #Homer dashboard service installed. I'm now trying to set up #Authelia so I can have single sign-on to my services. For some, it's working now, but I can't seem to get Linkding to work no matter what I do. This is on a #RaspberryPi 500 with 8 GB RAM and a 512 GB SD card, running #Stormux, which is based on #ArchlinuxARM. Can anyone help? I'll reply to this post with all my relevant config files in separate posts. What's happening is this: Linkding is supposed to be available at bookmarks.laniesplace.us. When I go there, I see a 401 unauthorized error and a link to sign into Authelia. Once I sign in, though, it redirects back to the page with the 401 error. I've been trying to figure this out for hours with no luck. Files will be in replies to this post.
#SelfHosting #Linux #HomeLab #RPi #RaspberryPi500 #RPi500 #Tech #Technology
@selfhost @selfhosting @selfhosted @linux

top 13 comments
sorted by: hot top controversial new old
[–] [email protected] 10 points 1 week ago (2 children)

Why did you hashtag everything and comment every yaml 0_o

[–] [email protected] 4 points 1 week ago (1 children)

I believe this is a Mastodon post that's also federating to lemmy

[–] [email protected] 1 points 1 week ago

Ah that makes more sense

[–] [email protected] 1 points 1 week ago

It's a Mastodon post and the person just wrote everything in one paragraph. Lemmy uses the 1st line as the title for networks that do not support titled posts (like Friendica for example), but it seems that when it exceeds 200 characters it cuts the whole thing and uses everything as a description too.

[–] [email protected] 6 points 1 week ago

Nothing makes me realize I left my glasses at home quite like this post. 🤣

[–] [email protected] 1 points 1 week ago

@selfhost @selfhosting @selfhosted @linux Authelia configuration.yml:

theme: light

server:  
 address: 0.0.0.0:9091

log:  
 level: debug  
 format: text  
 file\_path: /var/log/authelia/authelia.log

totp:  
 issuer: laniesplace.us  
 period: 30  
 skew: 1

authentication\_backend:  
 file:  
 path: /config/users\_database.yml  
 password:  
 algorithm: argon2id  
 iterations: 3  
 memory: 65536  
 parallelism: 4  
 salt\_length: 16  
 key\_length: 32

access\_control:  
 default\_policy: deny  
 rules:  
 \# Public Access  
 \- domain:   
 \- "pihole.laniesplace.us"  
 \- "homer.laniesplace.us"  
 policy: bypass

 \# High Security (Two Factor)  
 \- domain:   
 \- "portainer.laniesplace.us"  
 \- "netdata.laniesplace.us"  
 \- "cockpit.laniesplace.us"  
 \- "glances.laniesplace.us"  
 \- "code.laniesplace.us"  
 policy: two\_factor  
 subject:  
 \- "group:admins"

 \# Medium Security (One Factor Admin)  
 \- domain:  
 \- "forgejo.laniesplace.us"  
 \- "files.laniesplace.us"  
 \- "uptime.laniesplace.us"  
 policy: one\_factor  
 subject:  
 \- "group:admins"

 \# Standard Auth (One Factor)  
 \- domain:  
 \- "thelounge.laniesplace.us"  
 \- "miniflux.laniesplace.us"  
 \- "linkding.laniesplace.us"  
 \- "wiki.laniesplace.us"  
 policy: one\_factor

 \# Catch-all rule  
 \- domain: "\*.laniesplace.us"  
 policy: one\_factor

session:  
 name: authelia\_session  
 domain: laniesplace.us  
 same\_site: lax  
 expiration: 3600  
 inactivity: 300  
 remember\_me: 1M

regulation:  
 max\_retries: 3  
 find\_time: 120  
 ban\_time: 300

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

notifier:  
 disable\_startup\_check: false  
 smtp:  
 address: submission://smtp.gmail.com:587  
 username: [email protected]  
 password: rcig lqpk cbsg aqcm  
 sender: "Authelia \<[email protected]\>"  
 identifier: auth.laniesplace.us  
 subject: "[Authelia] {title}"  
 startup\_check\_address: [email protected]  
 timeout: 5s

identity\_validation:  
 reset\_password:  
 jwt\_secret: ${AUTHELIA\_JWT\_SECRET\_FILE}  
[–] [email protected] 1 points 1 week ago

@selfhost @selfhosting @selfhosted @linux traefik.yml:

global:  
 checkNewVersion: true  
 sendAnonymousUsage: false

log:  
 level: DEBUG  
 filePath: /etc/traefik/logs/traefik.log

accessLog:  
 filePath: /etc/traefik/logs/access.log

entryPoints:  
 web:  
 address: :80  
 http:  
 redirections:  
 entryPoint:  
 to: websecure  
 scheme: https  
 websecure:  
 address: :443  
 http:  
 tls:  
 certResolver: le

api:  
 dashboard: true  
 insecure: false

providers:  
 file:  
 directory: /etc/traefik/dynamic  
 watch: true  
 docker:  
 endpoint: unix:///var/run/docker.sock  
 watch: true  
 exposedByDefault: false  
 network: web

certificatesResolvers:  
 le:  
 acme:  
 email: [email protected]  
 storage: /etc/traefik/acme.json  
 tlsChallenge: {}  
[–] [email protected] 0 points 1 week ago

@selfhost @selfhosting @selfhosted @linux Authelia docker-compose.yml:

services:  
 authelia:  
 image: authelia/authelia:latest  
 container\_name: authelia  
 volumes:  
 \- ./config:/config  
 \- ./logs:/var/log/authelia  
 networks:  
 \- web  
 \- authelia\_internal  
 environment:  
 \- TZ=America/Chicago  
 \- AUTHELIA\_JWT\_SECRET\_FILE=/config/secrets/jwt\_secret  
 \- AUTHELIA\_SESSION\_SECRET\_FILE=/config/secrets/session\_secret  
 \- AUTHELIA\_STORAGE\_ENCRYPTION\_KEY\_FILE=/config/secrets/storage\_encryption\_key  
 labels:  
 \- "traefik.enable=true"  
 \- "traefik.http.routers.authelia.rule=Host(`auth.laniesplace.us`)"  
 \- "traefik.http.routers.authelia.entrypoints=websecure"  
 \- "traefik.http.routers.authelia.tls.certresolver=le"  
 \- "traefik.http.middlewares.authelia.forwardauth.authRequestHeaders=X-Forwarded-Proto,X-Forwarded-Host"  
 \- "traefik.http.middlewares.authelia-basic.forwardauth.authResponseHeaders=Remote-User,Remote-Name,Remote-Email"  
 \- "traefik.http.middlewares.authelia.forwardauth.tls.insecureSkipVerify=true"  
 \- "traefik.http.services.authelia.loadbalancer.server.port=9091"  
 \- "traefik.http.middlewares.authelia.forwardauth.address=http://authelia:9091/api/verify?rd=[https://auth.laniesplace.us](https://auth.laniesplace.us)"  
 \- "traefik.http.middlewares.authelia.forwardauth.trustForwardHeader=true"  
 \- "traefik.http.middlewares.authelia.forwardauth.authResponseHeaders=Remote-User,Remote-Groups,Remote-Name,Remote-Email"

 restart: unless-stopped  
 security\_opt:  
 \- no-new-privileges:true  
 depends\_on:  
 \- redis  
 healthcheck:  
 test: ["CMD", "wget", "--no-check-certificate", "--quiet", "--tries=1", "--spider", "http://localhost:9091/api/health"]  
 interval: 30s  
 timeout: 10s  
 retries: 3  
 start\_period: 60s

 redis:  
 image: redis:alpine  
 container\_name: authelia\_redis  
 networks:  
 \- authelia\_internal  
 restart: unless-stopped  
 volumes:  
 \- ./redis:/data  
 command: redis-server --save 60 1 --loglevel warning  
 healthcheck:  
 test: ["CMD", "redis-cli", "ping"]  
 interval: 30s  
 timeout: 10s  
 retries: 3  
 security\_opt:  
 \- no-new-privileges:true

networks:  
 web:  
 external: true  
 authelia\_internal:  
 internal: true  
[–] [email protected] 0 points 1 week ago

@selfhost @selfhosting @selfhosted @linux traefik docker-compose.yml:
networks:
web:
external: true

services:
traefik:
image: traefik:v3.2.5
container_name: traefik
security_opt:
- no-new-privileges:true
ports:
- "80:80"
- "443:443"
- "8080:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./traefik.yml:/etc/traefik/traefik.yml:ro
- ./acme.json:/acme.json
- ./dynamic:/etc/traefik/dynamic:ro
- ./logs:/etc/traefik/logs
networks:
- web
restart: unless-stopped
labels:
- "traefik.enable=true"
- "traefik.http.routers.dashboard.rule=Host(traefik.laniesplace.us)"
- "traefik.http.routers.dashboard.service=api@internal"
- "traefik.http.routers.dashboard.entrypoints=websecure"
- "traefik.http.routers.dashboard.tls.certresolver=le"
- "traefik.http.routers.dashboard.middlewares=dashboard-auth"

[–] [email protected] 0 points 1 week ago

@selfhost @selfhosting @selfhosted @linux Web services docker-compose.yml, includes Linkding:

services:  
 linkding:  
 image: sissbruecker/linkding:latest-plus  
 container\_name: linkding  
 environment:  
 LD\_ENABLE\_AUTH\_PROXY: "true"  
 LD\_AUTH\_PROXY\_HEADER: "Remote-User"  
 LD\_AUTH\_PROXY\_AUTO\_LOGIN: "true"  
 LD\_AUTH\_PROXY\_LOGOUT\_URL: "[https://auth.laniesplace.us/logout](https://auth.laniesplace.us/logout)"  
 volumes:  
 \- linkding\_data:/etc/linkding/data  
 healthcheck:  
 test: ["CMD", "node", "-e", "const http = require('http'); const options = {host: 'localhost', port: 9090, path: '/', timeout: 2000}; const request = http.request(options, (res) =\> { process.exit([200, 302].includes(res.statusCode) ? 0 : 1)}); request.on('error', () =\> process.exit(1)); request.end()"]  
 interval: 30s  
 timeout: 10s  
 retries: 3  
 networks:  
 \- web  
 labels:  
 \- "traefik.enable=true"  
 \- "traefik.http.routers.linkding.rule=Host(`bookmarks.laniesplace.us`)"  
 \- "traefik.http.routers.linkding.entrypoints=websecure"  
 \- "traefik.http.routers.linkding.tls.certresolver=le"  
 \- "traefik.http.services.linkding.loadbalancer.server.port=9090"  
 \- "traefik.http.routers.linkding.middlewares=authelia@docker"

volumes:  
 linkding\_data:

networks:  
 web:  
 external: true

[–] [email protected] 0 points 1 week ago

@selfhost @selfhosting @selfhosted @linux traefik services.yml:

http:  
 services:  
 \# Docker Services  
 homer:  
 loadBalancer:  
 servers:  
 \- url: "http://homer:8080"

 glances:  
 loadBalancer:  
 servers:  
 \- url: "http://glances:61208"

 uptime-kuma:  
 loadBalancer:  
 servers:  
 \- url: "http://uptime-kuma:3001"

 miniflux:  
 loadBalancer:  
 servers:  
 \- url: "http://miniflux:8080"

 pihole:  
 loadBalancer:  
 servers:  
 \- url: "http://pihole:8088"

 portainer:  
 loadBalancer:  
 servers:  
 \- url: "http://portainer:9000"

 linkding:  
 loadBalancer:  
 servers:  
 \- url: "http://linkding:9090"

 \# Non-Docker Services  
 filebrowser:  
 loadBalancer:  
 servers:  
 \- url: "http://127.0.0.1:8085"

 netdata:  
 loadBalancer:  
 servers:  
 \- url: "http://127.0.0.1:19999"

 forgejo:  
 loadBalancer:  
 servers:  
 \- url: "http://127.0.0.1:3000"

 dokuwiki:  
 loadBalancer:  
 servers:  
 \- url: "http://127.0.0.1:81"

 cockpit:  
 loadBalancer:  
 servers:  
 \- url: "http://127.0.0.1:9090"  
[–] [email protected] 0 points 1 week ago

@selfhost @selfhosting @selfhosted @linux traefik middlewares.yml:

http:  
 middlewares:  
 dashboard-auth:  
 basicAuth:  
 users:  
 \- "admin:$apr1$t5/O0mIb$M6Mkxlqxmi2RRJHNL007Q1"  
[–] [email protected] 0 points 1 week ago

@selfhost @selfhosting @selfhosted @linux traefik routers.yml:

http:  
 routers:  
 dashboard:  
 rule: "Host(`traefik.laniesplace.us`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`))"  
 service: api@internal  
 entryPoints:  
 \- websecure  
 tls:  
 certResolver: le  
 middlewares:  
 \- dashboard-auth

 homer:  
 rule: "Host(`laniesplace.us`)"  
 service: homer  
 entryPoints:  
 \- websecure  
 tls:  
 certResolver: le  
 middlewares:  
 \- authelia@docker  
 headers:  
 customRequestHeaders:  
 X-Forwarded-Proto: "https"  
 X-Forwarded-Host: "laniesplace.us"  
 X-Forwarded-Uri: "/"  
 X-Forwarded-For: "true"

 glances:  
 rule: "Host(`glances.laniesplace.us`)"  
 service: glances  
 entryPoints:  
 \- websecure  
 tls:  
 certResolver: le  
 middlewares:  
 \- authelia@docker  
 headers:  
 customRequestHeaders:  
 X-Forwarded-Proto: "https"  
 X-Forwarded-Host: "glances.laniesplace.us"  
 X-Forwarded-Uri: "/"  
 X-Forwarded-For: "true"

 uptime-kuma:  
 rule: "Host(`uptime.laniesplace.us`)"  
 service: uptime-kuma  
 entryPoints:  
 \- websecure  
 tls:  
 certResolver: le  
 middlewares:  
 \- authelia@docker  
 headers:  
 customRequestHeaders:  
 X-Forwarded-Proto: "https"  
 X-Forwarded-Host: "uptime.laniesplace.us"  
 X-Forwarded-Uri: "/"  
 X-Forwarded-For: "true"

 miniflux:  
 rule: "Host(`rss.laniesplace.us`)"  
 service: miniflux  
 entryPoints:  
 \- websecure  
 tls:  
 certResolver: le  
 middlewares:  
 \- authelia@docker  
 headers:  
 customRequestHeaders:  
 X-Forwarded-Proto: "https"  
 X-Forwarded-Host: "rss.laniesplace.us"  
 X-Forwarded-Uri: "/"  
 X-Forwarded-For: "true"

 pihole:  
 rule: "Host(`pihole.laniesplace.us`)"  
 service: pihole  
 entryPoints:  
 \- websecure  
 tls:  
 certResolver: le  
 middlewares:  
 \- authelia@docker  
 \- pihole-redirect  
 headers:  
 customRequestHeaders:  
 X-Forwarded-Proto: "https"  
 X-Forwarded-Host: "pihole.laniesplace.us"  
 X-Forwarded-Uri: "/"  
 X-Forwarded-For: "true"

 portainer:  
 rule: "Host(`portainer.laniesplace.us`)"  
 service: portainer  
 entryPoints:  
 \- websecure  
 tls:  
 certResolver: le  
 middlewares:  
 \- authelia@docker  
 headers:  
 customRequestHeaders:  
 X-Forwarded-Proto: "https"  
 X-Forwarded-Host: "portainer.laniesplace.us"  
 X-Forwarded-Uri: "/"  
 X-Forwarded-For: "true"

 linkding:  
 rule: "Host(`bookmarks.laniesplace.us`)"  
 service: linkding  
 entryPoints:  
 \- websecure  
 tls:  
 certResolver: le  
 middlewares:  
 \- authelia@docker  
 headers:  
 customRequestHeaders:  
 X-Forwarded-Proto: "https"  
 X-Forwarded-Host: "bookmarks.laniesplace.us"  
 X-Forwarded-Uri: "/"  
 X-Forwarded-For: "true"  
 Remote-User: "{{ .Request.Headers.Remote-User }}"

 filebrowser:  
 rule: "Host(`files.laniesplace.us`)"  
 service: filebrowser  
 entryPoints:  
 \- websecure  
 tls:  
 certResolver: le  
 middlewares:  
 \- authelia@docker  
 headers:  
 customRequestHeaders:  
 X-Forwarded-Proto: "https"  
 X-Forwarded-Host: "files.laniesplace.us"  
 X-Forwarded-Uri: "/"  
 X-Forwarded-For: "true"

 netdata:  
 rule: "Host(`netdata.laniesplace.us`)"  
 service: netdata  
 entryPoints:  
 \- websecure  
 tls:  
 certResolver: le  
 middlewares:  
 \- authelia@docker  
 headers:  
 customRequestHeaders:  
 X-Forwarded-Proto: "https"  
 X-Forwarded-Host: "netdata.laniesplace.us"  
 X-Forwarded-Uri: "/"  
 X-Forwarded-For: "true"

 forgejo:  
 rule: "Host(`git.laniesplace.us`)"  
 service: forgejo  
 entryPoints:  
 \- websecure  
 tls:  
 certResolver: le  
 middlewares:  
 \- authelia@docker  
 headers:  
 customRequestHeaders:  
 X-Forwarded-Proto: "https"  
 X-Forwarded-Host: "git.laniesplace.us"  
 X-Forwarded-Uri: "/"  
 X-Forwarded-For: "true"

 dokuwiki:  
 rule: "Host(`wiki.laniesplace.us`)"  
 service: dokuwiki  
 entryPoints:  
 \- websecure  
 tls:  
 certResolver: le  
 middlewares:  
 \- authelia@docker  
 headers:  
 customRequestHeaders:  
 X-Forwarded-Proto: "https"  
 X-Forwarded-Host: "wiki.laniesplace.us"  
 X-Forwarded-Uri: "/"  
 X-Forwarded-For: "true"

 cockpit:  
 rule: "Host(`cockpit.laniesplace.us`)"  
 service: cockpit  
 entryPoints:  
 \- websecure  
 tls:  
 certResolver: le  
 middlewares:  
 \- authelia@docker  
 headers:  
 customRequestHeaders:  
 X-Forwarded-Proto: "https"  
 X-Forwarded-Host: "cockpit.laniesplace.us"  
 X-Forwarded-Uri: "/"  
 X-Forwarded-For: "true"