For those who want full control over their data, Nextcloud provides a powerful open-source solution for building a private cloud storage system. It not only enables secure file synchronization across devices but also allows you to deploy storage on your own server, avoiding reliance on third-party providers.
In this guide, we’ll go through the process of installing Nextcloud using isolated Docker containers, which greatly simplifies deployment and management. We’ll also configure automatic traffic encryption with SSL certificates from Let’s Encrypt to ensure secure data transmission.
You will need:
For the server, choose a configuration with 1 CPU core, 2 GB of RAM, and a public IPv4 address, which you can request when creating the server or later in the “Network” section.
The server will be set up within a few minutes. The IPv4 address, login, and password for SSH access will be available in the Dashboard.
Nextcloud requires several key components to run:
First, we create a directory where we will store configuration files, and navigate to it.
mkdir nextcloud && cd nextcloud
This hidden file will store variables with passwords:
nano .env
File contents:
NEXTCLOUD_ROOT_PASSWORD=secure_root_password_123
NEXTCLOUD_DB_PASSWORD=secure_nextcloud_db_password_456
NPM_ROOT_PASSWORD=secure_npm_root_password_789
NPM_DB_PASSWORD=secure_npm_db_password_012
Don’t forget to replace the values with your own.
Use nano to create it:
nano docker-compose.yml
Add the following configuration:
volumes:
nextcloud-data:
nextcloud-db:
npm-data:
npm-ssl:
npm-db:
networks:
frontend:
backend:
services:
nextcloud-app:
image: nextcloud:31.0.8
restart: always
volumes:
- nextcloud-data:/var/www/html
environment:
- MYSQL_PASSWORD=${NEXTCLOUD_DB_PASSWORD}
- MYSQL_DATABASE=nextcloud
- MYSQL_USER=nextcloud
- MYSQL_HOST=nextcloud-db
- MYSQL_PORT=3306
networks:
- frontend
- backend
nextcloud-db:
image: mariadb:12.0.2
restart: always
command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW
volumes:
- nextcloud-db:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=${NEXTCLOUD_ROOT_PASSWORD}
- MYSQL_PASSWORD=${NEXTCLOUD_DB_PASSWORD}
- MYSQL_DATABASE=nextcloud
- MYSQL_USER=nextcloud
networks:
- backend
npm-app:
image: jc21/nginx-proxy-manager:2.12.6
restart: always
ports:
- "80:80"
- "81:81"
- "443:443"
environment:
- DB_MYSQL_HOST=npm-db
- DB_MYSQL_PORT=3306
- DB_MYSQL_USER=npm
- DB_MYSQL_PASSWORD=${NPM_DB_PASSWORD}
- DB_MYSQL_NAME=npm
volumes:
- npm-data:/data
- npm-ssl:/etc/letsencrypt
networks:
- frontend
- backend
npm-db:
image: jc21/mariadb-aria:10.11.5
restart: always
environment:
- MYSQL_ROOT_PASSWORD=${NPM_ROOT_PASSWORD}
- MYSQL_DATABASE=npm
- MYSQL_USER=npm
- MYSQL_PASSWORD=${NPM_DB_PASSWORD}
volumes:
- npm-db:/var/lib/mysql
networks:
- backend
Run the command:
docker compose up -d
When running docker compose up -d
, you may encounter an error related to Docker Hub pull limits.
In that case:
Log in to your Docker Hub account, or register a new one on the official website.
Go to Account settings → Personal access tokens.
Click Generate new token.
Enter a description, set an expiration date, and select permissions: Read, Write, Delete.
Click Generate.
Copy and save the token (it will only be shown once).
On the server, log in with:
docker login -u dockeruser
Replace dockeruser
with your Docker Hub username. When prompted for a password, paste the token.
Restart the containers:
docker compose up -d
Wait until all containers are up and running.
Check with:
docker ps
All containers should have the status Up
.
Open a browser and go to http://<server-IP>:81
to access the Nginx Proxy Manager interface.
Log in with the default credentials:
Login: admin@example.com
Password: changeme
On first login, update the admin user details (Full Name, Nickname, Email).
Change the admin password:
Current Password: changeme
New Password: your new password
Confirm Password: repeat the new password
Save changes.
Go to Hosts → Proxy Hosts.
Click Add Proxy Host.
Fill in the fields:
Domain Names: the domain for your Nextcloud instance.
Scheme: http
.
Forward Hostname/IP: nextcloud-app
(the service name from docker-compose.yml
).
Forward Port: 80.
Go to the SSL tab:
In SSL Certificate, select Request a new SSL Certificate.
Enable:
Force SSL
HTTP/2 Support
HSTS Enabled
Enter your email for Let’s Encrypt.
Agree to Let’s Encrypt terms of service.
Click Save.
The configured host will appear in the list.
Now, navigate to your domain name. If everything is set up correctly, the Nextcloud web interface will open, and an SSL certificate will be issued by Let’s Encrypt.
At this point, Nextcloud installation and basic configuration is complete.
In this article, we demonstrated how to deploy Nextcloud using Docker and issue a free Let’s Encrypt certificate.
This method is one of the most reliable, secure, and easily scalable approaches. Docker ensures application isolation, simplifies updates, and makes migration between systems easier. Using an SSL certificate is not just a recommendation but a necessity for protecting confidential data and ensuring encrypted traffic.