Want to run your own private cloud instead of using Google Drive, Dropbox, or OneDrive?
In this guide, we’ll install Nextcloud on a VPS using Docker Compose, connect it to our own domain, and secure it with free HTTPS using Nginx Proxy Manager.
For this tutorial, we’ll use:
VPS: DigitalOcean
Operating System: Ubuntu
Domain: zacstech.biz
Nextcloud: cloud.zacstech.biz
The final setup will look like this:
Internet
│
▼
cloud.zacstech.biz
│
▼
HTTPS :443
│
▼
Nginx Proxy Manager
│
▼
Nextcloud
│
▼
MariaDB
The Nextcloud Docker image is an official Docker image, and the Nextcloud project recommends using persistent Docker volumes and a database such as MariaDB for this type of deployment.
1. Create a Non-Root User
It’s better to use a normal user account for everyday administration rather than logging into the VPS as root.
If you haven’t already created one:
adduser zack
Add the user to the sudo group:
usermod -aG sudo zack
Then switch to the new user:
su - zack
You can verify the user:
whoami
It should return:
zack
2. Install Docker
We’ll use Docker’s official installation instructions rather than an unofficial Ubuntu package.
Official Docker Ubuntu Installation Guide
First update the package list:
sudo apt update
Install the required packages:
sudo apt install ca-certificates curl
Create Docker’s keyring directory:
sudo install -m 0755 -d /etc/apt/keyrings
Download Docker’s official GPG key:
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
Make the key readable:
sudo chmod a+r /etc/apt/keyrings/docker.asc
Add Docker’s official repository:
sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF
Update the package list:
sudo apt update
Now install Docker Engine, Buildx and Docker Compose:
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Docker’s official documentation currently recommends this package-based installation method for Ubuntu.
3. Check That Docker Is Running
Check the Docker service:
sudo systemctl status docker
You should see:
Active: active (running)
If Docker isn’t running, start it with:
sudo systemctl start docker
You can also make sure it starts automatically when the VPS boots:
sudo systemctl enable docker
4. Test Docker
Let’s make sure Docker actually works.
Run:
sudo docker run hello-world
Docker will download a small test image, run it and display:
Hello from Docker!
If you see that message, Docker is working correctly. This is also the test recommended in Docker’s official installation documentation.
5. Check Docker and Docker Compose Versions
Check Docker:
docker --version
Then check Docker Compose:
docker compose version
You should get a version number from both commands.
Notice that we’re using:
docker compose
rather than the older:
docker-compose
The Compose plugin is the current Docker-supported approach on Linux.
6. Point Your Domain to the VPS
Before setting up Nextcloud, point your domain to the VPS.
For example, create an A record:
Type: A
Host: cloud
Value: YOUR_VPS_IP
This gives you:
cloud.zacstech.biz
pointing to your VPS.
You can check that DNS is resolving with:
ping cloud.zacstech.biz
You should see the VPS IP address.
7. Open the Required Ports
If you’re using a firewall, make sure these ports are accessible:
80 → HTTP
81 → Nginx Proxy Manager
443 → HTTPS
For example, if you’re using UFW:
sudo ufw allow 80/tcp
sudo ufw allow 81/tcp
sudo ufw allow 443/tcp
Check the firewall:
sudo ufw status
Important
Port 81 is the Nginx Proxy Manager administration interface. It doesn’t need to be publicly accessible to Nextcloud users.
For better security, you can restrict port 81 to your own IP address instead of opening it to everyone.
Also be aware that Docker-published ports can interact with firewall rules differently from normal host services. Docker’s documentation specifically warns that published container ports can bypass some UFW/firewalld filtering, so review your firewall configuration carefully.
8. Create the Nextcloud Directory
Create a directory for the installation:
mkdir ~/nextcloud
Enter the directory:
cd ~/nextcloud
9. Create the Docker Compose File
Create the file:
nano docker-compose.yml
Paste the following:
services:
db:
image: mariadb:lts
restart: unless-stopped
command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW
environment:
MYSQL_ROOT_PASSWORD: CHANGE_THIS_ROOT_PASSWORD
MYSQL_DATABASE: nextcloud
MYSQL_USER: nextcloud
MYSQL_PASSWORD: CHANGE_THIS_DATABASE_PASSWORD
volumes:
- db_data:/var/lib/mysql
nextcloud:
image: nextcloud:apache
restart: unless-stopped
depends_on:
- db
environment:
MYSQL_DATABASE: nextcloud
MYSQL_USER: nextcloud
MYSQL_PASSWORD: CHANGE_THIS_DATABASE_PASSWORD
MYSQL_HOST: db
volumes:
- nextcloud_data:/var/www/html
npm:
image: jc21/nginx-proxy-manager:2.15.1
restart: unless-stopped
ports:
- "80:80"
- "81:81"
- "443:443"
volumes:
- npm_data:/data
- npm_letsencrypt:/etc/letsencrypt
volumes:
db_data:
nextcloud_data:
npm_data:
npm_letsencrypt:
Change the passwords
Change:
CHANGE_THIS_ROOT_PASSWORD
and:
CHANGE_THIS_DATABASE_PASSWORD
to strong, unique passwords.
Important: The MYSQL_PASSWORD must be identical in both the MariaDB and Nextcloud sections.
The official Nextcloud Docker examples likewise require database credentials to be supplied and use persistent volumes for the database and Nextcloud data.
Save the file:
CTRL + X
Y
Enter
10. Start Nextcloud
Start all three containers:
docker compose up -d
Docker will download the images and start:
- MariaDB
- Nextcloud
- Nginx Proxy Manager
Check their status:
docker compose ps
You should see the three services running.
You can also use:
docker ps
11. Access Nginx Proxy Manager
Nginx Proxy Manager provides a web interface for managing our reverse proxy and SSL certificates.
Open:
http://YOUR_VPS_IP:81
Port 81 is only for the Nginx Proxy Manager administration interface. The official Nginx Proxy Manager documentation uses ports 80, 81 and 443 in its Docker Compose example and identifies port 81 as the Admin UI.
12. Configure the Nextcloud Proxy
In Nginx Proxy Manager, go to:
Hosts → Proxy Hosts → Add Proxy Host
For Domain Names, enter:
cloud.zacstech.biz
For Scheme:
http
For Forward Hostname/IP:
nextcloud
For Forward Port:
80
Enable:
Block Common Exploits
Then click Save.
Because both containers are running in the same Docker Compose project, Nginx Proxy Manager can reach the Nextcloud container using the Docker service name:
nextcloud
13. Enable Free HTTPS
Edit the proxy host you just created.
Go to the SSL section.
Choose:
Request a New SSL Certificate
Enter:
cloud.zacstech.biz
Enable:
Force SSL
You can also enable:
HTTP/2 Support
Accept the Let’s Encrypt terms and click Save.
Now your Nextcloud installation should be available at:
https://cloud.zacstech.biz
Nextcloud’s Docker documentation specifically notes that when the installation is reachable from the internet, HTTPS encryption is mandatory.
14. Complete the Nextcloud Installation
Open:
https://cloud.zacstech.biz
You should see the Nextcloud setup screen.
Create your administrator account.
Administration username
Choose your preferred username.
For example:
admin
Administration password
Create a strong password.
This is your Nextcloud login password.
It is different from:
- Your VPS password
- Your Linux user password
- Your MariaDB root password
- Your MariaDB database password
Click Install.
Nextcloud will then complete the installation.
15. Reset a Forgotten Nextcloud Password
If you forget the Nextcloud administrator password, you can reset it from the terminal.
First, go into the project directory:
cd ~/nextcloud
List the Nextcloud users:
docker compose exec nextcloud php occ user:list
You’ll see something similar to:
- admin: admin
Then reset the password:
docker compose exec nextcloud php occ user:resetpassword admin
Replace admin with your actual Nextcloud username.
Nextcloud will ask you to enter and confirm the new password.
16. Useful Docker Commands
Check the containers
docker compose ps
View all logs
docker compose logs
View Nextcloud logs
docker compose logs nextcloud
View Nginx Proxy Manager logs
docker compose logs npm
Restart the containers
docker compose restart
Stop the containers
docker compose down
Don’t use docker compose down -v unless you intentionally want to remove the Docker volumes.
Your persistent Nextcloud data and database are stored in Docker volumes.
17. Updating Nextcloud
When you want to pull newer container images:
cd ~/nextcloud
Then:
docker compose pull
And recreate the containers:
docker compose up -d
Check everything:
docker compose ps
However, always back up your Nextcloud files and database before major upgrades.
For production, don’t blindly jump between major Nextcloud releases without checking the supported upgrade path.
18. Check the Logs if Something Goes Wrong
If Nextcloud isn’t working:
docker compose logs nextcloud
If the database isn’t working:
docker compose logs db
If Nginx Proxy Manager isn’t working:
docker compose logs npm
You can also follow the logs live:
docker compose logs -f nextcloud
Press:
CTRL + C
to stop viewing the logs.
19. Final Setup
Once everything is configured, your setup looks like this:
INTERNET
│
▼
cloud.zacstech.biz
│
HTTPS
Port 443
│
▼
Nginx Proxy Manager
│
▼
Nextcloud
│
▼
MariaDB
The three Docker services are:
nextcloud
db
npm
And your users only need to visit:
https://cloud.zacstech.biz
They don’t need to know anything about port 81.
Complete Command Reference
For convenience, here are the main commands from the tutorial in one place.
Docker installation
sudo apt update
sudo apt install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Verify Docker
sudo systemctl status docker
docker --version
docker compose version
sudo docker run hello-world
Create the project
mkdir ~/nextcloud
cd ~/nextcloud
nano docker-compose.yml
Start Nextcloud
docker compose up -d
Check containers
docker compose ps
docker ps
View logs
docker compose logs
docker compose logs nextcloud
docker compose logs npm
docker compose logs db
Restart
docker compose restart
Update images
docker compose pull
docker compose up -d
Reset a Nextcloud password
docker compose exec nextcloud php occ user:list
docker compose exec nextcloud php occ user:resetpassword admin
Final Note
This setup uses Docker Compose + MariaDB + Nginx Proxy Manager, rather than exposing Nextcloud directly on a port such as 8080. Nginx Proxy Manager handles the public web traffic and HTTPS, while Nextcloud and MariaDB remain behind the reverse proxy.
For production use, make backups part of the setup from day one. A VPS is not a backup, and Docker volumes alone don’t protect you from VPS failure, accidental deletion, or other disasters.



