Nextcloud AIO does not support label configuration

Hi,

I'm have running Portainer with some containers/services, that are behind Traefik v2. Actually everything is configured with labels inside the Portainer stack (compose file) and is working fine. At the moment I want to use/setup the Nextcloud AIO (All In One).
So I have also set some labels for the Nextcloud stack, but receiving an 502 / Bad Gateway from the Apache (behind the Nextcloud AIO).

After some research I have found the following statement/documentation (github.com):

Traefik's building blocks (router, service, middlewares) need to be defined using dynamic configuration similar to this official Traefik configuration example. Using docker labels won't work because of the nature of the project.

I like the label configuration, because it can be simply accessed while using the Portainer UI. So my question is, if I can mix the label configuration with file configuration? So the file config is only for Nextcloud AIO? Or is it better to migrate the complete config to the file configuration? Do I have anything to consider?

The label config does not work with nextcloud-aio because it's not an "all-in-one" container, but instead a manager container that spins up further containers on the host through use of docker.sock. Therefore you can't simply add labels to the additional created containers.

You need to use a dynamic config file for nextcloud-aio, which you load via provider.file in your static Traefik config. You can leave the rest of your setup as-is, next to the provider.docker you just need a provider.file and the dynamic config file.

The needed parameter loadBalancer.servers.url is not supported in dynamic config from Docker (reference). You can leave a "Thumb up" on this Gihub issue to show your interest in this feature.

1 Like

@bluepuma77 thank you for your answer! I will give it a try.

So I have configured my whole traefik configuration using the dynamic file config. All services are running as expected but the nextcloud-aio gives me a "Bad Gateway - 502".

I have created a portainer stack (docker compose). As template I have used the provided one and have it adapt to my environment:

services:
  nextcloud:
    image: nextcloud/all-in-one:latest
    restart: always
    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:
  #    - 81:80 # Can be removed 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
  #    - 8181:8080
  #    - 8443:8443 # Can be removed 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
    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
      - 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=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_DATADIR=/mnt/ncdata # 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=10G # 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 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_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_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'
    # networks: # Is needed when you want to create the nextcloud-aio network with ipv6-support using this file, see the network config at the bottom of the file
      # - nextcloud-aio # Is needed when you want to create the nextcloud-aio network with ipv6-support using this file, see the network config at the bottom of the file

    networks:
      - jarvis-proxy-network

volumes:
  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

networks:
  jarvis-proxy-network:
      name: jarvis-proxy-network

Here is my dynamic traefik yaml:

http:
  routers:
    nextcloud:
      service: nextcloud-service
      entryPoints:
        - websecure
      middlewares:
        - nextcloud-chain
      rule: "Host(`nextcloud.mydomain.de`)"
      tls:
        options: default
    
    ...

  middlewares:
    nextcloud-secure-headers:
      headers:
        hostsProxyHeaders:
          - "X-Forwarded-Host"
        referrerPolicy: "same-origin"

    https-redirect:
      redirectscheme:
        scheme: https

    nextcloud-chain:
      chain:
        middlewares:
          # - ... (e.g. rate limiting middleware)
          - https-redirect
          - nextcloud-secure-headers

  services:
    nextcloud-service:
      loadBalancer:
        servers:
          - url: "http://nextcloud:11000"

...

tls:
  certificates:
    - certFile: /etc/certs/live/mydomain.de/fullchain.pem
      keyFile: /etc/certs/live/mydomain.de/privkey.pem

in the static traefik config there are the configured entrypoints:

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

providers:
  docker:
    exposedbydefault: false
    network: jarvis-proxy-network
  file:
    directory: /etc/traefik/dynamic
    watch: true

log:
  level: DEBUG
  format: json

The traefik DEBUG log gives me:

2023-07-21T19:07:52Z DBG msg='502 Bad Gateway' caused by: dial tcp 172.29.4.7:11000: connect: connection refused
2023-07-21T19:07:53Z DBG msg='502 Bad Gateway' caused by: dial tcp 172.29.4.7:11000: connect: connection refused

Actually I have no idea to find the wrong setting / to get it working.

I want to reach the Nextcloud AIO using the url:

https://nextcloud.mydomain.de

May anyone can give me a hint?! :slight_smile:

Thank you!

Where is your Traefik docker-compose.yml? Are they using the same Docker network?

Here you can see the traefik compose:

version: '3.9'

services:
  traefik:
    image: traefik:v2.10.3
    container_name: traefik
    restart: always       
    ports:
      - 80:80
      - 443:443  
      # The Web UI (enabled by --api.insecure=true)
      - 8080:8080
    
    networks:
     - jarvis-proxy-network
     
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - traefik-volume:/etc/traefik
      - certbot-letsencrypt-volume:/etc/certs:ro
      

volumes:
  traefik-volume:
    external: true

  certbot-letsencrypt-volume:
    external: true

networks:
  jarvis-proxy-network:
      name: jarvis-proxy-network

And yes, it is using the same network.

It seems Traefik and target service don’t share the same compose file.

You might need an external Docker network external: true (doc) or share one created inside compose attachable: true (doc).

I have added the flag external: true to the traefik and nextcloud compose file. But it is the same result "Bad Gateway".

Under Portainer > Networks is my network also listed / created in the past.

After I have researched the compose file > comment, I have found the hint, that for IPv6 support the nextwork nextcloud-aio must exist. For testing purposes I have created that netxcloud-aio network, switched my network with the nextcloud-aio network in the nextcloud compose file and add that network to the traefik compose file, so theoretically that network can be reached by traefik.

But also that will give the Bad Gateway.

Do I have any chance to get more Debug details?

Go into the containers (docker exec) and check with ping or curl/wget if the other one is reachable.

1 Like

That's a good idea. I will check this later! Thank you.

So I have tried to ping from the traefik container to the nextcloud-aio container:

docker exec traefik ping 172.29.8.2
PING 172.29.8.2 (172.29.8.2): 56 data bytes
64 bytes from 172.29.8.2: seq=0 ttl=64 time=1.319 ms
64 bytes from 172.29.8.2: seq=1 ttl=64 time=0.608 ms
64 bytes from 172.29.8.2: seq=2 ttl=64 time=0.144 ms
64 bytes from 172.29.8.2: seq=3 ttl=64 time=0.130 ms

or

docker exec traefik ping nextcloud-aio-mastercontainer
PING nextcloud-aio-mastercontainer (172.29.8.2): 56 data bytes
64 bytes from 172.29.8.2: seq=0 ttl=64 time=0.132 ms
64 bytes from 172.29.8.2: seq=1 ttl=64 time=0.192 ms
64 bytes from 172.29.8.2: seq=2 ttl=64 time=0.193 ms
64 bytes from 172.29.8.2: seq=3 ttl=64 time=0.195 ms

and the other way:

 docker exec nextcloud-aio-mastercontainer ping traefik
PING traefik (172.29.8.3): 56 data bytes
64 bytes from 172.29.8.3: seq=0 ttl=64 time=0.103 ms
64 bytes from 172.29.8.3: seq=1 ttl=64 time=0.173 ms
64 bytes from 172.29.8.3: seq=2 ttl=64 time=0.133 ms
64 bytes from 172.29.8.3: seq=3 ttl=64 time=0.138 ms

and got responses. So the nextcloud container is reachable for the traefik container.

Why do I get the "Bad Gateway 502"?

Is maybe here a mistake?

  middlewares:
    nextcloud-secure-headers:
      headers:
        hostsProxyHeaders:
          - "X-Forwarded-Host"
        referrerPolicy: "same-origin"

    https-redirect:
      redirectscheme:
        scheme: https

    nextcloud-chain:
      chain:
        middlewares:
          # - ... (e.g. rate limiting middleware)
          - https-redirect
          - nextcloud-secure-headers

I have simply copied that part from the nextcloud-aio/traefik documentation.

So the containers are reachable on the same network.

Now use curl/wget to check that the target service is available on the address

http://nextcloud:11000/

Here is the result:

docker exec traefik wget http://nextcloud-aio-matercontainer:11000/
wget: bad address 'nextcloud-aio-matercontainer:11000'

docker exec traefik wget http://nextcloud-aio-mastercontainer:11000/
Connecting to nextcloud-aio-mastercontainer:11000 (172.29.8.2:11000)
wget: can't connect to remote host (172.29.8.2): Connection refused

First call includes a typo, so bad address is correct. The second call shows the connection refused.

Port 11000 is not listed in the official ports used, so it may not be open.

We setup nextcloud manually with docker-compose.yml:

version: '3.9'

services:
  traefik:
    image: traefik:v2.10
    container_name: traefik
    hostname: traefik
    restart: always
    ports:
      - 80:80
      - 443:443
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - /var/log:/var/log
      - /data/traefik:/data/traefik
    command:
      - --log.level=INFO
      - --accesslog=true
      - --accesslog.filepath=/var/log/traefik-access.log
      - --api.dashboard=true
      - --providers.docker=true
      - --providers.docker.exposedByDefault=false
      - --entrypoints.web.address=:80
      - --entrypoints.web.http.redirections.entrypoint.to=websecure
      - --entrypoints.web.http.redirections.entrypoint.scheme=https
      - --entrypoints.websecure.address=:443
      - --entrypoints.websecure.http.tls.certresolver=myresolver
      - --certificatesresolvers.myresolver.acme.email=<mail@example.com>
      - --certificatesresolvers.myresolver.acme.storage=/data/traefik/acme.json
      - --certificatesresolvers.myresolver.acme.tlschallenge=true
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.dashboard.entrypoints=websecure"
      - "traefik.http.routers.dashboard.rule=Host(`traefik.example.com`)"
      - "traefik.http.routers.dashboard.service=api@internal"
      - "traefik.http.routers.dashboard.middlewares=auth"
      - "traefik.http.middlewares.auth.basicauth.users=admin:$$apr1$$v9rdfknT$$63JGq8avNBe993kUW0z6u1"


  whoami:
    image: traefik/whoami:v1.10
    container_name: whoami
    hostname: whoami
    restart: always
    labels:
      - 'traefik.enable=true'
      #- 'traefik.http.routers.whoami.tls=true'
      #- 'traefik.http.routers.whoami.tls.certresolver=myresolver'
      - 'traefik.http.routers.whoami.entrypoints=websecure'
      - 'traefik.http.routers.whoami.rule=PathPrefix(`/whoami`)'
      - 'traefik.http.routers.whoami.priority=1024'
      - 'traefik.http.services.whoami.loadbalancer.server.port=80'


  nginx:
    image: nginx
    container_name: nginx
    restart: always
    hostname: nginx
    volumes:
      - /data/nginx:/usr/share/nginx/html:ro
    labels:
      - 'traefik.enable=true'
      #- 'traefik.http.routers.nginx.tls=true'
      #- 'traefik.http.routers.nginx.tls.certresolver=myresolver'
      - 'traefik.http.routers.nginx.entrypoints=websecure'
      - 'traefik.http.routers.nginx.rule=Host(`example.com`) || Host(`www.example.com`)'
      - 'traefik.http.services.nginx.loadbalancer.server.port=80'


  postgres:
    image: postgres:14-alpine
    container_name: postgres
    restart: always
    volumes:
      - /data/postgres:/var/lib/postgresql/data
    environment:
      - TZ=Europe/Berlin
      - POSTGRES_DB=nextcloud
      - POSTGRES_USER=nextcloud
      - POSTGRES_PASSWORD=<ABC>


  nextcloud:
    image: nextcloud
    container_name: nextcloud
    hostname: nextcloud
    restart: always
    volumes:
      - /data/nextcloud:/var/www/html
    environment:
      - TZ=Europe/Berlin
      - POSTGRES_HOST=postgres
      - POSTGRES_DB=nextcloud
      - POSTGRES_USER=nextcloud
      - POSTGRES_PASSWORD=<ABC>
      - NEXTCLOUD_ADMIN_PASSWORD=<DEF>
      - NEXTCLOUD_ADMIN_USER=ncadmin
      - NEXTCLOUD_TRUSTED_DOMAINS=cloud.example.com
      - TRUSTED_PROXIES=traefik
      - OVERWRITEPROTOCOL=https
      - NC_default_phone_region=<EU>
    depends_on:
      - postgres
    labels:
      - 'traefik.enable=true'
      #- 'traefik.http.routers.nextcloud.tls=true'
      #- 'traefik.http.routers.nextcloud.tls.certresolver=myresolver'
      - 'traefik.http.routers.nextcloud.entrypoints=websecure'
      - 'traefik.http.routers.nextcloud.rule=Host(`cloud.example.com`)'
      - 'traefik.http.routers.nextcloud.middlewares=nextcloud-dav,nextcloud-header'
      - 'traefik.http.services.nextcloud.loadbalancer.server.port=80'
      - 'traefik.http.middlewares.nextcloud-dav.redirectRegex.regex=https://(.*)/.well-known/(card|cal)dav'
      - 'traefik.http.middlewares.nextcloud-dav.redirectRegex.replacement=https://$${1}/remote.php/dav/'
      - 'traefik.http.middlewares.nextcloud-dav.redirectRegex.permanent=true'
      - "traefik.http.middlewares.nextcloud-header.headers.referrerPolicy=no-referrer"
      - "traefik.http.middlewares.nextcloud-header.headers.stsSeconds=15552000"
      - "traefik.http.middlewares.nextcloud-header.headers.forceSTSHeader=true"
      - "traefik.http.middlewares.nextcloud-header.headers.stsPreload=true"
      - "traefik.http.middlewares.nextcloud-header.headers.stsIncludeSubdomains=true"
      - "traefik.http.middlewares.nextcloud-header.headers.browserXssFilter=true"
      - "traefik.http.middlewares.nextcloud-header.headers.customRequestHeaders.X-Forwarded-Proto=https"


  collabora:
    image: collabora/code
    container_name: collabora
    hostname: collabora
    restart: always
    environment:
      - aliasgroup1=https://cloud.example.com
      - dictionaries=en_US
      - username=coadmin
      - password=<GHI>
      - extra_params=--o:ssl.enable=false --o:ssl.termination=true
    tty: true
    labels:
      - 'traefik.enable=true'
      #- 'traefik.http.routers.collabora.tls=true'
      #- 'traefik.http.routers.collabora.tls.certresolver=myresolver'
      - 'traefik.http.routers.collabora.entrypoints=websecure'
      - 'traefik.http.routers.collabora.rule=Host(`office.example.com`) || Host(`co.example.com`)'
      - 'traefik.http.routers.collabora.middlewares=collabora-header'
      - 'traefik.http.middlewares.collabora-header.headers.referrerPolicy=no-referrer'
      - 'traefik.http.middlewares.collabora-header.headers.stsSeconds=15552000'
      - 'traefik.http.middlewares.collabora-header.headers.forceSTSHeader=true'
      - 'traefik.http.middlewares.collabora-header.headers.stsPreload=true'
      - 'traefik.http.middlewares.collabora-header.headers.stsIncludeSubdomains=true'
      - 'traefik.http.middlewares.collabora-header.headers.browserXssFilter=true'
      - 'traefik.http.middlewares.collabora-header.headers.customRequestHeaders.X-Forwarded-Proto=https'
      - 'traefik.http.services.collabora.loadbalancer.server.port=9980'
1 Like

Thank you for providing your compose file. In the past that was nearly the same way how I have integrated nextcloud.
I like the concept to maintain one all in one solution and parts like db and so are like a Blackbox.
Actually I have created a post in the Nextcloud forum.

But if you or someone else have some other ideas, please share. :slightly_smiling_face:

One important thing is, that the AIO setup page has to executed. One part is to enter the domain, where Nextcloud is running and the other to select the desired AddOns. After that a bunch of Nextcloud Container will be created including the Apache Server.

So actually I don't have longer the Bad Gateway - 502. Now I have a Gateway Timeout 504.

The Traefik Service Config to Nextcloud must point to the host-ip:11000. Else the 502 will return.

One little step forward, but know the next problem. I think the Traefik part should be fine,but I am not sure..

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.