Replies: 72 comments 415 replies
-
hi , |
Beta Was this translation helpful? Give feedback.
This comment has been hidden.
This comment has been hidden.
-
This is amazing @flll , I am trying to achieve the same since a month. But I am not using docker. Can you KINDLY make a script like the one for nextcloud with nginx as server, caddy as reverse proxy, tailscale and cloudflare as DNS. regards |
Beta Was this translation helpful? Give feedback.
This comment has been hidden.
This comment has been hidden.
-
Thank you for your work @flll . But no matter how many times I try the procedure, the hostname I give in the compose environment doesn't get created in the tailscale and rather a random ephemeral hostname is created after manually authenticating using the url in the log.
My Internet and Network connection is fine. But I cannot log into the nextcloud instance even with the the randomly generated hostname in my tailnet. |
Beta Was this translation helpful? Give feedback.
-
Did anyone get this error? docker compose up tailscale-1 | boot: 2024/10/24 22:18:21 Running 'tailscale up' |
Beta Was this translation helpful? Give feedback.
-
Nice guide! Thanks so much.
or
Note: same goes for the |
Beta Was this translation helpful? Give feedback.
-
Okay, one question: Should I "sudo dnf install tailscale" on my host, then follow all this docker compose things? because how would I declare ACL dst 'nextcloud.your-tailnet.ts.net'? Or do I add my device manually in tailscale admin? I might be very less informed about ACL and tags, but I am trying to learn and doing all this to use nextcloud-aio is tiring, but I am trying my best. Thanks! PS: I was using this
|
Beta Was this translation helpful? Give feedback.
-
Thanks for the guide, it's great but I cannot make it work for myself. My compose.yaml:
My ACL:
Caddy seems to recognize the domain name correctly, i.e. it resolves $NC_DOMAIN correctly. Tailscale logs:
Tried opening 443 (TCP and UDP), 80, 8080 (out of desperation) in firewall and even disabling the firewall completely, none of it helped Seems that no matter what I do, in the nextcloud container I see:
Pinging the domain name within tailscale works without problems |
Beta Was this translation helpful? Give feedback.
-
Finally access the domain. |
Beta Was this translation helpful? Give feedback.
-
Hey, So I have tried a lot of things, now my experience is like this:
Apache logs:
Nextcloud logs:
Redis:
Database:
Notify Push:
Nextcloud Mastercontainer Logs:
My ACL of Tailscale:
|
Beta Was this translation helpful? Give feedback.
-
Has anyone tried to deploy using the portainer stack? Caddy log:
I have double-checked my NC_DOMAIN variable. compose.yml: services:
nextcloud-aio-mastercontainer:
image: nextcloud/all-in-one:latest
init: true
restart: always
container_name: nextcloud-aio-mastercontainer # This line cannot be changed.
volumes:
- nextcloud_aio_mastercontainer:/mnt/docker-aio-config
- /var/run/docker.sock:/var/run/docker.sock:ro
networks:
- nextcloud-aio
ports:
- 0.0.0.0:8080:8080
environment:
APACHE_PORT: 11000
APACHE_IP_BINDING: 127.0.0.1
SKIP_DOMAIN_VALIDATION: true
caddy:
image: caddy:alpine
restart: unless-stopped
container_name: caddy
environment:
NC_DOMAIN: nextcloud.[redacted].ts.net # Change this to your domain ending with .ts.net in the format {$TS_HOSTNAME}.{tailnetdomain}
volumes:
- type: bind
source: /home/surya/Caddyfile
target: /etc/caddy/Caddyfile
- type: volume
source: caddy_certs
target: /certs
- type: volume
source: caddy_data
target: /data
- type: volume
source: caddy_config
target: /config
- type: volume
source: tailscale_sock
target: /var/run/tailscale/ # Mount the volume for /var/run/tailscale/tailscale.sock
read_only: true
network_mode: service:tailscale
tailscale:
image: tailscale/tailscale:latest
container_name: tailscale
environment:
TS_HOSTNAME: nextcloud # Enter the hostname for your tailnet
TS_AUTH_KEY: tskey-client-kYthXvJbHD21CNTRL-[redacted] # OAuth client key recommended
TS_EXTRA_ARGS: --advertise-tags=tag:nextcloud # Tags are required when using OAuth client
init: true
restart: unless-stopped
volumes:
- /dev/net/tun:/dev/net/tun
- type: volume
source: tailscale
target: /var/lib/tailscale
- type: volume
source: tailscale_sock
target: /tmp # Mounting the entire /tmp folder to access tailscale.sock
cap_add:
- NET_ADMIN
- NET_RAW
networks:
- nextcloud-aio
volumes:
nextcloud_aio_mastercontainer:
name: nextcloud_aio_mastercontainer # This line cannot be changed.
caddy_certs:
name: caddy_certs
caddy_data:
name: caddy_data
caddy_config:
name: caddy_config
tailscale:
name: tailscale
tailscale_sock:
name: tailscale_sock
networks:
nextcloud-aio:
name: nextcloud-aio
driver: bridge
enable_ipv6: false
driver_opts:
com.docker.network.driver.mtu: "9001" # Jumbo Frame
com.docker.network.bridge.host_binding_ipv4: "127.0.0.1" # Harden aio Tailscale ACL: "groups": {
"group:admin": ["js-surya@github"],
"group:users": ["user@example.com", "otheruser@example.com"],
},
"tagOwners": {
"tag:nextcloud": ["group:admin"],
},
"acls": [
// Allow general unrestricted access (you can comment this out if needed).
{"action": "accept", "src": ["*"], "dst": ["*:*"]},
// Allow users in "group:users" to access any devices tagged with "nextcloud".
{"action": "accept", "src": ["group:users"], "dst": ["tag:nextcloud:*"]}, I'm not an IT expert, and I'm relatively new to this. My IP is behind CGNAT, and I want to access my Nextcloud server outside my local network using Tailscale. I'm eager to learn, so any suggestions or help would be appreciated. |
Beta Was this translation helpful? Give feedback.
-
Apache is always unhealthy docker exec -it nextcloud-aio-apache bash -x /healthcheck.sh
|
Beta Was this translation helpful? Give feedback.
-
@flll Wanted to mention that I was able to get this working without needing caddy at all. I think it simplifies things a bit. Tailscale can natively proxy Note this employs tailscale serve (as opposed to tailscale funnel) so will only expose the service to your tailnet, not publicly. You could set a funnel flag to true in the json config below to expose it publicly, though some security and performance caveats would apply if you did.
|
Beta Was this translation helpful? Give feedback.
-
Hi. Thanks a lot for this guide! I was having a lot of trouble with the Cloudflare DNS tunnel and the setup using Tailscale is much simpler. However, I was not able to access the instance locally from a LAN device not connected to my Tailscale network. I have my pihole local DNS server point
Do you have any suggestion on how to make this work? Would it help to use |
Beta Was this translation helpful? Give feedback.
-
@flll will tailscale, caddy sidecar work with synapse+coturn? I wonder if it is possiable? |
Beta Was this translation helpful? Give feedback.
-
This was a great guide, thank you @flll! My only feedback: Thanks again! |
Beta Was this translation helpful? Give feedback.
-
How to setup with TSDproxy in order to have multiple apps:TSDproxy is a tailscale reverse proxy that allows you to deploy multiple docker apps without the needing sidecars. In this following example, we'll configure TSDproxy to redirect to:
PLEASE NOTE: Create a 90-day, no-ephemeral key.
media:
filename: /config/media.yaml
defaultProxyProvider: default
defaultProxyAccessLog: false
nextcloud:
url: http://nextcloud-aio-apache:11000
Check your machine list into tailscale, you should see the different hosts. PLEASE NOTE: I wasn't able to make it work the turn/stun server for "nextcloud-aio-talk:3478" upstream using TSDproxy. Improvements are welcome! |
Beta Was this translation helpful? Give feedback.
-
Great. But how about synapse server and coturn server
…On Mon, Mar 24, 2025, 10:46 Chris Coria ***@***.***> wrote:
How to setup with TSDproxy in order to have multiple apps:
TSDproxy is a tailscale reverse proxy
<https://almeidapaulopt.github.io/tsdproxy/> that allows you to deploy
multiple docker apps without the needing sidecars.
In this following example, we'll configure TSDproxy to redirect to:
- Nextcloud
- Vaultwarden
- Pi-hole
- Dashy
- Stirling PDF
- Calibre web
PLEASE NOTE: Create a 90-day, no-ephemeral key
<https://login.tailscale.com/admin/settings/keys>.
docker-compose.yml:
services:
## TSDproxy
tsdproxy:
image: almeidapaulopt/tsdproxy:latest
container_name: tsdproxy
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- tsdproxy_data:/data
- tsdproxy_config:/config
environment:
# Get AuthKey from your Tailscale account
- TSDPROXY_AUTHKEY=tskey-auth-XXXXXXXXXXXXX # Change: put your tailscale key.
# Address of docker server (access to example.com ports)
# - TSDPROXY_HOSTNAME=192.168.xxx.xxx
- DOCKER_HOST=unix:///var/run/docker.sock
restart: unless-stopped
ports:
- 8086:8080 # For the dashboard
networks:
- proxy-net
- nextcloud-aio
## NEXTCLOUD
nextcloud:
image: nextcloud/all-in-one:latest
init: true
restart: always
container_name: nextcloud-aio-mastercontainer # This line cannot be changed.
volumes:
- nextcloud_aio_mastercontainer:/mnt/docker-aio-config
- /var/run/docker.sock:/var/run/docker.sock:ro
ports:
- "8080:8080"
environment:
- NEXTCLOUD_DATADIR=/mnt/data/nextcloud # Change: Use your own dir.
# - AIO_DISABLE_BACKUP_SECTION=true
- APACHE_PORT=11000
- APACHE_IP_BINDING=0.0.0.0
- SKIP_DOMAIN_VALIDATION=false
- NEXTCLOUD_ENABLE_DRI_DEVICE=true # Change this if you don't have DRI supported.
networks:
- nextcloud-aio
## PI-HOLE
pihole:
image: pihole/pihole:latest
container_name: pihole
restart: always
labels:
tsdproxy.enable: "true"
tsdproxy.name: "pi"
tsdproxy.container_port: 80
tsdproxy.ephemeral: "false"
environment:
- TZ="America/Mexico_City"
- WEBPASSWORD="XXXXXXXXXX" # Change: choose password.
- DNS1=8.8.8.8
- DNS2=8.8.4.4
ports:
- "5353:53/udp" # DNS port
- "8083:80" # Dashboard
volumes:
- pihole_config:/etc/pihole
- pihole_dnsmasq:/etc/dnsmasq.d
networks:
- proxy-net
## VAULTWARDEN
vaultwarden:
image: vaultwarden/server:latest
container_name: vaultwarden
restart: always
labels:
tsdproxy.enable: "true"
tsdproxy.name: "vault"
tsdproxy.ephemeral: "false"
volumes:
- /mnt/data/vaultwarden:/data # Change: choose your location
environment:
- WEBSOCKET_ENABLED=true
- SIGNUPS_ALLOWED=true
ports:
- "8081:80" # Publicar puerto 80 del contenedor en el puerto 8081 del host
networks:
- proxy-net
## DASHY
dashy:
image: lissy93/dashy:latest
container_name: dashy
restart: always
labels:
tsdproxy.enable: "true"
tsdproxy.name: "dashy"
tsdproxy.ephemeral: "false"
ports:
- "8082:8080" # Dashboard
volumes:
- dashy_config:/config
networks:
- proxy-net
## PDF
stirling-pdf:
image: docker.stirlingpdf.com/stirlingtools/stirling-pdf:latest
container_name: stirling-pdf
labels:
tsdproxy.enable: "true"
tsdproxy.name: "pdf"
tsdproxy.ephemeral: "false"
ports:
- 8084:8080
volumes:
- StirlingPDF_trainingData:/usr/share/tessdata # Required for extra OCR languages
- StirlingPDF_extraConfigs:/configs
- StirlingPDF_customFiles:/customFiles/
- StirlingPDF_logs:/logs/
- StirlingPDF_pipeline:/pipeline/
environment:
- DOCKER_ENABLE_SECURITY=false
- LANGS=en_US
networks:
- proxy-net
## CALIBRE WEB
calibre-web:
image: lscr.io/linuxserver/calibre-web:latest
container_name: calibre-web
labels:
tsdproxy.enable: "true"
tsdproxy.name: "books"
tsdproxy.ephemeral: "false"
environment:
- PUID=1000
- PGID=1000
- TZ=Etc/UTC
- DOCKER_MODS=linuxserver/mods:universal-calibre #optional
- OAUTHLIB_RELAX_TOKEN_SCOPE=1 #optional
volumes:
- calibre_data:/config
- /mnt/data/calibre/library:/books
ports:
- 8085:8083
restart: unless-stopped
networks:
- proxy-net
volumes:
tsdproxy_data:
name: tsdproxy-data
tsdproxy_config:
name: tsdproxy-config
nextcloud_aio_mastercontainer:
name: nextcloud_aio_mastercontainer # This line cannot be changed.
dashy_config:
name: dashy_config
pihole_config:
name: pihole_config
pihole_dnsmasq:
name: pihole_dnsmasq
calibre_data:
name: calibre_data
StirlingPDF_trainingData:
name: StirlingPDF_trainingData
StirlingPDF_extraConfigs:
name: StirlingPDF_extraConfigs
StirlingPDF_customFiles:
name: StirlingPDF_customFiles
StirlingPDF_logs:
name: StirlingPDF_logs
StirlingPDF_pipeline:
name: StirlingPDF_pipeline
networks:
proxy-net:
name: proxy-net
driver: bridge
nextcloud-aio:
external: true # Use the existing Nextcloud network
1. Run with sudo docker compose up -d
2. Then stop all using sudo docker compose down
3. Inspect the tsdproxy config volume using: sudo docker volume ls
4. Then inspect the container using: sudo docker volume inspect
tsdproxy-config, you'll see the config docker dir.
5. Enter into root using sudo su and then cd
/var/lib/docker/volumes/tsdproxy-config/_data. Check current files
using ls, you'll see a file called tsdproxy.yaml.
6. Then edit tsdproxy.yaml and add into files::
media:
filename: /config/media.yaml
defaultProxyProvider: default
defaultProxyAccessLog: false
7. Save it. Now create a new file in the working dir
(/var/lib/docker/volumes/tsdproxy-config/_data) named media.yaml and
add:
nextcloud:
url: http://nextcloud-aio-apache:11000
8. Save it. You're good to go! You'll see
—
Reply to this email directly, view it on GitHub
<#5439 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/BMKVEZZN24AWSF7KE2VFCO32V6LZZAVCNFSM6AAAAABQGBXP2KVHI2DSMVQWIX3LMV43URDJONRXK43TNFXW4Q3PNVWWK3TUHMYTENJZG43DINI>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
I now can start my Nextcloud. Thanks guy. |
Beta Was this translation helpful? Give feedback.
-
Awesome guide—really well documented... Appreciate the efforts! 🙌 Even I got everything up and running (learned about docker and everything.. 3 weeks ago.. hah), but I’m struggling with local (as in not via tailscale/internet) access since it seems somehow impossible to reach Nextcloud directly from the LAN. I tried setting up a local DNS entry in pihole ( Also, performance over Tailscale is really slow and sometimes unresponsive, especially on Android using the nextcloud client (shows no internet, then works but sluggishly). Not sure if this is expected or if I'm doing something wrong. (despite fiber-optics inet access) Any pointers? Would love your guys insights—thanks again for putting this together! 🚀 But... in this state its kinda useless to be completely frank.. haha 😅 |
Beta Was this translation helpful? Give feedback.
-
Got AIO working with Tailscale based on cristo357's approachI finally managed to get Nextcloud AIO working with Tailscale subdomains by following the approach described by cristo357. Here's how I did it. 1. Get a Tailscale auth keyFirst, obtain an auth key from Tailscale by going to Settings → Keys → Auth Keys. IMPORTANT: Make sure to create it as "Reusable" or it will stop working after a single use. 2. Create the required Docker networksdocker network create tsdproxy_default
docker network create nextcloud_aio_network 3. Set up tsdproxyCreate a services:
tsdproxy:
image: almeidapaulopt/tsdproxy:latest
container_name: tsdproxy
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./tsdproxy_data:/data
- ./tsdproxy_config:/config
environment:
- TSDPROXY_AUTHKEY=tskey-auth-xxxxxx-xxxxxxx # Change this
- DOCKER_HOST=unix:///var/run/docker.sock
restart: unless-stopped
ports:
- "8086:8080" # For the control panel (accessible from any interface)
networks:
- tsdproxy_default
- nextcloud_aio_network
networks:
tsdproxy_default:
external: true
nextcloud_aio_network:
external: true Note: "latest" works as of April 1, 2025. If it doesn't work, try the tag "almeidapaulopt/tsdproxy:1.4.7" Start the container: docker compose up -d If successful, two new folders should be created: 4. Configure the Proxy ListNow we need to configure a Proxy List so that when we launch the Nextcloud container, it can generate the subdomain. Adding a label to the AIO docker-compose doesn't work since we only have a container launcher. We need to interact with the Apache container on port 11000, and we can't do that by editing the AIO compose file. This part took me many hours to understand. More information about Proxy Lists can be found at https://almeidapaulopt.github.io/tsdproxy/docs/list/ Edit the newly created configuration file: nano tsdproxy_config/tsdproxy.yaml And set it up like this: defaultproxyprovider: default
docker:
local:
host: unix:///var/run/docker.sock
targethostname: 172.31.0.1
files:
media:
filename: /config/media.yaml
defaultProxyProvider: default
defaultProxyAccessLog: false
tailscale:
providers:
default:
authkey: tskey-auth-xxxxx-xxxxxx
controlurl: https://controlplane.tailscale.com
datadir: /data/
http:
hostname: 0.0.0.0
port: 8080
log:
level: info
json: false
proxyaccesslog: true Basically, we've added the "media" section. Now create the nextcloud:
url: http://nextcloud-aio-apache:11000 This will make our subdomain "nextcloud.tailcxxxxx.ts.net" and we'll see a service with that name in our Tailscale network. 5. Start the proxyIf you want to verify that the proxy is working properly, at least the general part, you can run: docker run -d --name sample-nginx -p 8111:80 --label "tsdproxy.enable=true" nginx:latest This will start a test nginx instance. If you access your tailnet network on port 8086, you should see the proxy dashboard, along with the nginx button. Clicking the button should open nginx from its subdomain. 6. Set up Nextcloud AIOCreate the Nextcloud folder and add the compose file: services:
nextcloud-aio-mastercontainer:
image: nextcloud/all-in-one:latest
container_name: nextcloud-aio-mastercontainer
init: true
restart: always
volumes:
- nextcloud_aio_mastercontainer:/mnt/docker-aio-config
- /var/run/docker.sock:/var/run/docker.sock:ro
ports:
- "8080:8080"
environment:
- NEXTCLOUD_DATADIR=/mnt/external/nextcloud
- APACHE_PORT=11000
- APACHE_IP_BINDING=0.0.0.0
- APACHE_ADDITIONAL_NETWORK=tsdproxy_default
- SKIP_DOMAIN_VALIDATION=true
- DISABLE_IP_RESTRICTIONS=true
- NEXTCLOUD_MOUNT=/mnt/external
networks:
- nextcloud_aio_network
volumes:
nextcloud_aio_mastercontainer:
name: nextcloud_aio_mastercontainer
networks:
tsdproxy_default:
name: tsdproxy_default
driver: bridge
nextcloud_aio_network:
external: true Launch it and it should open the container configuration menu. After starting them, it should work. TroubleshootingIf it doesn't work, check these things:
In my case, the problem was that I was applying the labels to the AIO container, and I spent many hours until I understood that they needed to be applied to the Apache container, which was impossible to do directly. You have to configure the media from the proxy. The second problem I had was with "nextcloud-1", which made any configuration attempt unsuccessful. It's possible that the compose files can be simplified with fewer configuration options, but this worked for me.
|
Beta Was this translation helpful? Give feedback.
-
I'm new to docker, trailscale, coding, self-hosting, etc.....
I'm sorry to ask such basic questions. I've been trying to research all of this but I'm keep getting links that take me back to this page. |
Beta Was this translation helpful? Give feedback.
-
This was working for me just last week on a VM that I scrapped. Trying it again today and it's creating a bunch of nextcloud machine clones. Tried a handful of times but the same issue, so I'm confused. One difference was this time the tailscale and caddy container had a "-1" at the end |
Beta Was this translation helpful? Give feedback.
-
This was the only setup I could get to work to even load into nextcloud-aio, my question is if nextcloud and ccollabora aren't communicating re: "failed to connect to remote server" error, could this mean that we need additional arguments in the Docker-Compose and CaddyFile to add the collabora sever for communication something like
Or is it possible collabora needs to be added to tailscale the same way nextcloud is with its own tag? |
Beta Was this translation helpful? Give feedback.
-
I've made it through the first three steps. My containers and tailscale are up and running. But how do I proceed from here?
|
Beta Was this translation helpful? Give feedback.
-
I need help connecting to http://localhost:8080 on my old laptop being used a testing bench. I want to get this running to get a feel on it before i apply it on a stronger pc for the actual home server. Laptop: Windows 10, i5 3rd Gen, 256GB Storage, 4GB RAM I was able to follow the steps here until the Nextcloud AIO Provision all containers were up and running (green) but when I tried to open Nextcloud following the Provision, localhost:8080 doesnt load. After a few troubleshooting with chatgpt, it was seen that Caddy and apache container are not connecting properly. Apache is giving a bad gateway and when i try doing Chatgpt's solution which is to connect the two manually, It displays the same thing in which i am now in a loop and i don't know what else to do now. |
Beta Was this translation helpful? Give feedback.
-
I have done everything till step 4. When I navigate to my Nextcloud's domain i.e. Tailscale's domain, the domain does not respond. To troubleshoot, I ran the following commands and got this response: docker logs nexcloud-aio-nextcloud
docker logs containers-nextcloud-aio-caddy-1
Could someone please help me? Thanks. |
Beta Was this translation helpful? Give feedback.
-
How can I publish this to the internet using Tailscale funnels? I've tried following the exact guide above and it works inside my tailnet network, but I tried "tailscale funnel --bg https://localhost:80" and the same with 443 inside the tailscale container, as well as on the server itself to publish the website, but the website doesn't seem to work (it gives http 502 when doing it inside the Tailscale container and just straight up doesn't seem to find the website when trying to make the funnel on the host) |
Beta Was this translation helpful? Give feedback.
-
Disclaimer: It might be possible that the config below is not working 100% correctly, yet. Improvements to it are very welcome!
This setup integrates Nextcloud All-in-One (AIO) with Tailscale, using Caddy as a reverse proxy.
Since Tailscale currently only allows communication with localhost(127.0.0.1), we use a sidecar with Caddy to communicate with AIO.
serve.json
configuration (This document does not provide an example ofserve.json
)1. Set Environment Variables
Set the following environment variables:
Note
We will not create a .env file, but instead write directly into the compose.yml file later.
If you do create a .env file, compose will automatically read it. In this case, set the key-value format in service[].environment[] of the compose.yml to keys only, allowing compose to pass variables to the service.
Ensure NC_DOMAIN is in the correct format.
When using OAuth client key, set tags in TS_EXTRA_ARGS and define them in ACL.
For more detailed information, please refer to:
https://tailscale.com/blog/docker-tailscale-guide
2. Configure Docker Compose File
Create a compose.yml file with the following content. Replace environment variables as appropriate.
compose.yml
Important
Make sure to replace
NC_DOMAIN
,TS_HOSTNAME
,TS_AUTH_KEY
, andTS_EXTRA_ARGS
with your actual values before running the docker compose file.3. Create Caddyfile and Caddy.Dockerfile
Create a Caddyfile in the current directory with the following content:
Caddyfile
Note
Do not manually replace the
{$NC_DOMAIN}
variable. It will be automatically populated with the value set in your environment variables.Create Caddy.Dockerfile
4. Set Up Nextcloud AIO
docker compose up --build --wait
anddocker compose logs --follow
https://$NC_DOMAIN/
(e.g., https://nextcloud.your-tailnet.ts.net/)If it doesn't work
Please try the following:
Docker Reset Commands
If things don't work, use the following commands to reset
Caution
Only use this if nothing else works.
CLICK!
After force stopping, check that the Nextcloud entry is no longer visible in the Tailscale admin console

Thank you for your advice, frazar
Beta Was this translation helpful? Give feedback.
All reactions