Nextcloud, tailscale+Cloudflare as DNS and Caddy as reverse proxy

[INTRODUCTION]
Hello Nextcloud community and developers. I have setup my Nextcloud server locally on my server at home using proxmox VM and LXCs by following this guide (Nextcloud Installationsanleitung Hub 9 - Carsten Rieger IT-Services). Most of the time I search and learnt that it is dangerous to expose a home-server to public internet. With that I found a solution using Tailscale network (https://tailscale.com) to access remotely in a secure way along caddy as reverse proxy with cloudflare-dns-module (https://caddyserver.com) and cloudflare (https://cloudflare.com) as DNS. This solution does not need any port forwarding and SSL cert generation manually as caddy resolve itself. (however I generate SSL) This idea is currently taken from Tailscale YouTube channel presented by Alex Kretzschmar (Alex Kretzschmar (@ironicbadger@techhub.social) - TechHub) & (https://www.youtube.com/@Tailscale)

[/details]

  1. Nextcloud version [Nextcloud Hub 9 (30.0.1)]
  2. Operating system and version Proxmox VM (Ubuntu 24.04) Local home-server
  3. nginx version (1.27.2)
  4. PHP version (8.3)
  5. Caddy with dns-cloudflare-module (on proxmox LXC-1001)
  6. Tailscale (on proxmox LXC-1001) & (Ubuntu 24.04) Local home-server)
  7. Cloudflare DNS for managing DNS records and API
    Note Tailscale is also installed in Proxmox VM ((Ubuntu 24.04) Local home-server) in which Nextcloud, nginx, PHP are running. This mean, I have 1x VM and 1x LXC both with Tailscale installed. Moreover, Caddy LXC is the name of my proxmox LXC in which caddy and tailscale are installed. Avoid confusion, please

[The issue I am facing]
During Nextcloud installation, I request and create Let’s Encrypt certificates (RSA 4096) without opening TCP ports 80 and 443 (Let's Encrypt Zertifikate (RSA 4096 oder EC 384) ohne offene TCP-Ports 80 und 443 beantragen und erstellen - Carsten Rieger IT-Services) because my ISP has blocked almost all my ports. I am using a domestic internet service which doesn’t allow any port forwarding and static public ip. After setting up my Nextcloud server, nextcloud.conf, config.php, nginx.conf and allowed trusted domains and IP addresses. Now I can only access to my newly created Nextcloud server through IP address but not via domain.
I am also sure that my caddy reverse proxy which is in LXC doesn’t communicate. This may be due to miss configuration. I am putting all the .conf, .config and Caddyfile commands in order to analyze by the community to rectify the error I made.

[The output of /etc/nginx/nginx.conf] file

user www-data;
worker_processes auto;
pid /var/run/nginx.pid;
events {
  worker_connections 2048;
  multi_accept on;
  use epoll;
  }
http {
  log_format criegerde escape=json  # *criegerde not know to me why I put this. Assist if need amendment, please
  '{'
    '"time_local":"$time_local",'
    '"remote_addr":"$remote_addr",'
    '"remote_user":"$remote_user",'
    '"request":"$request",'
    '"status": "$status",'
    '"body_bytes_sent":"$body_bytes_sent",'
    '"request_time":"$request_time",'
    '"http_referrer":"$http_referer",'
    '"http_user_agent":"$http_user_agent"'
  '}';
  server_names_hash_bucket_size 64;
  access_log /var/log/nginx/access.log criegerde;   # *criegerde
  error_log /var/log/nginx/error.log warn;
  set_real_ip_from 100.110.210.310 192.168.10.20;   #1st IP is of caddy lxc tailscale which run inside the caddy lxc and 2nd IP is actual IP address of caddy LXC container.
  real_ip_header X-Forwarded-For;
  real_ip_recursive on;
  include /etc/nginx/mime.types;
  default_type application/octet-stream;
  sendfile on;
  send_timeout 3600;
  tcp_nopush on;
  tcp_nodelay on;
  open_file_cache max=500 inactive=10m;
  open_file_cache_errors on;
  keepalive_timeout 65;
  reset_timedout_connection on;
  server_tokens off;
  resolver 1.1.1.1 1.0.0.1 valid=30s;  # as of cloudflare DNS, assist if need amendment, please
  resolver_timeout 5s;
  include /etc/nginx/conf.d/*.conf;

[The output of /var/www/nextcloud/config/config.php] file

<?php
$CONFIG = array (
  'instanceid' => 'XXXXXX,
  'passwordsalt' => 'XXXXXXXXXXXXXXXXXXX',
  'secret' => 'XXXXXXXXXXXXXXXXXXXXXXXXXXX',
  'trusted_domains' => 
  array (
    0 => 'nc.example.com',
    1 => '192.168.10.123',   # Local IP address of my local Ubuntu home-server installed in Proxmox as VM
    2 => 'nc.shee-foo.ts.net',   # Tailscale domain address/name of the installed on local Ubuntu home-server in Proxmox as VM
    3 => '100.80.170.11',   # tailscale IP address of the above domain
  ),
  'datadirectory' => '/var/nc_data',
  'dbtype' => 'xxxx',
  'version' => 'xx.xx.x',
  'overwrite.cli.url' => 'http://localhost',   # when I put 'https://nc.example.com', I cannot even access my Nextcloud server via IP address
  'dbname' => 'nextclouddb',
  'dbhost' => 'localhost',
  'dbport' => '',
  'dbtableprefix' => 'oc_',
  'mysql.utf8mb4' => true,
  'dbuser' => 'nc',
  'dbpassword' => 'XXXXX',
  'installed' => true,
//  'overwritehost' => 'nc.example.com',   # when // I can access my Nextcloud server with IP address otherwise not
  'activity_expire_days' => 14,
  'allow_local_remote_servers' => true,
  'auth.bruteforce.protection.enabled' => true,
  'forbidden_filenames' => 
  array (
    0 => '.htaccess',
    1 => 'Thumbs.db',
    2 => 'thumbs.db',
  ),
  'cron_log' => true,
  'default_phone_region' => 'OF',
'enable_previews' => true,
  'enabledPreviewProviders' => 
  array (
    0 => 'OC\\Preview\\PNG',
    1 => 'OC\\Preview\\JPEG',
    2 => 'OC\\Preview\\GIF',
    3 => 'OC\\Preview\\BMP',
    4 => 'OC\\Preview\\XBitmap',
    5 => 'OC\\Preview\\Movie',
    6 => 'OC\\Preview\\PDF',
    7 => 'OC\\Preview\\MP3',
    8 => 'OC\\Preview\\TXT',
    9 => 'OC\\Preview\\MarkDown',
    10 => 'OC\\Preview\\HEIC',
    11 => 'OC\\Preview\\Movie',
    12 => 'OC\\Preview\\MKV',
    13 => 'OC\\Preview\\MP4',
    14 => 'OC\\Preview\\AVI',
  ),
  'filesystem_check_changes' => 0,
  'filelocking.enabled' => 'true',
  'htaccess.RewriteBase' => '/',
  'integrity.check.disabled' => false,
  'knowledgebaseenabled' => false,
  'log_rotate_size' => '104857600',
  'logfile' => '/var/log/nextcloud/nextcloud.log',
  'loglevel' => 2,
  'logtimezone' => 'Europe/Paris',
  'memcache.local' => '\\OC\\Memcache\\APCu',
  'memcache.locking' => '\\OC\\Memcache\\Redis',
  'overwriteprotocol' => 'https',
  'preview_max_x' => 1024,
  'preview_max_y' => 768,
  'preview_max_scale_factor' => 1,
  'profile.enabled' => false,
 'redis' => 
  array (
    'host' => '/var/run/redis/redis-server.sock',
    'port' => 0,
    'password' => 'XXXXXXX',
    'timeout' => 0.5,
    'dbindex' => 1,
  ),
  'quota_include_external_storage' => false,
  'share_folder' => '/Freigaben',
  'skeletondirectory' => '',
  'trashbin_retention_obligation' => 'auto, 7',
  'maintenance_window_start' => 1,
  'maintenance' => false,
);

[The output of /etc/nginx/conf.d/nextcloud.conf] file

limit_req_zone $binary_remote_addr zone=NextcloudRateLimit:10m rate=2r/s;
server {
listen 443      ssl default_server;
listen [::]:443 ssl default_server;
http2 on;
server_name nc.example.com;
ssl_certificate /etc/letsencrypt/live/nc.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/nc.example.com/privkey.pem;
#ssl_certificate /etc/letsencrypt/ecc-certs/fullchain.pem;
#ssl_certificate_key /etc/letsencrypt/ecc-certs/privkey.pem;
#ssl_trusted_certificate /etc/letsencrypt/ecc-certs/chain.pem;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
ssl_protocols TLSv1.3 TLSv1.2;
ssl_ciphers 'TLS-CHACHA20-POLY1305-SHA256:TLS-AES-256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA38>
ssl_ecdh_curve X448:secp521r1:secp384r1;
ssl_prefer_server_ciphers on;
ssl_stapling on;
ssl_stapling_verify on;
client_max_body_size 10G;
client_body_timeout 3600s;
client_body_buffer_size 512k;
fastcgi_buffers 64 4K;
gzip on;
gzip_vary on;
gzip_comp_level 4;
gzip_min_length 256;
gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
gzip_types application/atom+xml text/javascript application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.g>
add_header Strict-Transport-Security            "max-age=15768000; includeSubDomains; preload;" always;
add_header Permissions-Policy                   "interest-cohort=()";
add_header Referrer-Policy                      "no-referrer"   always;
add_header X-Content-Type-Options               "nosniff"       always;
add_header X-Download-Options                   "noopen"        always;
add_header X-Frame-Options                      "SAMEORIGIN"    always;
add_header X-Permitted-Cross-Domain-Policies    "none"          always;
add_header X-Robots-Tag                         "noindex, nofollow" always;
add_header X-XSS-Protection                     "1; mode=block" always;
fastcgi_hide_header X-Powered-By;
include mime.types;
types {
text/javascript mjs;
}
root /var/www/nextcloud;
index index.php index.html /index.php$request_uri;
location = / {
if ( $http_user_agent ~ ^DavClnt ) {
return 302 /remote.php/webdav/$is_args$args;
}
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
location ^~ /.well-known {
location = /.well-known/carddav { return 301 /remote.php/dav/; }
location = /.well-known/caldav  { return 301 /remote.php/dav/; }
location /.well-known/acme-challenge { try_files $uri $uri/ =404; }
location /.well-known/pki-validation { try_files $uri $uri/ =404; }
return 301 /index.php$request_uri;
}
location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/)  { return 404; }
location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console)                { return 404; }
location ~ \.php(?:$|/) {
rewrite ^/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|ocs-provider\/.+|.+\/richdocumentscode\/proxy) /index.php$request_uri;
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
set $path_info $fastcgi_path_info;
try_files $fastcgi_script_name =404;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $path_info;
fastcgi_param HTTPS on;
fastcgi_param modHeadersAvailable true;
fastcgi_param front_controller_active true;
fastcgi_pass php-handler;
fastcgi_intercept_errors on;
fastcgi_request_buffering off;
fastcgi_read_timeout 3600;
fastcgi_send_timeout 3600;
fastcgi_connect_timeout 3600;
fastcgi_max_temp_file_size 0;
}
location ~ \.(?:css|js|mjs|svg|gif|png|jpg|ico|wasm|tflite|map|ogg|flac)$ {
try_files $uri /index.php$request_uri;
add_header Cache-Control "public, max-age=15778463, $asset_immutable";
expires 6M;
access_log off;
location ~ \.wasm$ {
default_type application/wasm;
}
}
location ~ \.woff2?$ {
try_files $uri /index.php$request_uri;
expires 7d;
access_log off;
}
location /remote {
return 301 /remote.php$request_uri;
}
location /login {
limit_req zone=NextcloudRateLimit burst=5 nodelay;
limit_req_status 429;
try_files $uri $uri/ /index.php$request_uri;
}
location / {
try_files $uri $uri/ /index.php$request_uri;
}
}

[The output of /etc/nginx/conf.d/http.conf] file

    server unix:/run/php/php8.3-fpm.sock;
}

map $arg_v $asset_immutable {
    "" "";
    default "immutable";
}

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name nc.example.com 192.168.10.123;   # IP address of my local Ubuntu home-server on which Nextcloud is installed
    root /var/www;

    location / {
        return 301 https://$host$request_uri;
    }
}


[The output of /etc/hosts] file

127.0.0.1 localhost
127.0.1.1 nc.example.com nc

# The following lines are desirable for IPv6 capable hosts
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

[The output of /etc/hostname] file

nc.example.com

[The output of Caddyfile]

(cloudflare) {
  tls {
    dns cloudflare <api_token>
  }
}

# nextcloud
https://nc.shee-foo.ts.net {      #Tailscale domain of Ubuntu home-server which is already made trusted
  reverse_proxy 192.168.10.123:80   # IP of ubuntu home-server on Proxmox VM on which nextcloud, PHP and nginx webserver is running
  import cloudflare
}

[Closing remarks]
Having the detailed output of my Nextcloud server, it is requested to the community and developers to please have your analysis and guide me, PLEASE

Regards

Need assistance kindly

you are doing many uncommon things this might be a reason why nobody can help. tailscale itself add useless complexity and looks hard to troubleshoot. Please review New AiO installation behind caddy and tailscale, Collabora not connecting? with a similar setup maybe you can learn something…

otherwise go through your communication chain and troubleshoot one step after another - dns resolution, connectivity, logs - this will result in good understand where requests are failing and you can focus at this equipment.

1 Like

I will say, I’m currently having an issue with my setup where the app lags on backspace for some reason, I made a post here https://forum.collaboraonline.com/t/collabora-backspace-on-existing-text-lagging-in-apps/3069/5 but am currently unsure of how to proceed.

maybe I’m wrong but I would expect it is not only backspace fails but many other “interactive” functions like text formatting. If this is the case I would assume websocket is not working right which is required for bi-directional communication between client and server and absolutely required for WYSIWYG experience. a look into the browser console could help.

I’m not sure what you mean about the browser console, but here, I made a video of it not responding to repeat backspaces of existing text, but all other formatting works. https://youtube.com/shorts/Qj7kidSlt9c?feature=share

I can reproduce this on three instances:

  • A manual installation using the CODE docker container.
  • A manual installation using the built-in CODE server
  • An AIO instance

It only happens on mobile (browser and app), not on desktop browsers, tested on a Pixel 7 running Android 15 and Nextcloud app version 3.30.3.

Oh, and I’m not using Cloudflare or any kind of tunnel or reverse proxy in front of these instances.

2 Likes

interesting… my Docker-based instance works fine on Pixel 9 with Firefox and Chrome! but I use traefik as reverse proxy I think it is less restrictive from the beginning.

Ah, yes, it’s just the Nextcloud app that struggles on mobile. Browser works fine, My users and I just prefer the layout of the app, which is unfortunate because without backspace it’s effectively unusable.

in your video you are edit an .odt file which is done using office app (richdocumentsapp+CODE).
technically It has very little to do with the Nextcloud app and works in my scenario on a Pixel both in the browser and from NC app. funny that you seem to share the problem with bb77 while it doesn’t manifest for me :grin: I would suggest you both compare your infrastructure to find the common part which might cause an issue. my guess would be reverse proxy as bb77 doesn’t use tunnel like tailscale.

@wwe I’m confused, it shows it editing in nextcloud, I don’t have the collabora or “office” app installed on my mobile. Does mobile client need something else installed?


Otherwise, editing .docx results in the same behavior. What filetype do you prefer?

@bb77 I recently posted my most up to date config here
basically for reverse proxy I just do

      https://nextcloud.wallaby-gopher.ts.net {
        bind tailscale/nextcloud
        reverse_proxy host.docker.internal:11000
        }
      https://collabora.wallaby-gopher.ts.net {
        bind tailscale/collabora
        reverse_proxy collabora:9980
        }

In that thread someone posted a link to a tailscale guide. It’s not scalable like mine without caddy-tailscale so it’s fairly different.

They reverse proxied straight to apache instead of the host.docker.internal and include :443 which I’ve been told is incorrect so I’m suspicious of their method.

https://{$NC_DOMAIN}:443 {
    reverse_proxy nextcloud-aio-apache:11000
}

Some other changes I identified that I’m not sure of the implications is they set init: true and the ports to 0.0.0.0:8080:8080 and the APACHE_IP_BINDING: 127.0.0.1 in the nextcloud compose.

There is no “editing in Nextcloud”! “Nextcloud Office” as marketing term which technically consists of

allows editing office files online. This is what happens behind the scenes - no need of additional (mobile) apps, everything happens online on your server but your need reliable connectivity. This is the reason why I assume an issue within the connectivity path.

Tailscale (and Caddy as a sidecar) Reverse Proxy · nextcloud/all-in-one · Discussion #5439 · GitHub this guide work perfectly

So I went to follow their guide, but integrating it with tailscale-caddy and their hardened network seems to break things specifically in that nextcloud-aio-apache is inaccessible:

configs:
  Caddyfile:
    content: |
      {
        tailscale {
          state_dir /tailscale
        }
      }
      https://jellyfin.wallaby-gopher.ts.net: {
        bind tailscale/jellyfin
        reverse_proxy jellyfin:8096
      }
      https://nextcloud.wallaby-gopher.ts.net:443 {
        bind tailscale/nextcloud
        reverse_proxy nextcloud-aio-apache:11000
        }
        #changing from host.docker.internal
      https://collabora.wallaby-gopher.ts.net {
        bind tailscale/collabora
        reverse_proxy collabora:9980
        }
      https://books.wallaby-gopher.ts.net {
        bind tailscale/books
        reverse_proxy audiobookshelf:80
        }
      https://jellyseerr.wallaby-gopher.ts.net {
        bind tailscale/jellyseerr
        reverse_proxy jellyseerr:5055
        }
      https://food.wallaby-gopher.ts.net {
        bind tailscale/food
        reverse_proxy food:9000
        }

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

volumes:
  nextcloud_aio_mastercontainer:
    name: nextcloud_aio_mastercontainer # This line is not allowed to be changed
  #caddy/tailscale configs
  caddy:
  tailscale:
  #live tv cabernet
  cabernet-data:
  cabernet-plugin:
  cabernet-secrets:
  #jellyfin
  jellyconfig:
  jellycache:
  #jellyseer
  jellyseerr-data:
  #audiobookshelf
  audioc:
  audiom:
  #mealie recipes
  mealie-data:
  #email
  thunderbird:
  protonmail:
services:

  #for recipes
  food:
    image: ghcr.io/mealie-recipes/mealie:v2.0.0 #
    container_name: food
    restart: always
    deploy:
      resources:
        limits:
          memory: 1000M #
    volumes:
      - mealie-data:/app/data/
    environment:
      # Set Backend ENV Variables Here
      ALLOW_SIGNUP: "false"
      PUID: 1000
      PGID: 1000
      TZ: America/Chicago
      MAX_WORKERS: 1
      WEB_CONCURRENCY: 1
      BASE_URL: https://food.wallaby-gopher.ts.net

  #for local emails
  thunderbird:
    image: jlesage/thunderbird
    ports:
      - "5800:5800"
    volumes:
      - thunderbird:/config:rw
    restart: unless-stopped

  #for thunderbird to get protonmail
  protonmail-bridge:
    image: shenxn/protonmail-bridge
    ports:
      - 1025:25/tcp
      - 1143:143/tcp
    restart: unless-stopped
    volumes:
      - protonmail:/root

  #jellyfin live tv
  cabernet:
    container_name: cabernet
    image: ghcr.io/cabernetwork/cabernet:latest
    environment:
      - TZ="America/Chicago"  # Timezone (Optional)
      - PUID=1000     # UserID (Optional)
      - PGID=1000     # GroupID (Optional)
    ports:
      - "6077:6077"    # Web Interface Port
      - "5004:5004"    # Port used to stream
    restart: unless-stopped
    volumes:
      - cabernet-data:/app/data                # App data (Optional)
      - cabernet-plugin:/app/plugins_ext  # Plugins Data (Optional)
      - cabernet-secrets:/app/.cabernet        # Ecryption key data (Optional)

  #to suggest shows and movies
  jellyseerr:
    image: fallenbagel/jellyseerr:latest
    container_name: jellyseerr
    environment:
      - LOG_LEVEL=debug
      - TZ=America/Chicago
    volumes:
      - jellyseerr-data:/app/config
    restart: unless-stopped

  #to watch shows/movies
  jellyfin:
    image: jellyfin/jellyfin
    user: 1000:1000
    volumes:
      #- /media/server/server/jellyfin-server/config:/config
      - jellyconfig:/config
      #- /media/server/server/jellyfin-server/cache:/cache
      - jellycache:/cache
      # ro means read only, we don't want jellyfin accidentally deleting our files
      - /media/16d1/Shows and Movies/Movies:/Movies:ro
      - /media/16d1/Shows and Movies/Shows:/Shows:ro
      #- /media/16tb/Books:/Books:ro
      - /home/drm/Music:/music:ro
    restart: unless-stopped
    runtime: nvidia
    deploy:
      resources:
        reservations:
          devices:
            - capabilities: [gpu]
    depends_on:
      - caddy


  #audiobooks, does better than Kavita for ebooks too
  audiobookshelf:
    image: ghcr.io/advplyr/audiobookshelf
    volumes:
      - /media/16d1/Books/Audiobooks:/audiobooks
      - /media/16d1/Books:/books
      #- </path/to/podcasts>:/podcasts
      - audioc:/config
      - audiom:/metadata
    environment:
      - TZ=America/Chicago
    restart: unless-stopped

  caddy:
    build:
        dockerfile_inline: |
          FROM caddy:2-builder AS builder
          RUN xcaddy build latest \
            --with github.com/tailscale/caddy-tailscale
          FROM caddy:2
          COPY --from=builder /usr/bin/caddy /usr/bin/caddy
    hostname: caddy
    init: true
    container_name: "caddy"
    networks:
      - nextcloud-aio
    extra_hosts:
      - "host.docker.internal:host-gateway"
    ports:
      - "80:80"
      - "443:443"
      - "443:443/udp"
    volumes:
      - caddy:/data
      - tailscale:/tailscale
    configs:
      - source: Caddyfile
        target: /etc/caddy/Caddyfile
    restart: unless-stopped


  #nextcloud
  nextcloud:
    image: nextcloud/all-in-one
    init: true #not sure what this does
    restart: always
    networks:
      - nextcloud-aio
    container_name: nextcloud-aio-mastercontainer # This line is not allowed to be changed as otherwise AIO will not work correctly
    volumes:
      - nextcloud_aio_mastercontainer:/mnt/docker-aio-config # This line is not allowed to be changed as otherwise the built-in backup solution will not work
      - /var/run/docker.sock:/var/run/docker.sock:ro # May be changed on macOS, Windows or docker rootless. See the applicable documentation. If adjusting, don't forget to also set 'WATCHTOWER_DOCKER_SOCKET_PATH'!
    ports:
      - 0.0.0.0:8080:8080 #added 0's
    environment: # Is needed when using any of the options below
      # - AIO_DISABLE_BACKUP_SECTION=false # Setting this to true allows to hide the backup section in the AIO interface. See https://github.com/nextcloud/all-in-one#how-to-disable-the-backup-section
      #- SKIP_DOMAIN_VALIDATION=true #might not be helping?
      - APACHE_PORT=11000 # Is needed when running behind a web server or reverse proxy (like Apache, Nginx, Cloudflare Tunnel and else). See https://github.com/nextcloud/all-in-one/blob/main/reverse-proxy.md
      - APACHE_IP_BINDING=127.0.0.1 #0.0.0.0 # Should be set when running behind a web server or reverse proxy (like Apache, Nginx, Cloudflare Tunnel and else) that is running on the same host. See https://github.com/nextcloud/all-in-one/blob/main/reverse-proxy.md
      # - BORG_RETENTION_POLICY=--keep-within=7d --keep-weekly=4 --keep-monthly=6 # Allows to adjust borgs retention policy. See https://github.com/nextcloud/all-in-one#how-to-adjust-borgs-retention-policy
      # - COLLABORA_SECCOMP_DISABLED=false # Setting this to true allows to disable Collabora's Seccomp feature. See https://github.com/nextcloud/all-in-one#how-to-disable-collaboras-seccomp-feature
      # - NEXTCLOUD_MOUNT=/mnt/ # Allows the Nextcloud container to access the chosen directory on the host. See https://github.com/nextcloud/all-in-one#how-to-allow-the-nextcloud-container-to-access-directories-on-the-host
      - NEXTCLOUD_UPLOAD_LIMIT=1G # Can be adjusted if you need more. See https://github.com/nextcloud/all-in-one#how-to-adjust-the-upload-limit-for-nextcloud
      - NEXTCLOUD_MAX_TIME=3600 # Can be adjusted if you need more. See https://github.com/nextcloud/all-in-one#how-to-adjust-the-max-execution-time-for-nextcloud
      - NEXTCLOUD_MEMORY_LIMIT=1024M # Can be adjusted if you need more. See https://github.com/nextcloud/all-in-one#how-to-adjust-the-php-memory-limit-for-nextcloud
      # - NEXTCLOUD_TRUSTED_CACERTS_DIR=/path/to/my/cacerts # CA certificates in this directory will be trusted by the OS of the nexcloud container (Useful e.g. for LDAPS) See See https://github.com/nextcloud/all-in-one#how-to-trust-user-defined-certification-authorities-ca
      # - NEXTCLOUD_ADDITIONAL_APKS=imagemagick # This allows to add additional packages to the Nextcloud container permanently. Default is imagemagick but can be overwritten by modifying this value. See https://github.com/nextcloud/all-in-one#how-to-add-os-packages-permanently-to-the-nextcloud-container
      # - NEXTCLOUD_ADDITIONAL_PHP_EXTENSIONS=imagick # This allows to add additional php extensions to the Nextcloud container permanently. Default is imagick but can be overwritten by modifying this value. See https://github.com/nextcloud/all-in-one#how-to-add-php-extensions-permanently-to-the-nextcloud-container
      # - NEXTCLOUD_ENABLE_DRI_DEVICE=true # This allows to enable the /dev/dri device in the Nextcloud container. ⚠️⚠️⚠️ Warning: this only works if the '/dev/dri' device is present on the host! If it should not exist on your host, don't set this to true as otherwise the Nextcloud container will fail to start! See https://github.com/nextcloud/all-in-one#how-to-enable-hardware-transcoding-for-nextcloud
      - TALK_PORT=3478 # This allows to adjust the port that the talk container is using. See https://github.com/nextcloud/all-in-one#how-to-adjust-the-talk-port
      # - WATCHTOWER_DOCKER_SOCKET_PATH=/var/run/docker.sock # Needs to be specified if the docker socket on the host is not located in the default '/var/run/docker.sock'. Otherwise mastercontainer updates will fail. For macos it needs to be '/var/run/docker.sock'
    depends_on:
      - caddy

  #for nextcloud office to work
  collabora:
    image: collabora/code
    container_name: collaborac
    restart: unless-stopped
    ports:
      - 9980:9980
    environment: #--o:security.capabilities=false did not help with phone backspace either, --o:ssl.termination=true
      - username=admin
      - password=Secret.Password
      - extra_params=--o:ssl.enable=false --o:ssl.termination=true --o:logging.level=debug
      - COLLABORA_SECCOMP_DISABLED=true
      #- dictionaries=en
    cap_add: #- SYS_ADMIN sometimes needed due to permission issue, - CHOWN no difference?
      - MKNOD
      - CAP_CHOWN
    #tty: true
    depends_on:
      - nextcloud



# Steps
#1. run the command: docker-compose up -d
#3. remove the auth key from docker-compose.yaml, save the file, you can keep the container running
#4. run the command: docker-compose up -d


Now I get this error in caddy and nextcloud is inaccessible:

ERR ts=1730740220.0632527 logger=http.log.error msg=dial tcp: lookup nextcloud-aio-apache: i/o timeout request={"remote_ip":"100.91.72.49","remote_port":"58150","client_ip":"100.91.72.49","proto":"HTTP/2.0","method":"POST","host":"nextcloud.wallaby-gopher.ts.net","uri":"/apps/text/session/4/push","headers":{"Accept-Encoding":["gzip, deflate, br, zstd"],"Content-Type":["application/json"],"X-Requested-With":["XMLHttpRequest, XMLHttpRequest"],"Origin":["https://nextcloud.wallaby-gopher.ts.net"],"Sec-Gpc":["1"],"User-Agent":["Mozilla/5.0 (X11; Linux x86_64; rv:131.0) Gecko/20100101 Firefox/131.0"],"Accept":["application/json, text/plain, */*"],"Sec-Fetch-Mode":["cors"],"Content-Length":["85156"],"Sec-Fetch-Dest":["empty"],"Cookie":["REDACTED"],"Te":["trailers"],"Accept-Language":["en-US,en;q=0.5"],"Dnt":["1"],"Requesttoken":["FRzHMM2ygovmnyYSMJ2w6BU7t2yxL8NTS/t1YdVD954=:Wkn/W/XRxv3fzmFGZOWJu1Bo7hyaXqEeMrA9Mo0Rj/Q="],"Sec-Fetch-Site":["same-origin"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"h2","server_name":"nextcloud.wallaby-gopher.ts.net"}} duration=3.00017506 status=502 err_id=u838k7y0c err_trace=reverseproxy.statusError (reverseproxy.go:1269)

it breaks my other apps like jellyfin as well.
I had to comment out that network and remove it after stopping everything with docker network rm because it persisted, breaking access even after commenting networks in nextcloud.

Do not change anything from this guide, otherwise it will not work. Moreover office collabora also didn’t work for me.
You have made everything changed from this guide and expecting that to work. But I must appreciate that you have tried something new, who know you can figure this out along Dev and community help. It will be a new path to run nextcloud AIO. Please try, and update here.

@A4all Regretfully I have no choice but to change items, because I have other services and cannot use just one instance of tailscale for all of them, hence caddy-tailscale.

@wwe I just discovered that .md files have no backspace issue. I think this suggests it’s not a connectivity path issue after all, but file-based. While I could just use markdown, the layout is too minimal on desktop, so not a solution for me. Do you have any idea why it might escape the problem .docx and .odt suffer from?

I’m sorry no idea… I’m not such deep into low level web technology. As I don’t see any issue in my installation it seems to be no generic problem with NC and CODE but rather some product-specific issue “in between” - network, reverse proxy etc… I’m not sure .md editor and CODE are doing exactly the same (e.g. I never heard websockets are required for Markdown editor).

If this important enough for you - start troubleshooting with systematic approach - increase the logs of each component to maximum level and start looking into details. As I suggested already - bb77 suffers from the same issue - I would check where your both instances differ from mine. or you can do the test other way round and setup an instance like mine with a traefik reverse proxy to see if you still hit the problem… it could even be a client problem - everything is possible so far.

In the meantime, I’ve tried a few things and I’m pretty sure my configuration (docker/coolwsd.xml, webserver config etc) is ok.

@rinkfaraway It seems to be related to the keyboard on my phone. I’m using a Pixel 7 with GrapheneOS, which uses the AOSP keyboard, and I’ve just checked with my girlfriend, who’s using a Pixel 6 with stock rom and Gboard, and for her the backspace key is working perfectly fine.

1 Like

For reference, here’s my webserver config / docker run command:

(Manual installation of Nextcloud with Apache and PHP-FPM, using the CODE Docker container)

Webserver Config Nextcloud:

<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName cloud.mydomnain.tld
DocumentRoot /var/www/html/nextcloud

<Directory /var/www/html/nextcloud/>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
Satisfy Any
</Directory>

<IfModule mod_dav.c>
Dav off
</IfModule>

<Directory /var/nextcloud-data/>
Require all denied
</Directory>

<Files ".ht*">
Require all denied
</Files>

RewriteEngine On
RewriteCond %{REQUEST_METHOD} ^TRACK
RewriteRule .* - [R=405,L]

SetEnv HOME /var/www/html/nextcloud
SetEnv HTTP_HOME /var/www/html/nextcloud

<IfModule mod_reqtimeout.c>
RequestReadTimeout body=0
</IfModule>

<IfModule mod_brotli.c>
AddOutputFilterByType BROTLI_COMPRESS text/javascript application/javascript application/x-javascript text/css image/svg+xml
BrotliCompressionQuality 0
</IfModule>

<IfModule mod_headers.c>
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set X-Content-Type-Options "nosniff"
Header always set X-Frame-Options "SAMEORIGIN"
</IfModule>

ProxyPass /push/ws ws://127.0.0.1:7867/ws
ProxyPass /push/ http://127.0.0.1:7867/
ProxyPassReverse /push/ http://127.0.0.1:7867/

ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined

SSLCertificateFile /etc/letsencrypt/live/cloud.mydomnain.tld/fullchain.pem
SSLCACertificateFile /etc/letsencrypt/live/cloud.mydomnain.tld/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/cloud.mydomnain.tld/privkey.pem

SSLEngine on
SSLProtocol -all +TLSv1.2 +TLSv1.3
SSLCipherSuite TLSv1.3 TLS_CHACHA20_POLY1305_SHA256:TLS_AES_256_GCM_SHA384
SSLCipherSuite TLS_CHACHA20_POLY1305_SHA256:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-CHACHA20-POLY1305:DHE-RSA-CHACHA20-POLY1305:PSK-CHACHA20-POLY1305:ECDHE-PSK-CHACHA20-POLY1305:DHE-PSK-CHACHA20-POLY1305:RSA-PSK-CHACHA20-POLY1305:DHE-RSA-AES256-GCM-SHA384:DH-RSA-AES256-GCM-SHA384:DHE-DSS-AES256-GCM-SHA384:DH-DSS-AES256-GCM-SHA384:ADH-AES256-GCM-SHA384:TLS_AES_256_GCM_SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:ECDH-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDH-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-CCM8:DHE-RSA-AES256-CCM:PSK-AES256-CCM:DHE-PSK-AES256-CCM:PSK-AES256-CCM8:DHE-PSK-AES256-CCM8:ECDHE-ECDSA-AES256-CCM:ECDHE-ECDSA-AES256-CCM8
SSLHonorCipherOrder on
SSLCompression off
SSLSessionTickets off
SSLOptions +StrictRequire
SSLOpenSSLConfCmd Curves secp384r1:secp256r1
SSLOpenSSLConfCmd ECDHParameters secp384r1
SSLStaplingResponderTimeout 5
SSLStaplingReturnResponderErrors off
</VirtualHost>
SSLUseStapling on
SSLStaplingCache shmcb:/var/run/ocsp(128000)
</IfModule>

Webserver config Collabora:

<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName office.mydomain.tld

<Location /browser/dist/admin>
Order Deny,Allow
Deny from all
Allow from 192.168.202.202
</Location>

AllowEncodedSlashes NoDecode
SSLProxyEngine On
ProxyPreserveHost On

# cert is issued for collaboraonline.example.com and we proxy to localhost
SSLProxyVerify None
SSLProxyCheckPeerCN Off
SSLProxyCheckPeerName Off

# static html, js, images, etc. served from coolwsd
# browser is the client part of Collabora Online
ProxyPass           /browser https://127.0.0.1:9980/browser retry=0
ProxyPassReverse    /browser https://127.0.0.1:9980/browser

# WOPI discovery URL
ProxyPass           /hosting/discovery https://127.0.0.1:9980/hosting/discovery retry=0
ProxyPassReverse    /hosting/discovery https://127.0.0.1:9980/hosting/discovery

# Capabilities
ProxyPass           /hosting/capabilities https://127.0.0.1:9980/hosting/capabilities retry=0
ProxyPassReverse    /hosting/capabilities https://127.0.0.1:9980/hosting/capabilities

# Main websocket
ProxyPassMatch      "/cool/(.*)/ws$"      wss://127.0.0.1:9980/cool/$1/ws nocanon

# Admin Console websocket
ProxyPass           /cool/adminws wss://127.0.0.1:9980/cool/adminws

# Download as, Fullscreen presentation and Image upload operations
ProxyPass           /cool https://127.0.0.1:9980/cool
ProxyPassReverse    /cool https://127.0.0.1:9980/cool

# Compatibility with integrations that use the /lool/convert-to endpoint
ProxyPass           /lool https://127.0.0.1:9980/cool
ProxyPassReverse    /lool https://127.0.0.1:9980/cool

Header always set Strict-Transport-Security "max-age=63072000"

ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined

SSLCertificateFile /etc/letsencrypt/live/office.mydomain.tld/fullchain.pem
SSLCACertificateFile /etc/letsencrypt/live/office.mydomain.tld/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/office.mydomain.tld/privkey.pem

SSLEngine on
SSLProtocol -all +TLSv1.2 +TLSv1.3
SSLCipherSuite TLSv1.3 TLS_CHACHA20_POLY1305_SHA256:TLS_AES_256_GCM_SHA384
SSLCipherSuite TLS_CHACHA20_POLY1305_SHA256:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-CHACHA20-POLY1305:DHE-RSA-CHACHA20-POLY1305:PSK-CHACHA20-POLY1305:ECDHE-PSK-CHACHA20-POLY1305:DHE-PSK-CHACHA20-POLY1305:RSA-PSK-CHACHA20-POLY1305:DHE-RSA-AES256-GCM-SHA384:DH-RSA-AES256-GCM-SHA384:DHE-DSS-AES256-GCM-SHA384:DH-DSS-AES256-GCM-SHA384:ADH-AES256-GCM-SHA384:TLS_AES_256_GCM_SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:ECDH-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDH-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-CCM8:DHE-RSA-AES256-CCM:PSK-AES256-CCM:DHE-PSK-AES256-CCM:PSK-AES256-CCM8:DHE-PSK-AES256-CCM8:ECDHE-ECDSA-AES256-CCM:ECDHE-ECDSA-AES256-CCM8
SSLHonorCipherOrder on
SSLCompression off
SSLSessionTickets off
SSLOptions +StrictRequire
SSLOpenSSLConfCmd Curves secp384r1:secp256r1
SSLOpenSSLConfCmd ECDHParameters secp384r1
SSLStaplingResponderTimeout 5
SSLStaplingReturnResponderErrors off
</VirtualHost>
SSLUseStapling on
SSLStaplingCache shmcb:/var/run/ocsp(128000)
</IfModule>

Docker run command:

docker run -t -d -p 127.0.0.1:9980:9980 --name=collabora \
-e "server_name=office.mydomain.net" \
-e "aliasgroup1=https://cloud.mydomain.net:443,https://cloud\\.mydomain\\.tld:443" \
-e "username=admin" -e "password=Sup3rs3cr3tPa$$w0rd" \
-e "lang=de_CH" -e "dictionaries=de_CH de_DE en_GB en_US" \
-e "extra_params=--o:home_mode.enable=true" \
--restart always collabora/code
1 Like

Yup, I had a privacy focused keyboard, FUTO, and changing it back to google, backspace issue went away immediately. It never occurred to me it might be a keyboard issue. Of course, the whole point of Nextcloud for me was to get away from Google :frowning: @wwe are there any keyboard related settings I’m not seeing?

1 Like