Caddy + Nextcloud (fpm) + Collabora - individual containers and docker-compose

I’m having a hard time configuring Caddy + Nextcloud (fpm) + Collabora, each in a individual container (and docker-compose).

There is a lot of “spreaded information”, unfortunately outdated (I think new versions of the three components have recently come out) and still many posts receive a “guidance” to ask in the forum of the other(s) program(s)…

Can we try to make an “optimized and updated” post to use these three great programs together? :innocent:

Scenario:

[VPS [Docker [Caddy] [Nextcloud] [Collabora] [...] ]]
                |         |           |
                ----------------------- (caddy_net)

I think this scenario is quite common for those who are (like me) learning. We use a VPS as a host, a “main” container (Caddy) to do the reverse proxy/https and we add containers as needed and/or willing to learn.

As I often need the certificates for other uses, I chose to use certbot on the host and copy the certificates I need “inside” each container as needed.

My Caddy docker-compose.yml file:

~/docker/caddy/docker-compose.yml
---------------------------------
version: "3.7"
services:
  caddy:
    image: caddy:2.5.0-alpine
    hostname: caddy
    container_name: caddy
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - ./certs:/certs
      - ./config:/config
      - ./data:/data
      - ./sites:/srv
networks:
  default:
    name: caddy_net
    external: true

Caddyfile?

~/docker/caddy/Caddyfile
------------------------
{
        #debug
        auto_https disable_certs
}

collabora.cites.aop {
        tls /certs/collabora.cites.aop/fullchain.pem /certs/collabora.cites.aop/privkey.pem
        # ??? reverse_proxy collabora ???
}

nextcloud.cites.aop {
        tls /certs/nextcloud.cites.aop/fullchain.pem /certs/nextcloud.cites.aop/privkey.pem
        # ??? reverse_proxy nextcloud ???
}

Last try with Nextcloud (not fpm version and very very slow, with errors).

~/docker/nextcloud/docker-compose.yml
-------------------------------------
version: '2'
volumes:
  nextcloud:
  db:
services:
  db:
    image: mariadb
    restart: unless-stopped
    command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW
    volumes:
      - db:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: "P@ssw0rd"
      MYSQL_PASSWORD: "P@ssw0rd"
      MYSQL_DATABASE: "nextcloud"
      MYSQL_USER: "nextcloud"
  app:
    image: nextcloud
    restart: unless-stopped
    links:
      - db
    volumes:
      - nextcloud:/var/www/html
    environment:
      MYSQL_PASSWORD: "P@ssw0rd"
      MYSQL_DATABASE: "nextcloud"
      MYSQL_USER: "nextcloud"
      MYSQL_HOST: "db"
      NEXTCLOUD_ADMIN_USER: "admin"
      NEXTCLOUD_ADMIN_PASSWORD: "P@ssw0rd"
      NEXTCLOUD_TRUSTED_DOMAINS: "nextcloud.cites.aop"
      # REDIS_HOST: (not set by default) Name of Redis container
      # REDIS_HOST_PASSWORD: (not set by default) Redis password
      SMTP_HOST: "mail.cites.aop"
      SMTP_SECURE: "tls"
      SMTP_PORT: 587
      SMTP_NAME: "mailer@cites.aop"
      SMTP_PASSWORD: "P@ssw0rd"
      MAIL_FROM_ADDRESS: "Nextcloud <no-reply@cites.aop>"
  # web:
  # image: nginx
  # restart: unless-stopped
  # ports:
  # - 8080:80
  # links:
  # - nextcloud
  # volumes:
  # - ./nginx.conf:/etc/nginx/nginx.conf:ro
  # volumes_from:
  # - nextcloud
networks:
  default:
    name: caddy_net
    external: true

Your docker-compose.yml should either have a container_name: attribute or use GitHub - lucaslorentz/caddy-docker-proxy: Caddy as a reverse proxy for Docker

Let’s assume you use container_name:, then, you do:

…
reverse_proxy container_name
…
1 Like

Sure, we just need someone from the community to write it! Post one on the Wiki - Caddy Community once you’ve gotten everything figured out.

FWIW, that’s definitely unusual. A large majority of users will specifically be using Caddy because of its Automatic HTTPS feature.

What’s the question, exactly? Please fill out the help topic template, there’s really not enough here for us to help.

2 Likes

If I understand what you’re doing, you should not eliminate the nginx container Nextcloud is providing. You should instead put Caddy in front of it as a reverse proxy and TLS terminator.

I say this because I think the nginx.conf Nextcloud provides is doing something pretty specific for them.

1 Like

Tried to adapt zilexa instructions but I only got a Caddy “Congratulations!” page. See no errors on both Caddy containers (main Caddy and Caddy from below docker-compose.yml).

docker-compose.yml

version: "2.0"
services:
  caddy:
    container_name: caddy-proxy
    image: caddy:2.5.0-alpine
    restart: unless-stopped
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./caddy/caddy_data:/data
      - ./caddy/config:/config
    #  - ./nextcloud/var/www/html:/nextcloud/var/www/html
    #  - ./nextcloud/var/data:/nextcloud/var/nextdata
    volumes_from:
      - nextcloud
    #ports:
    #  - 8080:80
    #  - 8443:443
  nextcloud:
    image: nextcloud:23-fpm
    container_name: nextcloud
    restart: unless-stopped
    mem_limit: 2048m
    mem_reservation: 512m
    depends_on:
      - nextcloud-db
      - nextcloud-cache
    environment:
      NEXTCLOUD_DATA_DIR: /var/nextdata
      NEXTCLOUD_TRUSTED_DOMAINS: nextcloud.cites.aop
      NEXTCLOUD_ADMIN_USER: admin
      NEXTCLOUD_ADMIN_PASSWORD: P4ssw0rd
      POSTGRES_HOST: nextcloud-db
      POSTGRES_DB: nextcloud
      POSTGRES_USER: nextcloud
      POSTGRES_PASSWORD: P4ssw0rd
      REDIS_HOST: nextcloud-cache
      REDIS_HOST_PASSWORD: P4ssw0rd
      SMTP_HOST: "mail.cites.aop"
      SMTP_SECURE: "tls"
      SMTP_PORT: 587
      SMTP_NAME: "mailer@cites.aop"
      SMTP_PASSWORD: "P4ssw0rd"
      MAIL_FROM_ADDRESS: "Nextcloud <no-reply@cites.aop>"
      #SMTP_FROM_ADDRESS: $EMAIL
    volumes:
      - ./nextcloud/var/nextdata:/var/nextdata
      - ./nextcloud/var/www/html:/var/www/html
      - ./nextcloud/var/www/html/config:/var/www/html/config
      # Custom settings for php fpm to make nextcloud work. The default settings resulted in the error:
      # WARNING: [pool www] server reached pm.max_children setting (5), consider raising it
      #- ./nextcloud/etc/www-custom.ini:/usr/local/etc/php-fpm.d/zz-custom.conf
    labels:
      caddy: nextcloud.cites.aop
      #caddy.tls: $EMAIL
      caddy.file_server: ""
      caddy.root: "* /nextcloud/var/www/html"
      caddy.php_fastcgi: "{{upstreams 9000}}"
      caddy.php_fastcgi.root: "/var/www/html"
      caddy.php_fastcgi.env: "front_controller_active true"
      caddy.encode: gzip
      caddy.redir_0: "/.well-known/carddav /remote.php/dav 301"
      caddy.redir_1: "/.well-known/caldav /remote.php/dav 301"
      caddy.header.Strict-Transport-Security: '"max-age=15768000;includeSubDomains;preload"' # Required for Nextcloud
      #caddy.header.X-XSS-Protection: '"1; mode=block;"'             # Required for FileRun+OnlyOffice
      #caddy.header.X-Content-Type-Options: "nosniff"                # Required for FileRun+OnlyOffice
      #caddy.header.X-Frame-Options: "SAMEORIGIN"                    # Required for FileRun+OnlyOffice
  nextcloud-db:
    container_name: nextcloud-db
    image: postgres:12-alpine
    restart: unless-stopped
    environment:
      POSTGRES_USER: nextcloud
      POSTGRES_PASSWORD: P4ssw0rd
    volumes:
      - ./nextcloud/db:/var/lib/postgresql/data
      - /etc/localtime:/etc/localtime:ro
  nextcloud-cache:
    container_name: nextcloud-cache
    image: redis:alpine
    restart: unless-stopped
    mem_limit: 2048m
    mem_reservation: 512m
    command: redis-server --requirepass P4ssw0rd
networks:
  default:
    name: caddy_net
    external: true

This isn’t the caddy-docker-proxy image, that’s the vanilla Caddy image. You’re looking for this:

Also if you’re trying to use nextcloud, you won’t be able to use it this way, unless you also mount nextcloud’s files into the Caddy container at /nextcloud/var/www/html. Caddy needs to be able to see the files inside its own container to be able to serve static files and to detect which PHP files exist.

It might be simpler to use the Apache variant of the nextcloud image, in which case you can just reverse_proxy to it. Might perform a bit worse, but it’s a simpler setup.

1 Like

I think I will do this later… :wink:

Let me explain this.
For example, I use the certificates from ldap.cites.aop and mail.cites.aop in two places:

  • ldap.cites.aop - on the ldap server itself (docker container) and on Caddy to provide HTTPS for phpLDAPadmin (another container)
  • mail.cites.aop - on the mail server itself (docker container) and on Caddy to provide HTTPS for Roundcube (another container)

Both cases I use one URL to two purposes: server itself and web app associated with.

Ok, I do not made a proper question, it was more some sort of “invitation to collaboration”. :laughing:

I decided to make this a two step process:

  • one: make one docker-compose.yml with all Nextcloud components working perfectly, direct on the VPS using only HTTP
  • two: make the proper Caddyfile configuration to put “one” behind Caddy

“One” is almost there, I made a post on Nextcloud forum to get help.

Docker-compose - almost perfect, need help with collabora/code

As soon as I got “one” done, I would appreciate help to make “two”. :innocent:

Bellow, the two essential files to “one”. :smile:

docker-compose.yml

version: '2'
services:

  #nextcloud-db:
  #  image: postgres:12-alpine
  #  container_name: nextcloud-db
  #  restart: unless-stopped
  #  environment:
  #    POSTGRES_USER: nextcloud
  #    POSTGRES_PASSWORD: password
  #  volumes:
  #    - nextcloud-db:/var/lib/postgresql/data
  #    - /etc/localtime:/etc/localtime:ro

  nextcloud-db:
    image: mariadb
    container_name: nextcloud-db
    restart: unless-stopped
    command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_PASSWORD: password
      MYSQL_DATABASE: nextcloud
      MYSQL_USER: nextcloud
    volumes:
      - nextcloud-db:/var/lib/mysql

  nextcloud-cache:
    image: redis:alpine
    container_name: nextcloud-cache
    restart: unless-stopped
    mem_limit: 2048m
    mem_reservation: 512m
    command: redis-server --requirepass password

  nextcloud-app:
    image: nextcloud:fpm-alpine
    container_name: nextcloud-app
    restart: unless-stopped
    depends_on:
      - nextcloud-db
      - nextcloud-cache
    environment:
      MYSQL_DATABASE: nextcloud
      MYSQL_USER: nextcloud
      MYSQL_PASSWORD: password
      MYSQL_HOST: nextcloud-db
      POSTGRES_DB: nextcloud
      POSTGRES_USER: nextcloud
      POSTGRES_PASSWORD: password
      POSTGRES_HOST: nextcloud-db
      NEXTCLOUD_ADMIN_USER: admin
      NEXTCLOUD_ADMIN_PASSWORD: password
      NEXTCLOUD_TRUSTED_DOMAINS: nextcloud.example.com collabra.example.com
      REDIS_HOST: nextcloud-cache
      REDIS_HOST_PASSWORD: password
      SMTP_HOST: mail.example.com
      SMTP_SECURE: tls
      SMTP_PORT: 587
      SMTP_AUTHTYPE: LOGIN
      SMTP_NAME: mailer@example.com
      SMTP_PASSWORD: password
      MAIL_FROM_ADDRESS: no-reply
      MAIL_DOMAIN: example.com
    volumes:
      - nextcloud-app:/var/www/html

  nextcloud-web:
    image: nginx:alpine
    container_name: nextcloud-web
    restart: unless-stopped
    ports:
      - 80:80
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
    volumes_from:
      - nextcloud-app

  nextcloud-collabora:
    image: collabora/code
    container_name: nextcloud-collabora
    restart: unless-stopped
    ports:
      - 9980:9980
    depends_on:
      - nextcloud-web
    cap_add:
     - MKNOD
    environment:
      - username=admin
      - password=password
      - DONT_GEN_SSL_CERT=yes
      - server_name=collabra.example.com
      - dictionaries=en_US es_ES pt_BR
      - extra_params=--o:ssl.enable=false
      # Domain the service should be accessed from:
     #- domain=${VIRTUAL_HOST}
     #- domain=example.com
      #
     #- VIRTUAL_HOST=${COLLABORA_VIRTUAL_HOST}
     #- VIRTUAL_HOST=collabra.example.com
     #- LETSENCRYPT_HOST=${COLLABORA_VIRTUAL_HOST}
     #- LETSENCRYPT_HOST=${COLLABORA_VIRTUAL_HOST}
      #
      # Extra parameters to Collabora, see also
      # https://www.collaboraoffice.com/code/nginx-reverse-proxy/:
      # SSL terminates at the proxy
     #- extra_params=--o:ssl.enable=false --o:ssl.termination=true
    volumes:
      - /etc/localtime:/etc/localtime:ro

volumes:
  nextcloud-app:
  nextcloud-db:

networks:
  default:
    name: caddy_net
    external: true

and nginx.conf

worker_processes auto;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    # Prevent nginx HTTP Server Detection
    server_tokens   off;

    keepalive_timeout  65;

    #gzip  on;

    upstream php-handler {
        server nextcloud-app:9000;
    }

    server {
        listen 80;

        # HSTS settings
        # WARNING: Only add the preload option once you read about
        # the consequences in https://hstspreload.org/. This option
        # will add the domain to a hardcoded list that is shipped
        # in all major browsers and getting removed from this list
        # could take several months.
        #add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;" always;

        # set max upload size
        client_max_body_size 512M;
        fastcgi_buffers 64 4K;

        # Enable gzip but do not remove ETag headers
        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 application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;

        # Pagespeed is not supported by Nextcloud, so if your server is built
        # with the `ngx_pagespeed` module, uncomment this line to disable it.
        #pagespeed off;

        # HTTP response headers borrowed from Nextcloud `.htaccess`
        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                         "none"          always;
        add_header X-XSS-Protection                     "1; mode=block" always;

        # Remove X-Powered-By, which is an information leak
        fastcgi_hide_header X-Powered-By;

        # Path to the root of your installation
        root /var/www/html;

        # Specify how to handle directories -- specifying `/index.php$request_uri`
        # here as the fallback means that Nginx always exhibits the desired behaviour
        # when a client requests a path that corresponds to a directory that exists
        # on the server. In particular, if that directory contains an index.php file,
        # that file is correctly served; if it doesn't, then the request is passed to
        # the front-end controller. This consistent behaviour means that we don't need
        # to specify custom rules for certain paths (e.g. images and other assets,
        # `/updater`, `/ocm-provider`, `/ocs-provider`), and thus
        # `try_files $uri $uri/ /index.php$request_uri`
        # always provides the desired behaviour.
        index index.php index.html /index.php$request_uri;

        # Rule borrowed from `.htaccess` to handle Microsoft DAV clients
        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;
        }

        # Make a regex exception for `/.well-known` so that clients can still
        # access it despite the existence of the regex rule
        # `location ~ /(\.|autotest|...)` which would otherwise handle requests
        # for `/.well-known`.
        location ^~ /.well-known {
            # The rules in this block are an adaptation of the rules
            # in `.htaccess` that concern `/.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; }

            # Let Nextcloud's API for `/.well-known` URIs handle all other
            # requests by passing them to the front-end controller.
            return 301 /index.php$request_uri;
        }

        # Rules borrowed from `.htaccess` to hide certain paths from clients
        location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/)  { return 404; }
        location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console)                { return 404; }

        # Ensure this block, which passes PHP files to the PHP process, is above the blocks
        # which handle static assets (as seen below). If this block is not declared first,
        # then Nginx will encounter an infinite rewriting loop when it prepends `/index.php`
        # to the URI, resulting in a HTTP 500 error response.
        location ~ \.php(?:$|/) {
            # Required for legacy support
            rewrite ^/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-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;         # Avoid sending the security headers twice
            fastcgi_param front_controller_active true;     # Enable pretty urls
            fastcgi_pass php-handler;

            fastcgi_intercept_errors on;
            fastcgi_request_buffering off;
        }

        location ~ \.(?:css|js|svg|gif)$ {
            try_files $uri /index.php$request_uri;
            expires 6M;         # Cache-Control policy borrowed from `.htaccess`
            access_log off;     # Optional: Don't log access to assets
        }

        location ~ \.woff2?$ {
            try_files $uri /index.php$request_uri;
            expires 7d;         # Cache-Control policy borrowed from `.htaccess`
            access_log off;     # Optional: Don't log access to assets
        }

        # Rule borrowed from `.htaccess`
        location /remote {
            return 301 /remote.php$request_uri;
        }

        location / {
            try_files $uri $uri/ /index.php$request_uri;
        }
    }
}

I was working on this when I saw that “Nextcloud All In One”.

Nextcloud AIO stands for Nextcloud All In One and provides easy deployment and maintenance with most features included in this one Nextcloud instance.

Included are:

  • Nextcloud
  • Nextcloud Office
  • High performance backend for Nextcloud Files
  • High performance backend for Nextcloud Talk
  • Backup solution (based on BorgBackup)
  • OnlyOffice
  • ClamAV

Nextcloud All In One

Are reverse proxies supported?

Yes. Please refer to the following documentation on this: reverse-proxy.md

I tried to use it behind Caddy but had no success.

Take a look here:

Reverse-proxy (Caddy) already in place. How install/configure NC AIO?

1 Like

Nextcloud AIO is still experimental.

Go for nextcloudpi-x86.

@francislavoie , finally I got a docker-compose.yml file that runs perfectly latest version of Nextcloud with Collabora.

Can you help me to put this “stack” behind Caddy?

This is the docker-compose.yml to start Nextcloud + Collabora (note that at bottom I leave the “caddy_net” network ready).

version: '2'
services:

  nextcloud-db:
    image: postgres:14.2-alpine
    container_name: nextcloud-db
    restart: unless-stopped
    environment:
      POSTGRES_USER: nextcloud
      POSTGRES_PASSWORD: password
    volumes:
      - nextcloud-db:/var/lib/postgresql/data
      - /etc/localtime:/etc/localtime:ro

  nextcloud-cache:
    image: redis:7.0.0-alpine
    container_name: nextcloud-cache
    restart: unless-stopped
    mem_limit: 2048m
    mem_reservation: 512m
    command: redis-server --requirepass password

  nextcloud-app:
    image: nextcloud:24.0.0-fpm-alpine
    container_name: nextcloud-app
    restart: unless-stopped
    depends_on:
      - nextcloud-db
      - nextcloud-cache
    environment:
      POSTGRES_DB: nextcloud
      POSTGRES_USER: nextcloud
      POSTGRES_PASSWORD: password
      POSTGRES_HOST: nextcloud-db
      NEXTCLOUD_ADMIN_USER: admin
      NEXTCLOUD_ADMIN_PASSWORD: password
      NEXTCLOUD_TRUSTED_DOMAINS: nextcloud.local.cites.aop
      REDIS_HOST: nextcloud-cache
      REDIS_HOST_PASSWORD: password
      SMTP_HOST: mail.local.cites.aop
      SMTP_SECURE: tls
      SMTP_PORT: 587
      SMTP_AUTHTYPE: LOGIN
      SMTP_NAME: mailer@local.cites.aop
      SMTP_PASSWORD: password
      MAIL_FROM_ADDRESS: no-reply
      MAIL_DOMAIN: local.cites.aop
    volumes:
      - nextcloud-app:/var/www/html

  nextcloud-web:
    image: nginx:1.21.6-alpine
    container_name: nextcloud-web
    restart: unless-stopped
    ports:
      - 80:80
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
    volumes_from:
      - nextcloud-app

  nextcloud-collabora:
    image: collabora/code:21.11.4.2.1
    container_name: nextcloud-collabora
    restart: unless-stopped
    ports:
      - 9980:9980
    depends_on:
      - nextcloud-web
    environment:
      - username=admin
      - password=password
      - dictionaries=en_US es_ES pt_BR
      - extra_params=--o:ssl.enable=false
    volumes:
      - /etc/localtime:/etc/localtime:ro

volumes:
  nextcloud-app:
  nextcloud-db:

#networks:
#  default:
#    name: caddy_net
#    external: true

The companion nginx.conf is

worker_processes auto;

error_log  /var/log/nginx/error.log warn;

pid        /var/run/nginx.pid;

events {

    worker_connections  1024;

}

http {

    include       /etc/nginx/mime.types;

    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '

                      '$status $body_bytes_sent "$http_referer" '

                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;

    #tcp_nopush     on;

    # Prevent nginx HTTP Server Detection

    server_tokens   off;

    keepalive_timeout  65;

    #gzip  on;

    upstream php-handler {

        server nextcloud-app:9000;

    }

    server {

        listen 80;

        # HSTS settings

        # WARNING: Only add the preload option once you read about

        # the consequences in https://hstspreload.org/. This option

        # will add the domain to a hardcoded list that is shipped

        # in all major browsers and getting removed from this list

        # could take several months.

        #add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;" always;

        # set max upload size

        client_max_body_size 512M;

        fastcgi_buffers 64 4K;

        # Enable gzip but do not remove ETag headers

        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 application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;

        # Pagespeed is not supported by Nextcloud, so if your server is built

        # with the `ngx_pagespeed` module, uncomment this line to disable it.

        #pagespeed off;

        # HTTP response headers borrowed from Nextcloud `.htaccess`

        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                         "none"          always;

        add_header X-XSS-Protection                     "1; mode=block" always;

        # Remove X-Powered-By, which is an information leak

        fastcgi_hide_header X-Powered-By;

        # Path to the root of your installation

        root /var/www/html;

        # Specify how to handle directories -- specifying `/index.php$request_uri`

        # here as the fallback means that Nginx always exhibits the desired behaviour

        # when a client requests a path that corresponds to a directory that exists

        # on the server. In particular, if that directory contains an index.php file,

        # that file is correctly served; if it doesn't, then the request is passed to

        # the front-end controller. This consistent behaviour means that we don't need

        # to specify custom rules for certain paths (e.g. images and other assets,

        # `/updater`, `/ocm-provider`, `/ocs-provider`), and thus

        # `try_files $uri $uri/ /index.php$request_uri`

        # always provides the desired behaviour.

        index index.php index.html /index.php$request_uri;

        # Rule borrowed from `.htaccess` to handle Microsoft DAV clients

        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;

        }

        # Make a regex exception for `/.well-known` so that clients can still

        # access it despite the existence of the regex rule

        # `location ~ /(\.|autotest|...)` which would otherwise handle requests

        # for `/.well-known`.

        location ^~ /.well-known {

            # The rules in this block are an adaptation of the rules

            # in `.htaccess` that concern `/.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; }

            # Let Nextcloud's API for `/.well-known` URIs handle all other

            # requests by passing them to the front-end controller.

            return 301 /index.php$request_uri;

        }

        # Rules borrowed from `.htaccess` to hide certain paths from clients

        location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/)  { return 404; }

        location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console)                { return 404; }

        # Ensure this block, which passes PHP files to the PHP process, is above the blocks

        # which handle static assets (as seen below). If this block is not declared first,

        # then Nginx will encounter an infinite rewriting loop when it prepends `/index.php`

        # to the URI, resulting in a HTTP 500 error response.

        location ~ \.php(?:$|/) {

            # Required for legacy support

            rewrite ^/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-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;         # Avoid sending the security headers twice

            fastcgi_param front_controller_active true;     # Enable pretty urls

            fastcgi_pass php-handler;

            fastcgi_intercept_errors on;

            fastcgi_request_buffering off;

        }

        location ~ \.(?:css|js|svg|gif)$ {

            try_files $uri /index.php$request_uri;

            expires 6M;         # Cache-Control policy borrowed from `.htaccess`

            access_log off;     # Optional: Don't log access to assets

        }

        location ~ \.woff2?$ {

            try_files $uri /index.php$request_uri;

            expires 7d;         # Cache-Control policy borrowed from `.htaccess`

            access_log off;     # Optional: Don't log access to assets

        }

        # Rule borrowed from `.htaccess`

        location /remote {

            return 301 /remote.php$request_uri;

        }

        location / {

            try_files $uri $uri/ /index.php$request_uri;

        }

    }

}

My actual docker-compose.yml for Caddy is

version: "3.7"
services:

  caddy:
    image: caddy:2.5.1-alpine
    hostname: caddy
    container_name: caddy
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - ./sites:/srv
      - app_data:/data
      - app_config:/config

volumes:
  app_data:
  app_config:

networks:
  default:
    name: caddy_net
    external: true

And the Caddyfile is

{
        debug
}

nextcloud.local.cites.aop {
        acme_server
        tls internal
        reverse_proxy nextcloud-web

Nextcloud works fine through Caddy but when I try to create a document in Nextcloud that will use Collabora I always get an error.

:face_with_diagonal_mouth:

That doesn’t really give me much to go on here. I don’t have a good picture of the flow. What’s in your logs? Please be specific about any errors you’re seeing. Saying “I always get an error” doesn’t tell me what the error is; it could be anything.

Why are you using nginx in this setup? You can use Caddy’s php_fastcgi to serve nextcloud instead.

If you please show me how to make this change I will be glad to use Caddy instead Nginx.

Now I am really exausted, too much hours (and days) on this. Need to sleep, tomorrow I will try to collect logs info and explain better the flow.

Did you read this wiki?

1 Like

Yes, several times. The scenario is different in many ways. Two Caddy instances running, frontend directly on frontend host, backend running inside container. I am using only one Caddy instance, running inside container with one Docker external network named “caddy_net”.

Also involves a manual copy of certificate file from one Caddy to the other.

That wiki may be outdated in several points. One of them is to use “- domain=${NEXTCLOUD_FQDN}”.

On docker log of the nextcloud-collabora container:

-e ERR: Use of domain variable is not supported. First host/domain who tries to connect to COOL is always allowed.
To allow multiple host and its aliases use something like this and pass it as env variable:
aliasgroup1=https://domain1:443,https://its-alias|its-second-alias:443
aliasgroup2=https://domain2:443,https://its-alias:443
For more info: https://sdk.collaboraonline.com/docs/installation/CODE_Docker_image.html

Why nginx though? You can serve the PHP app with Caddy instead; it’ll be simpler. The wiki shows you how to do that; look at the config for the backend Caddy.

Will try again, in this scenario: Nextcloud + Collabora substituting Nginx by Caddy and exposing necessary ports direct on host (ports 80, 443 and 9980). No “caddy_net”.

The wiki shows you how to do that

Several points do not work/changed. Some things I know what to change, for example:

        @collabora {
                path /loleaflet/* # Loleaflet is the client part of LibreOffice Online
                path /hosting/discovery # WOPI discovery URL
                path /hosting/capabilities # Show capabilities as json
                path /lool/* # Main websocket, uploads/downloads, presentations
        }

to

        @collabora {
                path /browser/* # Loleaflet is the client part of LibreOffice Online
                path /hosting/discovery # WOPI discovery URL
                path /hosting/capabilities # Show capabilities as json
                path /cool/* # Main websocket, uploads/downloads, presentations
        }

If I manage to put the “Nextcloud stack” to work with Caddy replacing Nginx maybe you could assist me later on put another Caddy in front of this stack, to be the reverse proxy for it and other services.

The key is that php_fastcgi communicates with the nextcloud php-fpm container, and the Caddy container also needs the nextcloud PHP code mounted at the same filesystem location – Caddy needs to see the files to know how to perform the rewrites, and to serve static files.

Like I said though, I don’t understand what isn’t working so I can’t really give you much other than vague suggestions.

Look, this will be the docker-compose.yml that I will use:

version: '2'
services:

  nextcloud-db:
    image: postgres:14.2-alpine
    container_name: nextcloud-db
    restart: unless-stopped
    volumes:
      - nextcloud-db:/var/lib/postgresql/data
      - /etc/localtime:/etc/localtime:ro
    environment:
      POSTGRES_USER: nextcloud
      POSTGRES_PASSWORD: password

  nextcloud-cache:
    image: redis:7.0.0-alpine
    container_name: nextcloud-cache
    restart: unless-stopped
    mem_limit: 2048m
    mem_reservation: 512m
    command: redis-server --requirepass password

  nextcloud-app:
    image: nextcloud:24.0.0-fpm-alpine
    container_name: nextcloud-app
    restart: unless-stopped
    ports:
      - 9000:9000
    volumes:
      - nextcloud-app:/var/www/html
    depends_on:
      - nextcloud-db
      - nextcloud-cache
    environment:
      POSTGRES_DB: nextcloud
      POSTGRES_USER: nextcloud
      POSTGRES_PASSWORD: password
      POSTGRES_HOST: nextcloud-db
      NEXTCLOUD_ADMIN_USER: admin
      NEXTCLOUD_ADMIN_PASSWORD: password
      NEXTCLOUD_TRUSTED_DOMAINS: nextcloud.local.cites.aop
      REDIS_HOST: nextcloud-cache
      REDIS_HOST_PASSWORD: password
      SMTP_HOST: mail.local.cites.aop
      SMTP_SECURE: tls
      SMTP_PORT: 587
      SMTP_AUTHTYPE: LOGIN
      SMTP_NAME: mailer@local.cites.aop
      SMTP_PASSWORD: password
      MAIL_FROM_ADDRESS: no-reply
      MAIL_DOMAIN: local.cites.aop

  nextcloud-web:
    image: caddy:2.5.1-alpine
    container_name: nextcloud-web
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - nextcloud-caddy-data:/data
      - nextcloud-caddy-config:/config
    volumes_from:
      - nextcloud-app

  nextcloud-collabora:
    image: collabora/code:21.11.4.2.1
    container_name: nextcloud-collabora
    restart: unless-stopped
    ports:
      - 9980:9980
    volumes:
      - /etc/localtime:/etc/localtime:ro
    depends_on:
      - nextcloud-web
    environment:
      - username=admin
      - password=password
      - dictionaries=en_US es_ES pt_BR
      - extra_params=--o:ssl.enable=false

volumes:
  nextcloud-app:
  nextcloud-db:
  nextcloud-caddy-data:
  nextcloud-caddy-config:

Ports exposed on localhost: 80, 443, 9000 and 9980.

Caddy (here named “nextcloud-web”) will have access to static files using:

    volumes_from:
      - nextcloud-app

First attempt will be with this Caddyfile (copied from Wiki and with little adjustments):

{
        debug

        acme_server
        tls internal
}

nextcloud.local.cites.aop {

        encode gzip

        @collabora {
                path /browser/*
                path /hosting/discovery
                path /hosting/capabilities
                path /cool/*
        }

        reverse_proxy @collabora https://127.0.0.1:9980 {
                header_up Host "nextcloud.local.cites.aop"
                transport http {
                        tls_insecure_skip_verify
                }
        }

        root * /var/www/html
        file_server

        php_fastcgi 127.0.0.1:9000 {
                env front_controller_active true # Remove index.php form url
        }

        header {
                Strict-Transport-Security max-age=31536000; # enable HSTS
        }

        # .htaccess / data / config / ... shouldn't be accessible from outside
        @forbidden {
                path /.htaccess
                path /data/*
                path /config/*
                path /db_structure
                path /.xml
                path /README
                path /3rdparty/*
                path /lib/*
                path /templates/*
                path /occ
                path /console.php
        }

        respond @forbidden 404
}

What I did with above configuration and results below:

(1) $ docker-compose up -d ; docker logs -f nextcloud-web

[+] Running 10/10
 ⠿ Network nextcloud_default                  Created                                                                                              0.0s
 ⠿ Volume "nextcloud_nextcloud-caddy-config"  Created                                                                                              0.0s
 ⠿ Volume "nextcloud_nextcloud-db"            Created                                                                                              0.0s
 ⠿ Volume "nextcloud_nextcloud-app"           Created                                                                                              0.0s
 ⠿ Volume "nextcloud_nextcloud-caddy-data"    Created                                                                                              0.0s
 ⠿ Container nextcloud-db                     Started                                                                                              0.7s
 ⠿ Container nextcloud-cache                  Started                                                                                              0.7s
 ⠿ Container nextcloud-app                    Started                                                                                              1.0s
 ⠿ Container nextcloud-web                    Started                                                                                              1.4s
 ⠿ Container nextcloud-collabora              Started                                                                                              1.7s
{"level":"info","ts":1652021188.814965,"msg":"using provided configuration","config_file":"/etc/caddy/Caddyfile","config_adapter":"caddyfile"}
{"level":"warn","ts":1652021188.8267128,"msg":"Caddyfile input is not formatted; run the 'caddy fmt' command to fix inconsistencies","adapter":"caddyfile","file":"/etc/caddy/Caddyfile","line":6}
{"level":"info","ts":1652021188.8305697,"logger":"admin","msg":"admin endpoint started","address":"tcp/localhost:2019","enforce_origin":false,"origins":["//127.0.0.1:2019","//localhost:2019","//[::1]:2019"]}
{"level":"info","ts":1652021188.8317742,"logger":"tls.cache.maintenance","msg":"started background certificate maintenance","cache":"0xc0004a1960"}
{"level":"info","ts":1652021188.8329644,"logger":"http","msg":"server is listening only on the HTTPS port but has no TLS connection policies; adding one to enable TLS","server_name":"srv0","https_port":443}
{"level":"info","ts":1652021188.833018,"logger":"http","msg":"enabling automatic HTTP->HTTPS redirects","server_name":"srv0"}
{"level":"warn","ts":1652021188.9328918,"logger":"pki.ca.local","msg":"installing root certificate (you might be prompted for password)","path":"storage:pki/authorities/local/root.crt"}
{"level":"info","ts":1652021188.9334302,"msg":"define JAVA_HOME environment variable to use the Java trust"}
{"level":"info","ts":1652021188.933445,"msg":"Warning: \"certutil\" is not available, install \"certutil\" with \"apt install libnss3-tools\" or \"yum install nss-tools\" and try again"}
{"level":"info","ts":1652021188.9717364,"msg":"certificate installed properly in linux trusts"}
{"level":"debug","ts":1652021188.9720566,"logger":"http","msg":"starting server loop","address":"[::]:443","http3":false,"tls":true}
{"level":"debug","ts":1652021188.9722614,"logger":"http","msg":"starting server loop","address":"[::]:80","http3":false,"tls":false}
{"level":"info","ts":1652021188.972274,"logger":"http","msg":"enabling automatic TLS certificate management","domains":["nextcloud.local.cites.aop"]}
{"level":"info","ts":1652021188.9724083,"msg":"autosaved config (load with --resume flag)","file":"/config/caddy/autosave.json"}
{"level":"info","ts":1652021188.9724183,"msg":"serving initial configuration"}
{"level":"info","ts":1652021188.9725761,"logger":"tls","msg":"cleaning storage unit","description":"FileStorage:/data/caddy"}
{"level":"info","ts":1652021188.9726126,"logger":"tls","msg":"finished cleaning storage units"}
{"level":"info","ts":1652021188.9727461,"logger":"tls.obtain","msg":"acquiring lock","identifier":"nextcloud.local.cites.aop"}
{"level":"info","ts":1652021188.9816194,"logger":"tls.obtain","msg":"lock acquired","identifier":"nextcloud.local.cites.aop"}
{"level":"debug","ts":1652021188.9822605,"logger":"tls.obtain","msg":"trying issuer 1/1","issuer":"local"}
{"level":"debug","ts":1652021188.982567,"logger":"pki.ca.local","msg":"using intermediate signer","serial":"233056590805575220374369468503360849510","not_before":"2022-05-08 14:46:28 +0000 UTC","not_after":"2022-05-15 14:46:28 +0000 UTC"}
{"level":"info","ts":1652021188.9843614,"logger":"tls.obtain","msg":"certificate obtained successfully","identifier":"nextcloud.local.cites.aop"}
{"level":"info","ts":1652021188.9843857,"logger":"tls.obtain","msg":"releasing lock","identifier":"nextcloud.local.cites.aop"}
{"level":"warn","ts":1652021188.9850678,"logger":"tls","msg":"stapling OCSP","error":"no OCSP stapling for [nextcloud.local.cites.aop]: no OCSP server specified in certificate","identifiers":["nextcloud.local.cites.aop"]}
{"level":"debug","ts":1652021188.9851015,"logger":"tls.cache","msg":"added certificate to cache","subjects":["nextcloud.local.cites.aop"],"expiration":1652064388,"managed":true,"issuer_key":"local","hash":"6488d7afb204c6003da625da76becf2ab8d49f1c440e397be777122e494d1aa7","cache_size":1,"cache_capacity":10000}

(2) open http://nextcloud.local.cites.aop in Firefox, warning about certificate

{"level":"debug","ts":1652021429.1985624,"logger":"tls.handshake","msg":"choosing certificate","identifier":"nextcloud.local.cites.aop","num_choices":1}
{"level":"debug","ts":1652021429.198604,"logger":"tls.handshake","msg":"default certificate selection results","identifier":"nextcloud.local.cites.aop","subjects":["nextcloud.local.cites.aop"],"managed":true,"issuer_key":"local","hash":"6488d7afb204c6003da625da76becf2ab8d49f1c440e397be777122e494d1aa7"}
{"level":"debug","ts":1652021429.1986113,"logger":"tls.handshake","msg":"matched certificate in cache","subjects":["nextcloud.local.cites.aop"],"managed":true,"expiration":1652064388,"hash":"6488d7afb204c6003da625da76becf2ab8d49f1c440e397be777122e494d1aa7"}
{"level":"debug","ts":1652021429.2143114,"logger":"http.stdlib","msg":"http: TLS handshake error from 10.22.22.33:60770: remote error: tls: unknown certificate authority"}

(3) accepted certificate in Firefox = blank page on Firefox, logs bellow

{"level":"debug","ts":1652021509.9429865,"logger":"tls.handshake","msg":"choosing certificate","identifier":"nextcloud.local.cites.aop","num_choices":1}
{"level":"debug","ts":1652021509.9430203,"logger":"tls.handshake","msg":"default certificate selection results","identifier":"nextcloud.local.cites.aop","subjects":["nextcloud.local.cites.aop"],"managed":true,"issuer_key":"local","hash":"6488d7afb204c6003da625da76becf2ab8d49f1c440e397be777122e494d1aa7"}
{"level":"debug","ts":1652021509.943027,"logger":"tls.handshake","msg":"matched certificate in cache","subjects":["nextcloud.local.cites.aop"],"managed":true,"expiration":1652064388,"hash":"6488d7afb204c6003da625da76becf2ab8d49f1c440e397be777122e494d1aa7"}
{"level":"debug","ts":1652021509.960171,"logger":"http.handlers.rewrite","msg":"rewrote request","request":{"remote_ip":"10.22.22.33","remote_port":"60779","proto":"HTTP/2.0","method":"GET","host":"nextcloud.local.cites.aop","uri":"/","headers":{"Sec-Fetch-Site":["none"],"Sec-Fetch-User":["?1"],"Te":["trailers"],"User-Agent":["Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:100.0) Gecko/20100101 Firefox/100.0"],"Accept-Language":["pt-BR,pt;q=0.8,en-US;q=0.5,en;q=0.3"],"Upgrade-Insecure-Requests":["1"],"Sec-Fetch-Dest":["document"],"Accept":["text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8"],"Accept-Encoding":["gzip, deflate, br"],"Sec-Fetch-Mode":["navigate"]},"tls":{"resumed":false,"version":772,"cipher_suite":4867,"proto":"h2","server_name":"nextcloud.local.cites.aop"}},"method":"GET","uri":"/index.php"}
{"level":"debug","ts":1652021509.9602332,"logger":"http.handlers.reverse_proxy","msg":"selected upstream","dial":"127.0.0.1:9000","total_upstreams":1}
{"level":"debug","ts":1652021509.960351,"logger":"http.reverse_proxy.transport.fastcgi","msg":"roundtrip","request":{"remote_ip":"10.22.22.33","remote_port":"60779","proto":"HTTP/2.0","method":"GET","host":"nextcloud.local.cites.aop","uri":"/index.php","headers":{"X-Forwarded-For":["10.22.22.33"],"X-Forwarded-Proto":["https"],"User-Agent":["Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:100.0) Gecko/20100101 Firefox/100.0"],"Accept-Language":["pt-BR,pt;q=0.8,en-US;q=0.5,en;q=0.3"],"Sec-Fetch-User":["?1"],"Accept":["text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8"],"Sec-Fetch-Mode":["navigate"],"X-Forwarded-Host":["nextcloud.local.cites.aop"],"Upgrade-Insecure-Requests":["1"],"Sec-Fetch-Dest":["document"],"Sec-Fetch-Site":["none"],"Te":["trailers"],"Accept-Encoding":["gzip, deflate, br"]},"tls":{"resumed":false,"version":772,"cipher_suite":4867,"proto":"h2","server_name":"nextcloud.local.cites.aop"}},"dial":"127.0.0.1:9000","env":{"PATH_INFO":"","SERVER_PROTOCOL":"HTTP/2.0","HTTP_SEC_FETCH_SITE":"none","REMOTE_IDENT":"","QUERY_STRING":"","REMOTE_USER":"","SERVER_PORT":"443","SSL_CIPHER":"TLS_CHACHA20_POLY1305_SHA256","GATEWAY_INTERFACE":"CGI/1.1","front_controller_active":"true","HTTP_X_FORWARDED_FOR":"10.22.22.33","SSL_PROTOCOL":"TLSv1.3","REMOTE_HOST":"10.22.22.33","DOCUMENT_ROOT":"/var/www/html","DOCUMENT_URI":"/index.php","SCRIPT_FILENAME":"/var/www/html/index.php","HTTPS":"on","AUTH_TYPE":"","CONTENT_TYPE":"","REMOTE_ADDR":"10.22.22.33","HTTP_ACCEPT_LANGUAGE":"pt-BR,pt;q=0.8,en-US;q=0.5,en;q=0.3","CONTENT_LENGTH":"","REQUEST_METHOD":"GET","REQUEST_SCHEME":"https","SERVER_SOFTWARE":"Caddy/v2.5.1","SCRIPT_NAME":"/index.php","HTTP_SEC_FETCH_MODE":"navigate","HTTP_X_FORWARDED_PROTO":"https","HTTP_USER_AGENT":"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:100.0) Gecko/20100101 Firefox/100.0","REMOTE_PORT":"60779","HTTP_X_FORWARDED_HOST":"nextcloud.local.cites.aop","HTTP_SEC_FETCH_DEST":"document","HTTP_ACCEPT_ENCODING":"gzip, deflate, br","HTTP_HOST":"nextcloud.local.cites.aop","HTTP_ACCEPT":"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8","HTTP_SEC_FETCH_USER":"?1","HTTP_TE":"trailers","SERVER_NAME":"nextcloud.local.cites.aop","HTTP_UPGRADE_INSECURE_REQUESTS":"1","REQUEST_URI":"/"}}
{"level":"debug","ts":1652021509.9605653,"logger":"http.handlers.reverse_proxy","msg":"upstream roundtrip","upstream":"127.0.0.1:9000","duration":0.000310771,"request":{"remote_ip":"10.22.22.33","remote_port":"60779","proto":"HTTP/2.0","method":"GET","host":"nextcloud.local.cites.aop","uri":"/index.php","headers":{"Accept":["text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8"],"Sec-Fetch-Mode":["navigate"],"X-Forwarded-For":["10.22.22.33"],"X-Forwarded-Proto":["https"],"User-Agent":["Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:100.0) Gecko/20100101 Firefox/100.0"],"Accept-Language":["pt-BR,pt;q=0.8,en-US;q=0.5,en;q=0.3"],"Sec-Fetch-User":["?1"],"Te":["trailers"],"Accept-Encoding":["gzip, deflate, br"],"X-Forwarded-Host":["nextcloud.local.cites.aop"],"Upgrade-Insecure-Requests":["1"],"Sec-Fetch-Dest":["document"],"Sec-Fetch-Site":["none"]},"tls":{"resumed":false,"version":772,"cipher_suite":4867,"proto":"h2","server_name":"nextcloud.local.cites.aop"}},"error":"dialing backend: dial tcp 127.0.0.1:9000: connect: connection refused"}
{"level":"error","ts":1652021509.96104,"logger":"http.log.error","msg":"dialing backend: dial tcp 127.0.0.1:9000: connect: connection refused","request":{"remote_ip":"10.22.22.33","remote_port":"60779","proto":"HTTP/2.0","method":"GET","host":"nextcloud.local.cites.aop","uri":"/","headers":{"Upgrade-Insecure-Requests":["1"],"Sec-Fetch-Dest":["document"],"Sec-Fetch-Site":["none"],"Sec-Fetch-User":["?1"],"Te":["trailers"],"User-Agent":["Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:100.0) Gecko/20100101 Firefox/100.0"],"Accept-Language":["pt-BR,pt;q=0.8,en-US;q=0.5,en;q=0.3"],"Sec-Fetch-Mode":["navigate"],"Accept":["text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8"],"Accept-Encoding":["gzip, deflate, br"]},"tls":{"resumed":false,"version":772,"cipher_suite":4867,"proto":"h2","server_name":"nextcloud.local.cites.aop"}},"duration":0.001083144,"status":502,"err_id":"d0akjm4w6","err_trace":"reverseproxy.statusError (reverseproxy.go:1196)"}
{"level":"debug","ts":1652021509.9853601,"logger":"http.handlers.rewrite","msg":"rewrote request","request":{"remote_ip":"10.22.22.33","remote_port":"60779","proto":"HTTP/2.0","method":"GET","host":"nextcloud.local.cites.aop","uri":"/favicon.ico","headers":{"Sec-Fetch-Mode":["no-cors"],"Te":["trailers"],"User-Agent":["Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:100.0) Gecko/20100101 Firefox/100.0"],"Accept":["image/avif,image/webp,*/*"],"Accept-Language":["pt-BR,pt;q=0.8,en-US;q=0.5,en;q=0.3"],"Accept-Encoding":["gzip, deflate, br"],"Referer":["https://nextcloud.local.cites.aop/"],"Sec-Fetch-Dest":["image"],"Sec-Fetch-Site":["same-origin"]},"tls":{"resumed":false,"version":772,"cipher_suite":4867,"proto":"h2","server_name":"nextcloud.local.cites.aop"}},"method":"GET","uri":"index.php"}
{"level":"debug","ts":1652021509.9854026,"logger":"http.handlers.reverse_proxy","msg":"selected upstream","dial":"127.0.0.1:9000","total_upstreams":1}
{"level":"debug","ts":1652021509.9854846,"logger":"http.reverse_proxy.transport.fastcgi","msg":"roundtrip","request":{"remote_ip":"10.22.22.33","remote_port":"60779","proto":"HTTP/2.0","method":"GET","host":"nextcloud.local.cites.aop","uri":"index.php","headers":{"Accept-Language":["pt-BR,pt;q=0.8,en-US;q=0.5,en;q=0.3"],"X-Forwarded-Proto":["https"],"X-Forwarded-Host":["nextcloud.local.cites.aop"],"Sec-Fetch-Mode":["no-cors"],"Accept-Encoding":["gzip, deflate, br"],"Sec-Fetch-Dest":["image"],"Sec-Fetch-Site":["same-origin"],"Te":["trailers"],"Referer":["https://nextcloud.local.cites.aop/"],"User-Agent":["Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:100.0) Gecko/20100101 Firefox/100.0"],"Accept":["image/avif,image/webp,*/*"],"X-Forwarded-For":["10.22.22.33"]},"tls":{"resumed":false,"version":772,"cipher_suite":4867,"proto":"h2","server_name":"nextcloud.local.cites.aop"}},"dial":"127.0.0.1:9000","env":{"GATEWAY_INTERFACE":"CGI/1.1","REMOTE_USER":"","SERVER_PROTOCOL":"HTTP/2.0","DOCUMENT_URI":"index.php","SCRIPT_FILENAME":"/var/www/html/index.php","HTTP_ACCEPT":"image/avif,image/webp,*/*","QUERY_STRING":"","REQUEST_URI":"/favicon.ico","SSL_PROTOCOL":"TLSv1.3","HTTP_REFERER":"https://nextcloud.local.cites.aop/","HTTP_SEC_FETCH_DEST":"image","HTTP_SEC_FETCH_MODE":"no-cors","REMOTE_IDENT":"","HTTP_HOST":"nextcloud.local.cites.aop","HTTPS":"on","SSL_CIPHER":"TLS_CHACHA20_POLY1305_SHA256","HTTP_X_FORWARDED_HOST":"nextcloud.local.cites.aop","CONTENT_TYPE":"","REMOTE_ADDR":"10.22.22.33","SCRIPT_NAME":"/index.php","HTTP_X_FORWARDED_PROTO":"https","HTTP_ACCEPT_ENCODING":"gzip, deflate, br","CONTENT_LENGTH":"","SERVER_PORT":"443","HTTP_ACCEPT_LANGUAGE":"pt-BR,pt;q=0.8,en-US;q=0.5,en;q=0.3","PATH_INFO":"","SERVER_NAME":"nextcloud.local.cites.aop","DOCUMENT_ROOT":"/var/www/html","HTTP_SEC_FETCH_SITE":"same-origin","HTTP_TE":"trailers","REQUEST_METHOD":"GET","REQUEST_SCHEME":"https","SERVER_SOFTWARE":"Caddy/v2.5.1","front_controller_active":"true","AUTH_TYPE":"","REMOTE_HOST":"10.22.22.33","REMOTE_PORT":"60779","HTTP_X_FORWARDED_FOR":"10.22.22.33","HTTP_USER_AGENT":"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:100.0) Gecko/20100101 Firefox/100.0"}}
{"level":"debug","ts":1652021509.9856958,"logger":"http.handlers.reverse_proxy","msg":"upstream roundtrip","upstream":"127.0.0.1:9000","duration":0.000265649,"request":{"remote_ip":"10.22.22.33","remote_port":"60779","proto":"HTTP/2.0","method":"GET","host":"nextcloud.local.cites.aop","uri":"index.php","headers":{"Referer":["https://nextcloud.local.cites.aop/"],"User-Agent":["Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:100.0) Gecko/20100101 Firefox/100.0"],"Accept":["image/avif,image/webp,*/*"],"X-Forwarded-For":["10.22.22.33"],"X-Forwarded-Host":["nextcloud.local.cites.aop"],"Sec-Fetch-Mode":["no-cors"],"Accept-Encoding":["gzip, deflate, br"],"Sec-Fetch-Dest":["image"],"Sec-Fetch-Site":["same-origin"],"Te":["trailers"],"Accept-Language":["pt-BR,pt;q=0.8,en-US;q=0.5,en;q=0.3"],"X-Forwarded-Proto":["https"]},"tls":{"resumed":false,"version":772,"cipher_suite":4867,"proto":"h2","server_name":"nextcloud.local.cites.aop"}},"error":"dialing backend: dial tcp 127.0.0.1:9000: connect: connection refused"}
{"level":"error","ts":1652021509.9857433,"logger":"http.log.error","msg":"dialing backend: dial tcp 127.0.0.1:9000: connect: connection refused","request":{"remote_ip":"10.22.22.33","remote_port":"60779","proto":"HTTP/2.0","method":"GET","host":"nextcloud.local.cites.aop","uri":"/favicon.ico","headers":{"Sec-Fetch-Mode":["no-cors"],"Referer":["https://nextcloud.local.cites.aop/"],"Sec-Fetch-Dest":["image"],"Sec-Fetch-Site":["same-origin"],"Te":["trailers"],"User-Agent":["Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:100.0) Gecko/20100101 Firefox/100.0"],"Accept":["image/avif,image/webp,*/*"],"Accept-Language":["pt-BR,pt;q=0.8,en-US;q=0.5,en;q=0.3"],"Accept-Encoding":["gzip, deflate, br"]},"tls":{"resumed":false,"version":772,"cipher_suite":4867,"proto":"h2","server_name":"nextcloud.local.cites.aop"}},"duration":0.000493696,"status":502,"err_id":"ki5ye89vh","err_trace":"reverseproxy.statusError (reverseproxy.go:1196)"}