Nextcloud-aio with traefik gives 404 on public domain

Thanks to the help of @denNorske I finally ended up with the following functioning setup. It’s still very messy, but it may help others to put together something that works for them.

In the below, I replaced any IP addresses with e.g. localip, domains with mydomain.com, email addresses with my@email.com etc.

I have a traefik folder and a separate nextcloud folder, so to get everyting up and running I execute from each folder docker compose up -d and to stop the containers docker compose down.

Here is the static configuration file docker-compose.yml in my traefik folder:

# https://github.com/bluepuma77/traefik-best-practice/blob/main/docker-traefik-dashboard-letsencrypt/docker-compose.yml

name: traefik #To overwrite automatic naming of the container
services:
  traefik:
    image: traefik:latest
    container_name: traefik  #To overwrite automatic naming of the container
    ports:
      - 80:80
      - 443:443
      # for Vaultwarden:
      #- 8080:80
    networks:
      - proxy
      # - nextcloud-aio
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./letsencrypt:/letsencrypt
      - ./conf:/conf:ro
      - ./log:/log
      - /etc/localtime:/etc/localtime:ro
    command:
      - --api.dashboard=true
      - --log.level=DEBUG
      - --log.filepath=/log/traefik.log
      #- --log.maxsize=10MB
      - --accesslog=true
      - --accesslog.filepath=/log/traefik-access.log
      - --providers.docker.network=proxy
      #- --providers.docker.network=nextcloud-aio
      - --providers.docker.exposedByDefault=false
      # Added based on https://www.selfhostblog.com/ssl-with-traefik/
      - --providers.docker.watch=true
      - --providers.docker.defaultRule=Host(`{{ normalize .Name }}.mydomain.com`)
            
      - --providers.file.directory=conf
      - --providers.file.watch=true
      - --entrypoints.web.address=:80
      - --entrypoints.web.http.redirections.entrypoint.to=websecure
      - --entryPoints.web.http.redirections.entrypoint.scheme=https
      - --entrypoints.websecure.address=:443
      - --entrypoints.websecure.asDefault=true 
      # https://github.com/nextcloud/all-in-one/blob/main/reverse-proxy.md
      # replaced https by websecure and http by web
      #- --entrypoints.https.address=443
      - --entrypoints.websecure.transport.respondingTimeouts.readTimeout=3610s
      - --entrypoints.websecure.http.encodedCharacters.allowEncodedSlash=true
      - --entrypoints.websecure.http.encodedCharacters.allowEncodedQuestionMark=true
      - --entrypoints.websecure.http.encodedCharacters.allowEncodedPercent=true
      - --entrypoints.websecure.http.tls.certresolver=le
      # following https://www.selfhostblog.com/ssl-with-traefik. Comment out if defining main and sans domains in labels
      - --entrypoints.websecure.http.tls.domains[0].main=www.mydomain.com  
      - --entrypoints.websecure.http.tls.domains[1].main=traefik.mydomain.com  
      #- --entrypoints.websecure.http.tls.domains[2].main=vaultwarden.mydomain.com
      # Let's Encrypt configuration
      - "--certificatesresolvers.le.acme.email=my@email.com" # replace with your actual email
      - "--certificatesresolvers.le.acme.storage=/letsencrypt/acme.json"
      - "--certificatesresolvers.le.acme.httpchallenge.entrypoint=web"
      - "--certificatesresolvers.le.acme.tlschallenge=true"
      # Alternatively to the above (either comment out the above or the below)
      # See https://doc.traefik.io/traefik/v3.3/user-guides/docker-compose/acme-dns/
      #- "--certificatesresolvers.le.acme.dnschallenge=true"
      #- "--certificatesresolvers.le.acme.dnschallenge.provider=clouddns"
      #- "--certificatesresolvers.le.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory"
      #- "--certificatesresolvers.le.acme.email=my@email.com" 
      #- "--certificatesresolvers.le.acme.storage=/letsencrypt/acme.json"
    #environment:
      #- "CLOUDDNS_CLIENT_ID=12345"  # Same as AUTH_ID auto-generated when creating API user on ClouDNS
      #- "CLOUDDNS_EMAIL=my@email.com"
      #- "CLOUDNS_AUTH_ID=12345"
      #- "CLOUDDNS_PASSWORD=pastethesamepasswordassetupforAPIuseronClouDNS"

    labels:
      - traefik.enable=true
      - traefik.http.routers.mydashboard.rule=Host(`traefik.mydomain.com`)
      - traefik.http.routers.mydashboard.service=api@internal
      - traefik.http.routers.mydashboard.middlewares=myauth
      # Basic auth for the dashboard -- generate with: echo $(htpasswd -nB user)
      # Each $ in the output has to be replaced by a $$
      - traefik.http.middlewares.myauth.basicauth.users=user:$$12$$xc$$kj...
      #- traefik.docker.network=nextcloud-aio
      - traefik.docker.network=proxy
      # Uncomment the below if using acme-dns above
      #- traefik.http.routers.traefik.tls=true
      #- traefik.http.routers.traefik.tls.certresolver=le
      #- traefik.http.routers.traefik.tls.domains[0].main=mydomain.com
      #- traefik.http.routers.traefik.tls.domains[0].sans=*.mydomain.com
      #- traefik.http.routers.traefik.service=api@internal
      
networks:
#  nextcloud-aio:
#    name: nextcloud-aio
#    external: true
  proxy:
    name: proxy
    external: true


volumes:
  letsencrypt:
    name: letsencrypt
  conf:
    name: conf

Here is the dynamic configuration nextcloud.yml in the subfolder conf:

  # https://github.com/nextcloud/all-in-one/blob/main/reverse-proxy.md#adapting-the-sample-web-server-configurations-below
  http:  # changed from "web" - Traefik uses "http/tcp/udp/tls for top level keys. Routers and such go under "http" section.
    routers:
      nextcloud:
        rule: "Host(`www.mydomain.com`)"
        entrypoints:
          - "websecure"
        service: nextcloud
        middlewares:
          - nextcloud-chain
        tls:
          certresolver: "le"

    services:
      nextcloud:
        loadBalancer:
          servers:
            - url: "http://nextcloud-aio-apache:11000"

    middlewares:
      nextcloud-secure-headers:
        headers:
          hostsProxyHeaders:
            - "X-Forwarded-Host"
          referrerPolicy: "same-origin"
          customRequestHeaders:
            X-Forwarded-Proto: "https"  # This is the actual "protocol" you are forwarding, and has nothing to do with traefik.

      https-redirect:
        redirectscheme:
          scheme: "https"

      nextcloud-chain:
        chain:
          middlewares:
            - https-redirect
            - nextcloud-secure-headers

And now, in the seperate Nextcloud folder, here is my compose.yml:

name: nextcloud-aio # Add the container to the same compose project to which all the sibling containers are added automatically
services:
  nextcloud-aio-mastercontainer:
    image: ghcr.io/nextcloud-releases/all-in-one:latest # This is the container image used. You can switch to ghcr.io/nextcloud-releases/all-in-one:beta if you want to help testing new releases. See https://github.com/nextcloud/all-in-one#how-to-switch-the-channel
    init: true # This setting makes sure that signals from main process inside the container are correctly forwarded to children. See https://docs.docker.com/reference/compose-file/services/#init
    restart: always # This makes sure that the container starts always together with the host OS. See https://docs.docker.com/reference/compose-file/services/#restart
    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'!
    # devices: ["/dev/dri"] # Uncomment to enable hardware acceleration. ⚠️⚠️⚠️ Warning: this only works if the '/dev/dri' device is present on the host! If it should not exist on your host, don't add this as otherwise the mastercontainer will fail to start! See https://github.com/nextcloud/all-in-one#how-to-enable-hardware-acceleration-for-nextcloud
    network_mode: bridge # This adds the container to the same network as docker run would do. Comment this line and uncomment the line below and the networks section at the end of the file if you want to define a custom MTU size for the docker network
#    networks: ["nextcloud-aio"]
    ports:
#      - "80:80" # Can be removed when running behind a web server or reverse proxy (like Apache, Nginx, Caddy, Cloudflare Tunnel and else). See https://github.com/nextcloud/all-in-one/blob/main/reverse-proxy.md
      - "8080:8080" # This is the AIO interface, served via https and self-signed certificate. See https://github.com/nextcloud/all-in-one#explanation-of-used-ports
#     - "8443:8443" # Can be removed when running behind a web server or reverse proxy (like Apache, Nginx, Caddy, Cloudflare Tunnel and else). See https://github.com/nextcloud/all-in-one/blob/main/reverse-proxy.md
    # security_opt: ["label:disable"] # Needed when using SELinux. See https://github.com/nextcloud/all-in-one#are-there-known-problems-when-selinux-is-enabled
    environment: # This line is needed (has to be uncommented) 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
      APACHE_PORT: 11000 # Needed when running behind a web server or reverse proxy (like Apache, Nginx, Caddy, Cloudflare Tunnel and else). See https://github.com/nextcloud/all-in-one/blob/main/reverse-proxy.md
      APACHE_IP_BINDING: 0.0.0.0 # Should be set when running behind a web server or reverse proxy (like Apache, Nginx, Caddy, Cloudflare Tunnel and else) that is running on the same host. See https://github.com/nextcloud/all-in-one/blob/main/reverse-proxy.md
      APACHE_ADDITIONAL_NETWORK: proxy # (Optional) Connect the apache container to an additional docker network. Needed when behind a web server or reverse proxy (like Apache, Nginx, Caddy, Cloudflare Tunnel and else) running in a different docker network on same server. 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
      # AIO_LOG_LEVEL: warn # Allows to globally adjust the log level of the included AIO components. Supported values: debug, info, warn, error. See https://github.com/nextcloud/all-in-one#how-to-adjust-the-log-level-for-aio-components
      # 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
      # DOCKER_API_VERSION: 1.44 # You can adjust the internally used docker api version with this variable. ⚠️⚠️⚠️ Warning: please note that only the default api version (unset this variable) is supported and tested by the maintainers of Nextcloud AIO. So use this on your own risk and things might break without warning. See https://github.com/nextcloud/all-in-one#how-to-adjust-the-internally-used-docker-api-version
      # FULLTEXTSEARCH_JAVA_OPTIONS: "-Xms1024M -Xmx1024M" # Allows to adjust the fulltextsearch java options. See https://github.com/nextcloud/all-in-one#how-to-adjust-the-fulltextsearch-java-options
      NEXTCLOUD_DATADIR: /home/user/nextcloud_aio_data # Allows to set the host directory for Nextcloud's datadir. ⚠️⚠️⚠️ Warning: do not set or adjust this value after the initial Nextcloud installation is done! See https://github.com/nextcloud/all-in-one#how-to-change-the-default-location-of-nextclouds-datadir
      # 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: 16G # 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: 512M # 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 nextcloud container (Useful e.g. for LDAPS) See https://github.com/nextcloud/all-in-one#how-to-trust-user-defined-certification-authorities-ca
      # NEXTCLOUD_STARTUP_APPS: deck twofactor_totp tasks calendar contacts notes # Allows to modify the Nextcloud apps that are installed on starting AIO the first time. See https://github.com/nextcloud/all-in-one#how-to-change-the-nextcloud-apps-that-are-installed-on-the-first-startup
      # 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_NVIDIA_GPU: true # This allows to enable the NVIDIA runtime and GPU access for containers that profit from it. ⚠️⚠️⚠️ Warning: this only works if an NVIDIA gpu is installed on the server. See https://github.com/nextcloud/all-in-one#how-to-enable-hardware-acceleration-for-nextcloud.
      # NEXTCLOUD_KEEP_DISABLED_APPS: false # Setting this to true will keep Nextcloud apps that are disabled in the AIO interface and not uninstall them if they should be installed. See https://github.com/nextcloud/all-in-one#how-to-keep-disabled-apps
      SKIP_DOMAIN_VALIDATION: false # This should only be set to true if things are correctly configured. See https://github.com/nextcloud/all-in-one#how-to-skip-the-domain-validation
      # TALK_PORT: 3478 # This allows to adjust the port that the talk container is using which is exposed on the host. 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'

#   # Optional: Caddy reverse proxy. See https://github.com/nextcloud/all-in-one/discussions/575
#   # Alternatively, if you don't have a domain yet, use the built-in deSEC free domain registration in the AIO interface, or use Tailscale. See https://github.com/nextcloud/all-in-one#how-to-get-a-free-domain-via-desec and https://github.com/nextcloud/all-in-one/discussions/6817
#   # Hint: You need to uncomment APACHE_PORT: 11000 above, adjust cloud.example.com to your domain and uncomment the necessary docker volumes at the bottom of this file in order to make it work
#   # You can find further examples here: https://github.com/nextcloud/all-in-one/discussions/588
#   caddy:
#     image: caddy:alpine
#     restart: always
#     container_name: caddy
#     volumes:
#       - caddy_certs:/certs
#       - caddy_config:/config
#       - caddy_data:/data
#       - caddy_sites:/srv
#     network_mode: "host"
#     configs:
#       - source: Caddyfile
#         target: /etc/caddy/Caddyfile
# configs:
#   Caddyfile:
#     content: |
#       # Adjust cloud.example.com to your domain below
#       https://cloud.example.com:443 {
#         reverse_proxy localhost:11000
#       }

volumes: # If you want to store the data on a different drive, see https://github.com/nextcloud/all-in-one#how-to-store-the-filesinstallation-on-a-separate-drive
  nextcloud_aio_mastercontainer:
    name: nextcloud_aio_mastercontainer # This line is not allowed to be changed as otherwise the built-in backup solution will not work
  # caddy_certs:
  # caddy_config:
  # caddy_data:
  # caddy_sites:

# # Adjust the MTU size of the docker network. See https://github.com/nextcloud/all-in-one#how-to-adjust-the-mtu-size-of-the-docker-network
networks:
#   nextcloud-aio:
#     name: nextcloud-aio
#     driver_opts:
#       com.docker.network.driver.mtu: 1440
  proxy:
    name: proxy
    external: true