Docker-Compose Method - Recommended
Install Docker
Update the repo to get latest versions
sudo apt update
Install the latest version
sudo apt install docker.io
Set Docker to start on startup
sudo systemctl enable --now docker
Give your user permissions to docker, replacing user
with your username
sudo usermod -aG docker user
Once you have run this command close and reopen your session if you accessing remotely. This is to apply the permissions in the above step
Test it has installed correctly by getting the docker version
docker --version
Docker Compose
I also install docker-compose as some dockers need you to compose from a yml file. This downloads v2.16.0, just change this if the version updates to a later version
sudo curl -L "https://github.com/docker/compose/releases/download/v2.16.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
Give permissions to this
sudo chmod +x /usr/local/bin/docker-compose
Test it has installed correctly by getting the docker-compose version
docker-compose --version
Install Nextcloud
I keep all my dockers in a dockers folder in my home directory. If it doesn’t exist already, create this folder:-
mkdir ~/dockers
Now create a folder for Nextcloud to live in.
mkdir ~/dockers/nextcloud ~/dockers/
Create a folder for the www data
mkdir ~/dockers/nextcloud/data
Create a folder for the database
mkdir ~/dockers/nextcloud/sqldata
Change directory to this folder
cd ~/dockers/nextcloud
Create a docker-compose.yml file
nano docker-compose.yml
Paste the following. Change the 8081
part of 8081:80
if you want it to listen on an alternative port to port 8081. Change the MYSQL_PASSWORD
and MYSQL_ROOT_PASSWORD
. Ch
---
version: '2'
services:
app:
image: nextcloud
restart: always
ports:
- 8081:80
volumes:
- ./data:/var/www/html
environment:
- MYSQL_DATABASE=nextcloud
- MYSQL_USER=nextclouduser
- MYSQL_PASSWORD=changeme
- MYSQL_HOST=db
db:
image: mariadb
restart: always
command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW
volumes:
- ./sqldata:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=pleasechangeme
- MYSQL_PASSWORD=changeme
- MYSQL_DATABASE=nextcloud
- MYSQL_USER=nextcloud
Save the file with ctl + x, then y to save.
Run the docker-compose file with the following:-
docker-compose up -d
- Browse to the server ip and the port mentioned in the compose file, eg http://1.1.1.1:8081 and you should get the default page. If you want HTTPS, follow the next part, otherwise jump to Finish Setup
Adding HTTPS using Nginx Proxy Manager
Install Nginx Proxy Manager
I keep all my dockers in a dockers folder in my home directory. If it doesn’t exist already, create this folder:-
mkdir ~/dockers
Now create a folder for Nginx Proxy Manager to live in.
mkdir ~/dockers/nginxproxymanager
Change directory to this folder
cd ~/dockers/nginxproxymanager
Create 2 directories, data and letsencrypt, for nginxproxymanager to save to:-
mkdir data letencrypt
Create a docker-compose.yml file
nano docker-compose.yml
Paste the following. If you want to save the data to another directory change the volumes to point to the directories you want to.
version: '3'
services:
app:
image: 'jc21/nginx-proxy-manager:latest'
restart: unless-stopped
ports:
- '80:80'
- '81:81'
- '443:443'
environment:
DB_MYSQL_HOST: "db"
DB_MYSQL_PORT: 3306
DB_MYSQL_USER: "npm"
DB_MYSQL_PASSWORD: "npm"
DB_MYSQL_NAME: "npm"
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
db:
image: 'jc21/mariadb-aria:latest'
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: 'npm'
MYSQL_DATABASE: 'npm'
MYSQL_USER: 'npm'
MYSQL_PASSWORD: 'npm'
volumes:
- ./data/mysql:/var/lib/mysql
Save the file with ctl + x, then y to save.
Run the docker-compose file with the following:-
docker-compose up -d
First run Nginx Proxy Manger
Browse to http://serverip:81 and you will get the login screen. Default login is [email protected] password changeme. You will then get the edit user screen. Update the user email and press Save. You will then be prompted to change the password. Save this and you will get the main login screen.
Creating a wildcard certificate with DNS Challenge
Go to SSL Certificates, select “Add SSL Certificate”.
In the domain name type *.domainname, so *.llewellynhughes.co.uk for example. Edit the email if you need to. Tick “Use DNS Challenge”. Select your DNS provider. If your current DNS provider isn’t there, sign up for a free Cloudflare account and use their DNS, pointing your existing DNS Name Servers (ns) to Cloudflare. Agree to the terms and conditions and Save.
Your SSL Certificate should now be created and renewed automatically.
Proxying to an existing site
This presumes you have set your DNS record for your domain name. I use Adguard as my DNS server, so added a DNS Rewrite here to point back to my Nginx Proxy Manager. I have a DNS record for nextcloud.llewellynhughes.co.uk, with a DNS rewrite for that URL to go to my server ip.
Go to Hosts, Proxy Hosts, Add Proxy Host.
Domain names, fill in the url you have setup. In my example it’s nextcloud.llewellynhughes.co.uk.
Scheme is http Forward Hostname/IP is my server ip Port is my nextcloud install port, so 8081.
Tick Block Known Exploits and WebSocket Support.
Leave custom locations blank. For other projects you might need to use this for subfolders.
SSL, select your SSL Certificate created. I tick Force SSL, HTTP/2 Support, HSTS Enabled.
Nothing in advanced. These are for advanced Nginx configs.
Once done, Click Save.
After this, test going to your https url and it should work
Finishing setup
-
Add your domain to
trusted_domains
sudo nano ~/dockers/nextcloud/data/config/config.php
-
Under
trusted_domains
, add your url so it looks like this‘trusted_domains’ => array ( 0 => ‘nextcloud.example.com’, ),
-
Once on the site, create an admin account, open storage and database, and paste your data folder into there from the docker redirect. This will make files appear in ~/dockers/nextcloud/data/data folder
/var/www/html/data
-
Add the nextcloud database settings.
nextcloud password nextcloud localhost
-
Press finish setup.
-
All should be ready.
Nginx Method
Installing nginx if it’s not installed
-
First, update the repo to get latest versions
sudo apt update
-
Install nginx
sudo apt install nginx (you can ignore this step if you ran it above for the above install)
-
Enable the service to start on boot
sudo systemctl enable nginx
Install PHP
-
Update the repo to get latest versions
sudo apt update
-
Install php and php extensions
sudo apt install imagemagick php-imagick php7.4-common php7.4-mysql php7.4-fpm php7.4-gd php7.4-json php7.4-curl php7.4-zip php7.4-xml php7.4-mbstring php7.4-bz2 php7.4-intl php7.4-bcmath php7.4-gmp
Installing MariaDB
-
First, update the repo to get latest versions (you can ignore this step if you ran it above for the above installs)
sudo apt update
-
Install
Maridadb-server
andmariadb-client
sudo apt install mariadb-server mariadb-client
-
Secure the installation
sudo mysql_secure_installation
-
First will prompt you for current password, this will be blank so just press enter
Enter current password for root (enter for none):
-
Next, it will ask you to set a root password. Press Y and enter a password, and then confirm.
Set root password? [Y/n] Y
-
The rest, accept the defaults, and complete the configuration.
-
Enable the service to start on boot.
sudo systemctl enable mariadb-server
Setting up database for Nextcloud
-
Login to mysql, this was prompt you for your password you set earlier.
sudo mysql -u root -p
-
Create database
CREATE DATABASE nextcloud;
-
Create a user (Please change the password at the end to a secure password)
create user 'nextclouduser'@'localhost' identified by 'your-password';
-
Grant privileges to the above account
grant all privileges ON nextcloud.* TO 'nextclouduser'@'localhost';
-
Flush privileges and exit
flush privileges; exit;
Installing Nextcloud
-
Download the latest release, there is no “latest release, so get the latest url from https://nextcloud.com/install/#instructions-server
wget https://download.nextcloud.com/server/releases/nextcloud-21.0.1.zip
-
Unzip and move to the nginx directory, ignore the first command if you unzip installed already.
sudo apt install unzip sudo unzip nextcloud-21.0.1.zip -d /usr/share/nginx/
-
Amend permissions of the folder
sudo chown www-data:www-data /usr/share/nginx/nextcloud/ -R
-
Create the nginx config file
sudo nano /etc/nginx/conf.d/nextcloud.conf
-
Copy and paste the below into the file for the config. Change the
server_name
to your server name/IP. If you want to change the port too, change thelisten 80
line.server { listen 80; listen [::]:80; server_name nextcloud.example.com; # Add headers to serve security related headers add_header X-Content-Type-Options nosniff; add_header X-XSS-Protection "1; mode=block"; add_header X-Robots-Tag none; add_header X-Download-Options noopen; add_header X-Permitted-Cross-Domain-Policies none; add_header Referrer-Policy no-referrer; #I found this header is needed on Ubuntu, but not on Arch Linux. add_header X-Frame-Options "SAMEORIGIN"; # Path to the root of your installation root /usr/share/nginx/nextcloud/; access_log /var/log/nginx/nextcloud.access; error_log /var/log/nginx/nextcloud.error; location = /robots.txt { allow all; log_not_found off; access_log off; } # The following 2 rules are only needed for the user_webfinger app. # Uncomment it if you're planning to use this app. #rewrite ^/.well-known/host-meta /public.php?service=host-meta last; #rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json # last; location = /.well-known/carddav { return 301 $scheme://$host/remote.php/dav; } location = /.well-known/caldav { return 301 $scheme://$host/remote.php/dav; } location ~ /.well-known/acme-challenge { allow all; } # set max upload size client_max_body_size 512M; fastcgi_buffers 64 4K; # Disable gzip to avoid the removal of the ETag header gzip off; # Uncomment if your server is build with the ngx_pagespeed module # This module is currently not supported. #pagespeed off; error_page 403 /core/templates/403.php; error_page 404 /core/templates/404.php; location / { rewrite ^ /index.php; } location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)/ { deny all; } location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) { deny all; } location ~ ^/(?:index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/.+|ocs-provider/.+|core/templates/40[34])\.php(?:$|/) { include fastcgi_params; fastcgi_split_path_info ^(.+\.php)(/.*)$; try_files $fastcgi_script_name =404; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; #Avoid sending the security headers twice fastcgi_param modHeadersAvailable true; fastcgi_param front_controller_active true; fastcgi_pass unix:/run/php/php7.4-fpm.sock; fastcgi_intercept_errors on; fastcgi_request_buffering off; } location ~ ^/(?:updater|ocs-provider)(?:$|/) { try_files $uri/ =404; index index.php; } # Adding the cache control header for js and css files # Make sure it is BELOW the PHP block location ~* \.(?:css|js)$ { try_files $uri /index.php$uri$is_args$args; add_header Cache-Control "public, max-age=7200"; # Add headers to serve security related headers (It is intended to # have those duplicated to the ones above) add_header X-Content-Type-Options nosniff; add_header X-XSS-Protection "1; mode=block"; add_header X-Robots-Tag none; add_header X-Download-Options noopen; add_header X-Permitted-Cross-Domain-Policies none; add_header Referrer-Policy no-referrer; # Optional: Don't log access to assets access_log off; } location ~* \.(?:svg|gif|png|html|ttf|woff|ico|jpg|jpeg)$ { try_files $uri /index.php$uri$is_args$args; # Optional: Don't log access to other assets access_log off; } }
-
Create a data folder where you want to save the nextcloud data and give it permissions
sudo mkdir /usr/share/nginx/nextcloud-data sudo chown www-data:www-data /usr/share/nginx/nextcloud-data -R
-
Test the nginx config.
sudo nginx -t
-
If the above comes back successfully, restart nginx service.
sudo systemctl reload nginx
-
Browse to the web site you set in the nginx config file above and it should appear, http://nextcloud.example.com:80
-
You should then get a https certificate to secure your server if you are accessing it externally. I am using lets encrypt, but as I am not exposing it externally I used dns authorisation instead of http. If you want to skip this step, go to Finishing setup.
Securing the server over dns
-
Add latest certbot repository
sudo apt-add-repository ppa:certbot/certbot
-
Install certbot
sudo apt install certbot
-
First get the certbot file
wget https://github.com/joohoi/acme-dns-certbot-joohoi/raw/master/acme-dns-auth.py
-
Change permissions on file
chmod +x acme-dns-auth.py
-
Edit file
chmod +x acme-dns-auth.py
-
Change first line to
python3
#!/usr/bin/env python3
-
Move to the lets encrypt folder
sudo mv acme-dns-auth.py /etc/letsencrypt/
-
Create request (change nextcloud.example.com for your url)
sudo certbot certonly --manual --manual-auth-hook /etc/letsencrypt/acme-dns-auth.py --preferred-challenges dns --debug-challenges -d \*.nextcloud.example.com -d nextcloud.example.com
-
It will then prompt you to add a cname to your dns host. Log into your dns, and create a cname. Press enter once complete. If it fails due to dns replication timings, just run the above command again.
sudo certbot certonly --manual --manual-auth-hook /etc/letsencrypt/acme-dns-auth.py --preferred-challenges dns --debug-challenges -d \*.nextcloud.example.com -d nextcloud.example.com
Applying the cert
-
Once complete it will tell you where the certificate and chain have been saved. Change nextcloud.example.com to the domain used above and it will probably be in there.
Congratulations! Your certificate and chain have been saved at /etc/letsencrypt/live/nextcloud.example.com/fullchain.pem Your key file has been saved at /etc/letsencrypt/live/nextcloud.example.com/privkey.pem
-
Open the nextcloud nginx to use https
sudo nano /etc/nginx/conf.d/nextcloud.conf
-
Replace this
listen 80; listen [::]:80; server_name nextcloud.example.com;
-
With the following, changing the
ssl_certificate
andssl_certificate_key
fields to point to the correct location.listen 443 ssl http2; listen [::]:443 ssl http2; server_name nextcloud.example.com; ssl_certificate /etc/letsencrypt/live/nextcloud.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/nextcloud.example.com/privkey.pem;
-
Test the nginx config.
sudo nginx -t
-
If the above comes back successfully, restart nginx service.
sudo systemctl reload nginx
-
You should now be able to browse to your website on https://nextcloud.example.com replacing for your domain name.
Finishing setup
-
Add your domain to
trusted_domains
sudo nano /usr/share/nginx/nextcloud/config/config.php
-
Under
trusted_domains
, add your url so it looks like this‘trusted_domains’ => array ( 0 => ‘nextcloud.example.com’, ),
-
Once on the site, create an admin account, open storage and database, and paste your data folder into there from step 6 of installing nextcloud
/usr/share/nginx/nextcloud-data
-
Add the nextcloud database settings.
nextclouduser password nextcloud localhost
-
Press finish setup.
-
All should be ready.