SSL Certificate on Docker Nextcloud Server

Hi! I’m new to this forum and to Nexcloud in general. I have set up a Nextcloud server on a Docker container using a Raspberry Pi. This server is personal for me and my gf, so I have it running locally on my network on port 8080. To connect to it remotely I connect to my network through Wireguard since I use my Raspberry Pi as a VPN so I don’t need to expose my Nextcloud server to the internet nor do I want to.

The other day I was trying to set up my CalDAV server on my iPhone to have my calendars synced on both devices but I couldn’t because I need to set up an SSL certificate on my Nextcloud server so it had HTTPS. The same thing happened when I tried to use the Collabora app, it tells me I can’t because "it uses an insecure protocol (http) ". So now I want to set up an SSL certificate so I can fix both these problems and possible future ones, but the problem is I have never done that before.

So, in this post I’m basically asking for advice and help on setting an SSL certificate on my server (running on a docker container on my local network) to be able to enable HTTPS and access all of these functionalities I mentioned. I googled but I haven’t found a clear tutorial to follow, most mention using Nginx and Certbot but I don’t really know anything about that. If you guys know or find any tutorial that I can follow then that would be deeply appreciated! :slight_smile:

take a look at this post - I describe pretty complete docker setup with traefik - this is cool reverse proxy working really* smooth with docker. with traefik requesting letsencrypt certificates is really easy and it just work

if you don’t like or can’t follow the post just search for docker, traefik and nextcloud in this forum or google/youtube - there are lot of tutorials explaining how to setup nextcloud in docker with traefik.

1 Like

Thank you for the reply! I haven’t heard of Traefik so I will look into it. Will this allow me to keep my network local or will I recquire opening it to the internet? If so, will I need a domain name? By what I see on your post I think I will. Also, since I already have my server running I’m not sure if I should follow your instructions, wouldn’t I lose all my files? Is there a way of doing so without having to set up all of my Nextcloud info again?

I’m sorry for the many questions, I’m still learning about all this stuff so it’s almost all new to me.

traefik and SSL certificate almost always imply opening to the internet. If you keep your system within internal network there is little value in installing SSL certificates (I know theoretically somebody could intercept the data on wire but within internal switched network only the admin can do - so not areal treat). I would never mind enable TLS for internal services - TLS add lot of complexity and provide no value

Public CA would not issue certificate for private domain names - you need to run you own CA or create self-signed certificates for domain names other then real public domains. traefik is good in docker scenarios because it can handle letencrypt SSL certificate requests and renewals itself - with very low prerequisites.

it depends on what you do. you can add traefik or any other reverse proxy to your existing containers without loosing data, nut building from scratch is always easier. In general docker philosophy is to store nothing important inside of container (docker volume for data, parameter/variables for config) so if you do it right way you don’t loose data when you rebuild your containers.

1 Like

Ok, after many hours of frustation I got it to work! I ended up using Traefik as @wwe suggested (thanks a lot btw) with Letsencrypt to get HTTPS. I did not follow his tutorial but I ended up doing something similar. I installed both Nextcloud and Traefik as Docker containers so it’s easier to manage. Make sure to port foward ports 80 and 443 to whatever machine you’re using for hosting. You have to do this from your modem, google your exact model to find out how to do it. Also, I bought a domain name (I needed it anyways to host a personal website) and made sure to make A records for each subdomain. Here is what I did (I used Godaddy):

This way if I go to traefik.mywebsite.com I can access my Traefik dashboard and if I go to nc.mywebsite.com I can access my Nextcloud server. The blurred part on the A records is my external ip address. You can check yours here. Ignore the two other blurred entries.

The files you will need to create are the following:

mkdir traefik
mkdir traefik/letsencrypt
mkdir nextcloud
touch traefik/docker-compose.yml
touch traefik/dynamic.yaml
touch nextcloud/dynamic.yml

Then edit traefik/docker-compose.yml, traefik/dynamic.yaml and nextcloud/dynamic.yml to the following:

traefik/docker-compose.yml

version: "3.3"

services:
    traefik:
        image: traefik:latest
        restart: unless-stopped
        security_opt:
            - no-new-privileges:true
        ports:
            - 80:80 # <== http
            - 443:443 # <== https
            - 8080:8080 # <== :8080 is where the dashboard runs on
        command:
            ## API Settings - https://docs.traefik.io/operations/api/, endpoints - https://docs.traefik.io/operations/api/#endpoints ##
            - --api.insecure=true # <== Enabling insecure api, NOT RECOMMENDED FOR PRODUCTION
            - --api.dashboard=true # <== Enabling the dashboard to view services, middlewares, routers, etc...
            - --api.debug=true # <== Enabling additional endpoints for debugging and profiling
            ## Log Settings (options: ERROR, DEBUG, PANIC, FATAL, WARN, INFO) - https://docs.traefik.io/observability/logs/ ##
            - --log.level=DEBUG # <== Setting the level of the logs from traefik
            ## Provider Settings - https://docs.traefik.io/providers/docker/#provider-configuration ##
            - --providers.docker=true # <== Enabling docker as the provider for traefik
            - --providers.docker.exposedbydefault=false # <== Don't expose every container to traefik, only expose enabled ones
            - --providers.file.filename=/dynamic.yaml # <== Referring to a dynamic configuration file
            - --providers.docker.network=web # <== Operate on the docker network named web
            ## Entrypoints Settings - https://docs.traefik.io/routing/entrypoints/#configuration ##
            - --entrypoints.web.address=:80 # <== Defining an entrypoint for port :80 named web
            - --entrypoints.web-secured.address=:443 # <== Defining an entrypoint for https on port :443 named web-secured
            ## Certificate Settings (Let's Encrypt) -  https://docs.traefik.io/https/acme/#configuration-examples ##
            - --certificatesresolvers.mytlschallenge.acme.tlschallenge=true # <== Enable TLS-ALPN-01 to generate and renew ACME certs
            - --certificatesresolvers.mytlschallenge.acme.email=your-email@whatever.com # <== Setting email for certs
            - --certificatesresolvers.mytlschallenge.acme.storage=/letsencrypt/acme.json # <== Defining acme file to store cert information
        volumes:
            - ./letsencrypt:/letsencrypt # <== Volume for certs (TLS)
            - /var/run/docker.sock:/var/run/docker.sock # <== Volume for docker admin
            - ./dynamic.yaml:/dynamic.yaml # <== Volume for dynamic conf file, **ref: line 27
        networks:
            - web # <== Placing traefik on the network named web, to access containers on this network
        labels:
            #### Labels define the behavior and rules of the traefik proxy for this container ####
            - "traefik.enable=true" # <== Enable traefik on itself to view dashboard and assign subdomain to view it
            - "traefik.http.routers.api.rule=Host(`traefik.mywebsite.com`)" # <== Setting the domain for the dashboard
            - "traefik.http.routers.api.service=api@internal" # <== Enabling the api to be a service to access
        container_name: traefik

networks:
    web:
        external: true

traefik/dynamic.yml

## Setting up the middleware for redirect to https ##
http:
    middlewares:
        redirect:
            redirectScheme:
                scheme: https

nextcloud/docker-compose.yml

version: "3.3"

services:
    nextcloud-db:
        image: postgres:latest
        restart: on-failure
        environment:
            POSTGRES_USER: yourusername
            POSTGRES_PASSWORD: yourpassword
            POSTGRES_DB: nameforyourdatabase
            PGDATA: /var/lib/postgresql/data/pgdata
        volumes:
            - "/path/to/folder/nextcloud-db:/var/lib/postgresql/data"
        networks:
            - nextcloud-net
        container_name: nextcloud-db
    nextcloud:
        image: nextcloud:latest
        restart: on-failure
        depends_on:
            - nextcloud-db
        environment:
            POSTGRES_DB: "nameforyourdatabase"
            POSTGRES_USER: "yourusername"
            POSTGRES_PASSWORD: "yourpassword"
            POSTGRES_HOST: "nameforyourhost"
        volumes:
            - "/path/to/folder/nextcloud:/var/www/html"
        networks:
            - nextcloud-net
            - web
        labels:
            #### Labels define the behavior and rules of the traefik proxy for this container ####
            - "traefik.enable=true" # <== Enable traefik to proxy this container
            - "traefik.http.routers.nextcloud.rule=Host(`nc.mywebsite.com`)" # <== Your Domain Name goes here for the http rule
            - "traefik.http.routers.nextcloud.entrypoints=web" # <== Defining the entrypoint for http, **ref: line 30
            - "traefik.http.routers.nextcloud.middlewares=redirect@file" # <== This is a middleware to redirect to https
            - "traefik.http.routers.nextcloud-secured.rule=Host(`nc.mywebsite.com`)" # <== Your Domain Name for the https rule 
            - "traefik.http.routers.nextcloud-secured.entrypoints=web-secured" # <== Defining entrypoint for https, **ref: line 31
            - "traefik.http.routers.nextcloud-secured.tls.certresolver=mytlschallenge" # <== Defining certsresolvers for https
        container_name: nextcloud

networks:
    web:
        external: true
    nextcloud-net:
        external: true

Make sure to read these files and edit them to fit your info accordingly

After all that you’re ready to get the containers working! Just create the networks and run the containers:

docker network create web
docker network create nextcloud-db
cd traefik && docker-compose up -d
cd ../nextcloud && docker-compose up -d

These commands will create the web and nextcloud-net networks and will create containers traefik, nextcloud and nextcloud-db. This method will work (at least it did for me) so be sure to follow this tutorial carefully understanding each step.

I hope this is useful for someone! I will mark this as solved now.

1 Like

you find some more useful settings for your dynamic.yml here:

1 Like