Nextcloud docker compose setup with Caddy (2024)

OK. I did a speedrun for you with the tutorial above. No editing, nothing more. That’s enough to get me to the point where I can execute the command you described at the beginning and get a direct answer that I can work with, which on the one hand makes your question obsolete and on the other hand perhaps explains the problems you’re having:

$ docker compose exec app php occ app:remove circles
circles could not be removed as it is a shipped app

Well, I couldn’t know that because I didn’t try it directly or in the past and apparently there aren’t really any topics on the subject. However, I could imagine that you don’t get this message in the first place, so I will share my speedrun. Could this become a sport? Nextcloud installation speedrun. Like the case modding overclocker competitions of old, where all the hardware had to be unpacked, installed and connected… All on time… I digress…

command list
/docker$ mkdir nextcloud_tmp
/docker$ cd nextcloud_tmp/
/docker/nextcloud_tmp$ DOCKER_PROJECT_DIR=/docker
/docker/nextcloud_tmp$ nano .env
/docker/nextcloud_tmp$ nano nextcloud.env
/docker/nextcloud_tmp$ mkdir web
/docker/nextcloud_tmp$ nano web/Caddyfile
/docker/nextcloud_tmp$ nano docker-compose.yml
/docker/nextcloud_tmp$ mkdir secrets 
echo -n "admin" > ./secrets/nextcloud_admin_user
echo -n "nextcloud" > ./secrets/postgres_db
echo -n "nextcloud" > ./secrets/postgres_user
tr -dc 'A-Za-z0-9#$%&+_' < /dev/urandom | head -c 32 | tee ./secrets/postgres_password; echo
tr -dc 'A-Za-z0-9#$%&+_' < /dev/urandom | head -c 32 | tee ./secrets/nextcloud_admin_password; echo
tr -dc 'A-Za-z0-9#$%&+_' < /dev/urandom | head -c 32 | tee ./secrets/redis_password; echo
HK%GFXfPpQ4uXSCh#Bh2xH5arK71liqw
CQ64OViSIsNtNs_kle67U6jeA3Wh%IKY
%7s2iYR8PqJmCl0qgg4dvLXfPHe9BfHv
/docker/nextcloud_tmp$ sudo mkdir /HDD/nextcloud_tmp
/docker/nextcloud_tmp$ sudo chown $USER:$USER /HDD/nextcloud_tmp
/docker/nextcloud_tmp$ DH_DATA_DIR=/HDD/nextcloud_tmp/data
/docker/nextcloud_tmp$ mkdir -p apps config data db nextcloud redis web/data web/config $DH_DATA_DIR
/docker/nextcloud_tmp$ touch redis-session.ini
/docker/nextcloud_tmp$ sudo chown 1004:1004 apps config data db nextcloud redis redis-session.ini web/data web/config web/Caddyfile $DH_DATA_DIR
/docker/nextcloud_tmp$ tree -a ${DOCKER_PROJECT_DIR}/nextcloud_tmp/
/docker/nextcloud_tmp/
├── apps
├── config
├── data
├── db
├── docker-compose.yml
├── .env
├── nextcloud
├── nextcloud.env
├── redis
├── redis-session.ini
├── secrets
│   ├── nextcloud_admin_password
│   ├── nextcloud_admin_user
│   ├── postgres_db
│   ├── postgres_password
│   ├── postgres_user
│   └── redis_password
└── web
    ├── Caddyfile
    ├── config
    └── data

11 directories, 11 files
/docker/nextcloud_tmp$ docker compose up -d
[+] Running 1/1
 ✔ web Pulled                                                                                                           2.5s 
[+] Running 6/7
 ✔ Network nextcloud_tmp_default          Created                                                                       0.2s 
 ✔ Container nextcloud_tmp-redis-1        Healthy                                                                       7.6s 
 ✔ Container nextcloud_tmp-db-1           Healthy                                                                       7.6s 
 ✔ Container nextcloud_tmp-app-1          Started                                                                       7.8s 
 ✔ Container nextcloud_tmp-web-1          Started                                                                       8.6s 
 ✔ Container nextcloud_tmp-imaginary-1    Started                                                                       8.4s 
 ⠹ Container nextcloud_tmp-notify_push-1  Starting                                                                     10.3s 
Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "/var/www/html/custom_apps/notify_push/bin/x86_64/notify_push": stat /var/www/html/custom_apps/notify_push/bin/x86_64/notify_push: no such file or directory: unknown
/docker/nextcloud_tmp$ docker compose exec app php occ app:remove circles
circles could not be removed as it is a shipped app
/docker/nextcloud_tmp$ 

I did this with NEXTCLOUD_VERSION=29.0.8-fpm, next to my live system. For the sake of simplicity, I have used the user of the live instance 1004.

I do not indeed get that error, and i also tried to remove richdocuments and some other apps which should be removable (also in the gui).
I also forgot to mention i instaled nextcloud 30.0.2

Awesome guide, thank you very much @estebanium

I also got stuck on the login loop; I followed your guide along with my trusty companion, a chatgpt instance (i use duck duck go’s) and it is an invaluable asset for ruber duck debuggin this issues (sometimes). After some troubleshooting and adding NEXTCLOUD_LOG_LEVEL=debug to the nextcloud.env file I found after restarting the containers the following line:
db-1 | 2024-12-15 15:00:07.794 CET [243] FATAL: role "MYUSERNAME" does not exist

I haven’t fixed the error yet due to lack of time, but I wanted to post my findings for others that may be in the same situation I am. Some things that I found very useful while troubleshooting:

  • rubber duck debugging with chat gpt
  • having three terminals open, one with the logs for nextcloud, other with the logs for caddy and a last one to interact with both

When I get to fix the error I will report it here. Thanks to everyone for posting your findings!

Could you expand on why one would like to install imaginary and how does it differ from the previewgenerator app one can install? (And should I use one or both?)

Thanks for the guide, it was very usefull!

1 Like

The simple answer is that you don’t necessarily have to use Imaginary and can just install the Preview Generator app. If only the Preview Generator app is installed, the previews are generated with the Nextcloud on-board tools. The on-board tools work with PHP and although this is basically a great language for web applications, it is not efficient for generating preview images. That’s why Imaginary is used. And also to your question: this is not an either or, but in addition to the Preview Generator you also install Imaginary. You then specify Imaginary in the Preview Generator settings. The latter is created precisely for the use case and therefore works more efficiently and faster.

Finally:

  • Preview Generator
  • Preview Generator + Imaginary

Thanks for the reply! I ended up installing both of them.

This interests me (I tried the standard preview:generate-all and it was super slow). How can I change the app to use imaginary?

You’re welcome. It is described in “Setup imaginary”. You will likely already have a section in your config.php with OC\\Preview\\ with some file formats. You need to add these lines (by command or with an editor) to the config.php:

docker compose exec app php occ config:system:set enabledPreviewProviders 5 --value 'OC\Preview\Imaginary'
docker compose exec app php occ config:system:set preview_imaginary_url --value 'http://imaginary:9000'
# limit number of parallel jobs (adopt to your CPU core number)
docker compose exec app php occ config:system:set preview_concurrency_all --value 12
docker compose exec app php occ config:system:set preview_concurrency_new --value 8

If you want to add the entries by the commands above, you will need to pay attention to the 5. When you follow my tutorial, Imaginary will be the sixth entry (6-1=5), because we start to count on 0. I don’t know, how may entries your array already has. Using the wrong number, will result in an overwrite or an inappropriate configuration. Just for reference an example of such an array, when you are done and used the 3 for the following command:
docker compose exec app php occ config:system:set enabledPreviewProviders 3 --value 'OC\Preview\Imaginary'

'enabledPreviewProviders' =>
  array (
  0 => 'OC\\Preview\\something1',
  1 => 'OC\\Preview\\something2',
  2 => 'OC\\Preview\\something3',
  3 => 'OC\\Preview\\Imaginary',
),
'preview_imaginary_url' => 'http://imaginary:9000',

Edit:
If you set up Imaginary as it is described in the tutorial, this is really a no brainer. However, if you changed the port configuration or the hostname of the Imaginary docker container, you will need to adjust the url and port stated in the command.

1 Like

Hi @estebanium,

this is not correct what you did here:

  • OC\Preview\Imaginary
    Imaginary supports these MIME types:
    • image/bmp
    • image/x-bitmap
    • image/png
    • image/jpeg
    • image/gif
    • image/heic
    • image/heif
    • image/svg+xml
    • image/tiff
    • image/webp
    • application/illustrator
    • application/pdf (NC < 30)

and

  • OC\Preview\ImaginaryPDF (since NC 30)
    • application/pdf

so the legacy preview providers

  0 => 'OC\\Preview\\PNG',
  1 => 'OC\\Preview\\JPEG',
  2 => 'OC\\Preview\\GIF',
  3 => 'OC\\Preview\\HEIC',
  4 => 'OC\\Preview\\BMP',
  5 => 'OC\\Preview\\XBitmap',

and

  13 => 'OC\\Preview\\PDF',

… are not only no longer necessary but should also no longer be used if Imaginary is used and you want to take full advantage of its performance.

And then there is the preview provider

  9 => 'OC\\Preview\\Movie',

but there are no

  10 => 'OC\\Preview\\MKV',
  11 => 'OC\\Preview\\MP4',
  12 => 'OC\\Preview\\AVI',

preview providers. You probably thought them up yourself but they don’t exist so those lines don’t do anything.

You can read more details about preview providers here, where I explained it more in deep.

h.t.h.


Much and good luck,
ernolf

Thank you for your reply to this. I’m changing it to a more generic example, because that’s it as you already noticed. Don’t let them do stupid things.

Hi. I follow through this guide and did work well. I’m building this to have locally.
But I don’t like to have things not updated. So can I change the versions of NC and postgre In the configs to install the updated ones? In this case change NEXTCLOUD_VERSION=29.0.7-fpm to 30.0.05-fpm-alpine and db:image: postgres:15 to 17.2-bookworm or just 17.2 ?

And after that, how should I proceed to update without any problems? Because I tried to update and it stopped working (most probably I’ve made it wrong)

I’m glad that the guide has helped you. In principle, you can of course make updates and also upgrade to the next major release. The requirements and procedure are officially described and hopefully you have complied with them.

The situation is different when it comes to updating dependencies such as PostgreSQL. Presumably you chose PostgreSQL 17 because it is listed in the official documentation? Here it depends on whether you used the version from the guide and then wanted to upgrade to 17 or whether you already started with version 17. The former is not a simple swap of the version string, is not officially described and can be complex. You can find the procedure on the Internet.

Hello, this has been a fantastic guide to setting up both Caddy and Redis for me.

I was wondering, how would I go about setting up Collabora with this set-up?

1 Like

Hello Adjule,

I’m glad that the guide has helped you. Much of it would not have been possible without wwe. wwe has also published a tutorial on Collabora, which I used in particular to configure Nextcloud. Have a look there if you have any questions about the last steps.

Of course I have also created and documented something for my Collabora. However, I haven’t yet found the time to add it to the existing concept of stacks here. The documentation is a bit more specialized because I really wanted to use Docker Secrets, so the stack uses a Dockerfile. However, it is otherwise as “easy” to use as the existing tutorial.

Zusammenfassung

The Collabora Stack: Creation of the required files

Setup a directory for our projekt:
DOCKER_PROJECT_DIR=/docker

mkdir -p ${DOCKER_PROJECT_DIR}/collabora
cd ${DOCKER_PROJECT_DIR}/collabora

.env

As in the previous stacks, the .env file is responsible for the basic configuration. Although the scope here is significantly smaller than in the other stacks.

vim ${DOCKER_PROJECT_DIR}/collabora/.env

.env
# project name is used as container name prefix (folder name if not set)
COMPOSE_PROJECT_NAME=collabora-prod
# this is the global ENV file for docker-compose
# collabora FQDN - public DNS
DOMAIN=office.example.com
DOCKER_LOGGING_MAX_SIZE=5m
DOCKER_LOGGING_MAX_FILE=3

collabora.env

collabora.env
aliasgroup1=${DOMAIN}:443
username_FILE=/run/secrets/collabora_user
password_FILE=/run/secrets/collabora_admin_password
extra_params="--o:ssl.enable=false --o:ssl.termination=true"

:bulb: By default Collabora Online enables the first WOPI host that tries to connect. You can define the allowed WOPI hosts by passing environment variables. The FQDN of the Nextcloud instance must be entered under variable aliasgroup1, e.g. for aliasgroup1=https://${DOMAIN}:443 the domain cloud.domain.tdl is entered. This ensures that the Collabora server can only be used by the Nextcloud instance.

Dockerfile

Unfortunately, the Collabora image does not support Docker secrets by default. I have helped myself by editing the Docker image with a Dockerfile. I add a function in the start-collabora-online.sh with sed, which translates all environment variables ending in _FILE into the corresponding environment variable. The script could be adapted so that only certain variables can be set in this way. Such as username or password. The anchor for the insertion is the line # Start coolwsd.

Dockerfile
FROM collabora/code:24.04.8.1.1

USER root

# link: https://github.com/CollaboraOnline/online/blob/master/docker/from-packages/scripts/start-collabora-online.sh
RUN sed -i 's/# Start coolwsd/# Function to read environment variables with _FILE suffix\nset_env_from_file() {\n  for var in $(env | grep \x27_FILE=\x27); do\n    var_name="${var%%_FILE=*}"\n    file_path="${var#*=}"\n\n    if [ -f "$file_path" ]; then\n      export "$var_name"="$(cat "$file_path")"\n    fi\n  done\n}\n\n# Call the function to set environment variables from files\nset_env_from_file\n\n# Start coolwsd/g' /start-collabora-online.sh

RUN chmod 755 /start-collabora-online.sh

USER 100

The final script, that is added to start-collabora-online.sh:

# Function to read environment variables with _FILE suffix
set_env_from_file() {
  for var in $(env | grep '_FILE='); do
    # Extract the variable name without the _FILE suffix
    var_name="${var%%_FILE=*}"
    # Extract the file path
    file_path="${var#*=}"
    # Read the file content and export it as the environment variable
    if [ -f "$file_path" ]; then
      export "$var_name"="$(cat "$file_path")"
    fi
  done
}

# Call the function to set environment variables from files
set_env_from_file

# Start coolwsd

Collabora Stack (docker-compose.yml)

The Docker compose then looks like this:

docker-compose.yml
networks:
  proxy:
    external: true

secrets:
  collabora_user:
    file: ./secrets/collabora_user # put admin user in this file
  collabora_admin_password:
    file: ./secrets/collabora_admin_password # put admin password in this file

services:
  collabora:
    build:
      context: .
    restart: unless-stopped
    cap_add:
      - MKNOD
    privileged: true
    env_file:
      - ./collabora.env
    secrets:
      - collabora_user
      - collabora_admin_password
    networks:
      - default
      - proxy

secrets

Thanks to the customizations using Dockerfile, we can use our usual concept of Docker Secrets. To do this, we create a corresponding folder and generate the password. We can then use the password for the Collabora administration area.

mkdir ${DOCKER_PROJECT_DIR}/colalbora/secrets 
echo -n "admin" > ./secrets/collabora_user
tr -dc 'A-Za-z0-9#$%&+_' < /dev/urandom | head -c 32 | tee ./secrets/collabora_admin_password; echo

Customization of the Caddy Reverse Proxy

The reverse proxy still needs to be adapted so that our Collabora instance can be accessed via a subdomain.

We open the Caddyfile directly via: vim ${DOCKER_PROJECT_DIR}/proxy/Caddyfile and add a new section.

:bulb: The following also applies to this section: The subdomain should already point to your IP address of the reverse proxy or to the Docker host on which the reverse proxy is running via an A record!

docker-compose.yml
office.example.com {
    header {
        # Based on following source:
        # https://raw.githubusercontent.com/nextcloud/docker/refs/heads/master/.examples/docker-compose/insecure/mariadb/fpm/web/nginx.conf
        #
        # 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.
        # Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;"
        Strict-Transport-Security: "max-age=31536000; includeSubDomains;"

        # HTTP response headers borrowed from Nextcloud `.htaccess`
        Referrer-Policy no-referrer
        X-Content-Type-Options nosniff
        X-Download-Options noopen
        X-Frame-Options SAMEORIGIN
        X-Permitted-Cross-Domain-Policies none
        X-Robots-Tag "noindex,nofollow"
        X-XSS-Protection "1; mode=block"

        Permissions-Policy "accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(), cross-origin-isolated=(), display-capture=(), document-domain=(), encrypted-media=(), execution-while-not-rendered=(), execution-while-out-of-viewport=(), fullscreen=(), geolocation=(self), gyroscope=(), keyboard-map=(), magnetometer=(), microphone=(), midi=(), navigation-override=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(), usb=(), web-share=(), xr-spatial-tracking=()"
        Content-Security-Policy upgrade-insecure-requests
    }

    # Source: https://caddy.community/t/help-with-getting-caddy-working-with-nextcloud-and-collabra/14543
    @collabora {
        path /browser/* # Browser is the client part of LibreOffice Online
        path /hosting/discovery # WOPI discovery URL
        path /hosting/capabilities # Show capabilities as json
    }
    reverse_proxy @collabora http://collabora:9980 {
            header_up Host {host}
    }

    # download, presentation and image upload
    @cool path_regexp ^/(c|l)ool/*
    reverse_proxy @cool http://collabora:9980 {
        header_up Host {host}
    }

    # main websocket
    @websocket path_regexp ^/cool/(.*)/ws$
    reverse_proxy @websocket http://collabora:9980 {
        header_up Host {host}
        header_up Upgrade {http.request.header.Upgrade}
        header_up Connection "Upgrade"
        transport http {
            read_timeout 10h
        }
    }

    # Admin Console websocket
    @console path_regexp ^/cool/adminws$
    reverse_proxy @console http://collabora:9980 {
        header_up Host {host}
        header_up Upgrade {http.request.header.Upgrade}
        header_up Connection "Upgrade"
        transport http {
            read_timeout 10h
        }
    }
}

Launch the Collabora Stacks

First start of Collabora

Now is the time to start the stack: docker compose up -d

If the generation of the image does not work or you make adjustments to the Dockerfile, the following command can help to force the generation:
docker compose up -d --force-recreate --build

Testing the connection

A dial-in window should now open at the address https://office.example.com/browser/dist/admin/admin.html and it should be possible to dial in using admin and the password from ./secrets/collabora_admin_password.

Configuration of Nextcloud

After installation, the address of the Collabora server must be communicated to the Nextcloud Office app.

The compose file of the Nextcloud stack is used here, so either use -f to specify the path to the Nextcloud stack docker-compose.yaml or go to the directory of the Nextcloud stack.

  • Installation of the richdocuments app:

    docker compose exec app php occ app:enable richdocuments
    
  • Cofiguration of the CODE server URL:

    # docker compose
    docker compose exec app php occ config:app:set richdocuments wopi_url --value office.example.com
    docker compose exec app php occ richdocuments:activate-config
    
  • The last step must be implemented in the Nextcloud interface

    • Go to the settings of your Nextcloud (user menu top right corner “ Administration settings)
    • Select the Office menu item in the left-hand menu under Administration
    • Select Use your own server and enter the address of your Collabora server (e.g. https://office.example.com)
    • In addition, the Allow list for WOPI requests should be configured so that only the Collabora server can retrieve documents. This can be found further down below the advanced settings. The IPv4 and IPv6 address of the Collabora server must be entered here (e.g. 1.2.3.4,2a01:4f8:aaaa:bbbb:cccc::1).
    • In this case, it is the IP-Address of the host, that serves the reverse proxy. If you think of the picture at the beginning of the tutorial, the host of /docker/proxy:
      In my case 192.168.77.1

    :bulb: The IP address of the Collabora host should be the IP address of the Docker container that it has in the collabora network. You remember? The Collabora and Nextcloud stacks are connected via the proxy network.

    :checkered_flag: A separate Collabora server has been installed and set up in a Nextcloud. When opening documents in the Nextcloud web interface, Collabora is now automatically loaded so that the document can be edited.

1 Like

Thanks for the instructions, I was able to get Collabora all set up on my server.

I had noticed a slight typo on the section explaining how to set up Secrets, where it reads /colalbora/ instead of /collabora/.

Otherwise, I appreciate how thorough this is! Thank you so much for your help.

Dear @estebanium
thanks for this very detailed procedure. Unfortunately It didn’t work for me. I went through all steps up to the starting of the Caddy Stack. All services are up and running (healthy). However it could not generate letsencrypt certificate. I added the 2 NAT rules redirecting 80 and 443 ports to my host.
Nextcloud host is a physical linux server with Debian 12 distribution.
below is the log (masking senstive data). Any help is welcome. Thank you.
Laurent.

log
caddy  | {"level":"error","ts":1742331251.6012962,"msg":"validating authorization","identifier":"nextcloud.xxxxxxxx.com","problem":{"type":"urn:ietf:params:acme:error:connection","title":"","detail":"XX.XX.XX.XX: Fetching http://nextcloud.xxxxxxxx.com/.well-known/acme-challenge/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: Timeout during connect (likely firewall problem)","instance":"","subproblems":null},"order":"https://acme-v02.api.letsencrypt.org/acme/order/2289438286/364960892006","attempt":2,"max_attempts":3,"stacktrace":"github.com/mholt/acmez/v3.(*Client).ObtainCertificate\n\tgithub.com/mholt/acmez/v3@v3.0.0/client.go:152\ngithub.com/caddyserver/certmagic.(*ACMEIssuer).doIssue\n\tgithub.com/caddyserver/certmagic@v0.21.6/acmeissuer.go:477\ngithub.com/caddyserver/certmagic.(*ACMEIssuer).Issue\n\tgithub.com/caddyserver/certmagic@v0.21.6/acmeissuer.go:371\ngithub.com/caddyserver/caddy/v2/modules/caddytls.(*ACMEIssuer).Issue\n\tgithub.com/caddyserver/caddy/v2@v2.9.1/modules/caddytls/acmeissuer.go:249\ngithub.com/caddyserver/certmagic.(*Config).obtainCert.func2\n\tgithub.com/caddyserver/certmagic@v0.21.6/config.go:626\ngithub.com/caddyserver/certmagic.doWithRetry\n\tgithub.com/caddyserver/certmagic@v0.21.6/async.go:104\ngithub.com/caddyserver/certmagic.(*Config).obtainCert\n\tgithub.com/caddyserver/certmagic@v0.21.6/config.go:700\ngithub.com/caddyserver/certmagic.(*Config).ObtainCertAsync\n\tgithub.com/caddyserver/certmagic@v0.21.6/config.go:505\ngithub.com/caddyserver/certmagic.(*Config).manageOne.func1\n\tgithub.com/caddyserver/certmagic@v0.21.6/config.go:415\ngithub.com/caddyserver/certmagic.(*jobManager).worker\n\tgithub.com/caddyserver/certmagic@v0.21.6/async.go:73"}
caddy  | {"level":"error","ts":1742331251.6014621,"logger":"tls.obtain","msg":"could not get certificate from issuer","identifier":"nextcloud.xxxxxxxx.com","issuer":"acme-v02.api.letsencrypt.org-directory","error":"HTTP 400 urn:ietf:params:acme:error:connection - XX.XX.XX.XX: Fetching http://nextcloud.xxxxxxxx.com/.well-known/acme-challenge/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: Timeout during connect (likely firewall problem)"}
caddy  | {"level":"info","ts":1742331251.6017432,"logger":"tls.issuance.acme","msg":"creating new account because no account for configured email is known to us","email":"info@xxxxxxxx.com","ca":"https://acme.zerossl.com/v2/DV90","error":"open /data/caddy/acme/acme.zerossl.com-v2-dv90/users/info@xxxxxxxx.com/info.json: no such file or directory"}
caddy  | {"level":"info","ts":1742331251.6018522,"logger":"tls.issuance.acme","msg":"ACME account has empty status; registering account with ACME server","contact":["mailto:info@xxxxxxxx.com"],"location":""}
caddy  | {"level":"info","ts":1742331251.6038175,"logger":"tls.issuance.acme","msg":"creating new account because no account for configured email is known to us","email":"info@xxxxxxxx.com","ca":"https://acme.zerossl.com/v2/DV90","error":"open /data/caddy/acme/acme.zerossl.com-v2-dv90/users/info@xxxxxxxx.com/info.json: no such file or directory"}
caddy  | {"level":"info","ts":1742331253.5464418,"logger":"http","msg":"generated EAB credentials","key_id":"XXXXXXXXXXXXXXXXXXXXX"}
caddy  | {"level":"info","ts":1742331254.758443,"logger":"tls.issuance.acme","msg":"new ACME account registered","contact":["mailto:info@xxxxxxxx.com"],"status":"valid"}
caddy  | {"level":"info","ts":1742331254.7629824,"logger":"tls.issuance.acme","msg":"waiting on internal rate limiter","identifiers":["nextcloud.xxxxxxxx.com"],"ca":"https://acme.zerossl.com/v2/DV90","account":"info@xxxxxxxx.com"}
caddy  | {"level":"info","ts":1742331254.7630196,"logger":"tls.issuance.acme","msg":"done waiting on internal rate limiter","identifiers":["nextcloud.xxxxxxxx.com"],"ca":"https://acme.zerossl.com/v2/DV90","account":"info@xxxxxxxx.com"}
caddy  | {"level":"info","ts":1742331254.7630687,"logger":"tls.issuance.acme","msg":"using ACME account","account_id":"https://acme.zerossl.com/v2/DV90/account/XXXXXXXXXXXXXXXXXXXXX","account_contact":["mailto:info@xxxxxxxx.com"]}
caddy  | {"level":"info","ts":1742331256.4367092,"msg":"trying to solve challenge","identifier":"nextcloud.xxxxxxxx.com","challenge_type":"http-01","ca":"https://acme.zerossl.com/v2/DV90"}
1 Like

Hi LaurenC,

could you please edit your post and put that log in a code block and a spoiler?

Like so:


[details="description"]
\```
Your log
\```
[/details]

Without the backslash.

It looks like a firewall issue. Either on your debain host, or on your router/firewall. I guess on your debian machine, otherwise you would not be able to reach any website on your debian machine.
Are you able to reach any site on your server?
Could you do curl -v google.com on your server?

here it is. It was able to reach out google.com

log curl -v google.com
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0*   Trying [2a00:1450:4007:810::200e]:80...
* Connected to google.com (2a00:1450:4007:810::200e) port 80 (#0)
> GET / HTTP/1.1
> Host: google.com
> User-Agent: curl/7.88.1
> Accept: */*
>
< HTTP/1.1 301 Moved Permanently
< Location: http://www.google.com/
< Content-Type: text/html; charset=UTF-8
< Content-Security-Policy-Report-Only: object-src 'none';base-uri 'self';script-src 'nonce-NgnGcBjiz2IZKsrKfKwq7g' 'strict-dynamic' 'report-sample' 'unsafe-eval' 'unsafe-inline' https: http:;report-uri https://csp.withgoogle.com/csp/gws/other-hp
< Date: Wed, 19 Mar 2025 07:28:16 GMT
< Expires: Fri, 18 Apr 2025 07:28:16 GMT
< Cache-Control: public, max-age=2592000
< Server: gws
< Content-Length: 219
< X-XSS-Protection: 0
< X-Frame-Options: SAMEORIGIN
<
{ [219 bytes data]
100   219  100   219    0     0   5033      0 --:--:-- --:--:-- --:--:--  4977
* Connection #0 to host google.com left intact

Normally, if you have issues with your A-record not pointing to your public IP address, you would fail the challenge. However, you don’t get to that point. Did you publish any other service in the past, that could verify, that your routers firewall settings work? What router or firewall do you use?

Well, I’ve been using a dockerized version of Nexcloud for years on that server with nginx reverse-proxy service and os Debian 11. But I started from scratch installing a fresh version of Debian 12 and I wanted to benefit from FPM and simplicity of Caddy. That’s why I hit your post. The router is a french internet box (livebox) that I changed recently. I checked successfully that the DNS record is setup correctly by pinging to the IP name. Weird. Quick question : if I want to mess around with the router parameters, should I just restart caddy docker service to test the firewall new setup?

I would restart the container of the reverse proxy. I don’t know if it triggers a retry automatically.