Came across this post when I was trying to find a solution for this, figure I’d add mine now that I’ve gotten it to work.
Out of the box, the nextcloud docker sets up http, not https. To get it to support https, you need to make a few tweaks:
- You need to enable the
mod_ssl
module.
- You need to set up your SSL certificate and key. Creating them is out of scope for this thread, but we’ll see where you drop them so they can be used for the docker.
- You need to either add a site with ssl settings or tweak your existing site config file. I decided to add a configuration and called the file
default-ssl.conf
A challenge with setting up the site and the ssl module is that you have to restart the apache server - and that kills your container. If, like me, you spent an inordinate amount of time trying to tweak apache settings and not see them getting applied, this is why…
But here’s the solution I came up with:
- Create a directory (e.g.
config
) on your host. This will contain the config file with ssl enabled, and a certs
subdirectory with your SSL certificate and key.
- Copy your
default-ssl.conf
file over to /etc/apache2/sites-available
- Set up your nextcloud container to run
a2enmod ssl
and a2ensite default-ssl
. This is done differently depending on whether you’re using docker or kubernetes.
With docker, I used a Dockerfile that was based on nextcloud:
FROM nextcloud
RUN a2enmod ssl
COPY default-ssl.conf /etc/apache2/sites-available/default-ssl.conf
RUN a2ensite default-ssl
Once you’ve built the above with docker build . -t nextcloud-ssl
, you can run it with docker run -v "$PWD/certs:/etc/certs" -p 443:443 --name nextcloud-ssl -it nextcloud-ssl
.
With kubernetes, I actually mapped both /etc/certs
and default-ssl.conf
. For the config file, I used the sub_path
parameter – and note that in my example I got lazy and merely substituted the 000-default
file for the default-ssl
; with a bit of tweaking you should be able to have both co-exist.
Here are the relevant bits in my terraform file. Note that I’m using a simple, local volume mapping:
resource "kubernetes_persistent_volume_claim" "nextcloud-config-volume" {
metadata {
name = "nextcloud-config-volume"
namespace = "nextcloud"
}
spec {
access_modes = ["ReadWriteMany"]
storage_class_name = "standard"
resources {
requests = {
storage = "500Mi"
}
}
volume_name = kubernetes_persistent_volume.nextcloud-config-volume.metadata.0.name
}
}
resource "kubernetes_persistent_volume" "nextcloud-config-volume" {
metadata {
name = "nextcloud-config-volume"
}
spec {
storage_class_name = "standard"
node_affinity {
required {
node_selector_term {
match_expressions {
key = "kubernetes.io/hostname"
operator = "In"
values = ["my-server"]
}
}
}
}
capacity = {
storage = "500Mi"
}
access_modes = ["ReadWriteMany"]
persistent_volume_source {
local {
path = "/nextcloud/config"
}
}
}
}
[...]
resource "kubernetes_deployment" "nextcloud" {
[...]
spec {
[...]
template {
[...]
spec {
volume {
name = "nextcloud-config-volume"
persistent_volume_claim {
claim_name = "nextcloud-config-volume"
}
}
container {
image = "nextcloud"
name = "nextcloud"
# This is where the magic happens with a2enmod:
command = ["/bin/sh"]
args = ["-c", "a2enmod ssl && apache2-foreground"]
[...]
volume_mount {
mount_path = "/etc/certs"
name = "nextcloud-config-volume"
sub_path = "certs"
}
volume_mount {
mount_path = "/etc/apache2/sites-available/000-default.conf"
name = "nextcloud-config-volume"
sub_path = "default-ssl.conf"
}
}
}
}
}
}
And that should do it. The beauty of nextcloud, the practicality of containerization, and the security of HTTPS.
Hope this helps someone out there 