So you don’t want to run a reverse proxy but you need to serve your Nextcloud over HTTPS? Here’s a quick guide to enable SSL on Apache within the container.
Creating the certificate
Creating the certificate is out of the scope of this howto, but you don’t have to look far to find information on how to generate one.
However you do it, copy the certificate and key files to a directory of your choice (I will use /etc/ssl/mydomain/
). Use the filenames cert.pem
and key.pem
.
With an authority
There are a million guides on the internet, as well as official documentation, on how to generate a certificate with letsencrypt. Follow one of these to set up Nextcloud with a public domain name or subdomain you control.
Self-signing a certificate
If you’re running Nextcloud locally, or on a VPN with an internal IP and domain, you can’t use letsencrypt to generate your certiciates, so you will have to self-sign one.
I recommend also creating a certificate authority and signing the certificate. Then you can import the CA’s cert into your browser to prevent errors. Here’s a tutorial on how to do this, but you can google for about 1,000 more.
Installing SSL on the image
Create a Dockerfile in the directory you will run nextcloud from. I will use /srv/nextcloud/
in this example. Change admin@domain.tld
and nextcloud.domain.tld
to and admin email and your site’s domain, respectively.
$ cat Dockerfile
FROM nextcloud:apache
COPY setssl.sh /usr/local/bin/
RUN /usr/local/bin/setssl.sh admin@domain.tld nextcloud.domain.tld
This dockerfile inherits from nextcloud and runs our setssl.sh
script while ithe container boots. This is the recommended method outlined in the docker hub readme under Adding Features.
This is the script we’ll run in the container as it’s starting. Save it to setssl.sh
and give it executable permissions.
# setssl.sh
# USAGE: setssl.sh <email> <domain>
echo 'SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH
SSLProtocol All -SSLv2 -SSLv3
SSLHonorCipherOrder On
Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains"
Header always set X-Frame-Options DENY
Header always set X-Content-Type-Options nosniff
SSLCompression off
SSLSessionTickets Off' > /etc/apache2/conf-available/ssl-params.conf
echo "<IfModule mod_ssl.c>
<VirtualHost _default_:443>
ServerAdmin $2
ServerName $1
" > /etc/apache2/sites-available/default-ssl.conf
echo '
DocumentRoot /var/www/html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
SSLEngine on
SSLCertificateFile /etc/ssl/nextcloud/cert.pem
SSLCertificateKeyFile /etc/ssl/nextcloud/key.pem
<FilesMatch "\.(cgi|shtml|phtml|php)$">
SSLOptions +StdEnvVars
</FilesMatch>
<Directory /usr/lib/cgi-bin>
SSLOptions +StdEnvVars
</Directory>
</VirtualHost>
</IfModule>' >> /etc/apache2/sites-available/default-ssl.conf
a2enmod ssl >/dev/null
a2ensite default-ssl >/dev/null
a2enconf ssl-params >/dev/null
Finally, modify your docker run
or docker-compose
command to include the changes.
Running
Don’t forget to replace /etc/ssl/mydomain
with the path to your actual directory.
docker-compose
Change the nextcloud service lines in your docker-compose.yml
. You can use the one from Docker Hub as a basis.
nextcloud:
# image: nextcloud:latest
build: .
container_name: nextcloud
restart: unless-stopped
ports:
# - "8080:80"
- "8443:443"
volumes:
- "./nextcloud:/var/www/html"
- "/etc/ssl/mydomain:/etc/ssl/nextcloud"
docker run
First, build the new image described in the dockerfile. Then you can run it. You’ll have to mount the directory with the ssl certs as a volume, and use port 443 instead of 80. Something like this:
$ docker build --tag nextcloud_ssl .
$ docker run -d \
-p 8443:443
-v nextcloud:/var/www/html \
-v /etc/ssl/mydomain:/etc/ssl/nextcloud
nextcloud_ssl
Updating
Like it says in the readme:
Updating your own derived image is also very simple. When a new version of the Nextcloud image is available run:
docker build -t your-name --pull . docker run -d your-name
or for docker-compose:
docker-compose build --pull docker-compose up -d
The
--pull
option tells docker to look for new versions of the base image. Then the build instructions inside yourDockerfile
are run on top of the new image.