Menu
ZacsTech
  • Home
  • Linux
  • Windows
  • How To
  • Resources
  • Contact Us
ZacsTech

How to Self-Host Nextcloud on a VPS with Docker

Posted on September 15, 2026

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.

Official documentation

  • Docker Engine for Ubuntu
  • Docker Compose
  • Nextcloud Docker Image
  • Nextcloud Reverse Proxy Configuration
  • Nginx Proxy Manager Documentation

Related posts:

How to Install WordPress with a Single Script on Ubuntu 24.04How to Install WordPress with a Single Script on Ubuntu 24.04 How to Install Odoo 18 on Ubuntu 24.04 Set Up SoftEther VPN on Ubuntu 24.04 Super Fast WordPress on Ubuntu 26.04 LTS: Complete Manual Setup

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

  • facebook
  • twitter
  • pinterest
Privacy Policy
Terms and Conditions

Contact Us
About Us
©2026 ZacsTech | Powered by SuperbThemes
We use cookies on our website to give you the most relevant experience by remembering your preferences and repeat visits. By clicking “Accept All”, you consent to the use of ALL the cookies. However, you may visit "Cookie Settings" to provide a controlled consent.
Cookie SettingsAccept All
Manage consent

Privacy Overview

This website uses cookies to improve your experience while you navigate through the website. Out of these, the cookies that are categorized as necessary are stored on your browser as they are essential for the working of basic functionalities of the website. We also use third-party cookies that help us analyze and understand how you use this website. These cookies will be stored in your browser only with your consent. You also have the option to opt-out of these cookies. But opting out of some of these cookies may affect your browsing experience.
Necessary
Always Enabled
Necessary cookies are absolutely essential for the website to function properly. These cookies ensure basic functionalities and security features of the website, anonymously.
CookieDurationDescription
cookielawinfo-checkbox-analytics11 monthsThis cookie is set by GDPR Cookie Consent plugin. The cookie is used to store the user consent for the cookies in the category "Analytics".
cookielawinfo-checkbox-functional11 monthsThe cookie is set by GDPR cookie consent to record the user consent for the cookies in the category "Functional".
cookielawinfo-checkbox-necessary11 monthsThis cookie is set by GDPR Cookie Consent plugin. The cookies is used to store the user consent for the cookies in the category "Necessary".
cookielawinfo-checkbox-others11 monthsThis cookie is set by GDPR Cookie Consent plugin. The cookie is used to store the user consent for the cookies in the category "Other.
cookielawinfo-checkbox-performance11 monthsThis cookie is set by GDPR Cookie Consent plugin. The cookie is used to store the user consent for the cookies in the category "Performance".
viewed_cookie_policy11 monthsThe cookie is set by the GDPR Cookie Consent plugin and is used to store whether or not user has consented to the use of cookies. It does not store any personal data.
Functional
Functional cookies help to perform certain functionalities like sharing the content of the website on social media platforms, collect feedbacks, and other third-party features.
Performance
Performance cookies are used to understand and analyze the key performance indexes of the website which helps in delivering a better user experience for the visitors.
Analytics
Analytical cookies are used to understand how visitors interact with the website. These cookies help provide information on metrics the number of visitors, bounce rate, traffic source, etc.
Advertisement
Advertisement cookies are used to provide visitors with relevant ads and marketing campaigns. These cookies track visitors across websites and collect information to provide customized ads.
Others
Other uncategorized cookies are those that are being analyzed and have not been classified into a category as yet.
SAVE & ACCEPT