How to Install Nextcloud with Docker
Table of contents
- Key takeaways
- What is Nextcloud and what is it for?
- What do you need before you start?
- The Nextcloud docker-compose.yml with MariaDB and Redis
- First boot and configuration
- How do you publish it with Traefik and HTTPS?
- How do I take backups and updates?
- Frequently asked questions
- Do I really need Redis and MariaDB to use Nextcloud?
- Why should I not use the image's latest tag?
- What is the difference between the apache and fpm images?
- Conclusion
- Sources
Nextcloud is an open-source private cloud platform that, in Docker, runs as three containers: the application, a MariaDB database and a Redis cache. With a single docker-compose.yml file you get your own self-hosted Drive, calendar and contacts in minutes, with your data stored in a volume that you control.
Nextcloud is the most direct way to run your own private cloud, and with Docker it installs in a matter of minutes. In this guide you bring up the application alongside a MariaDB database and a Redis cache using a single docker-compose.yml file, learn how to configure it on first boot, how to publish it over HTTPS behind a reverse proxy and how to take backups. The same explanation is available in Spanish.
Key takeaways
- Nextcloud is an open-source platform for files, calendar, contacts and document editing that you host on your own server.
- The recommended setup uses three containers: the application (the official
nextcloudimage), a MariaDB database and a Redis cache for file locking. - The whole installation lives in the
/var/www/htmlvolume, so your data, configuration and installed apps persist even if you delete the container. - Pin a specific image version (for example
nextcloud:33-apache) instead of:latest; that way you decide when you move to a new major version, which can only go up one at a time. - To expose it to the Internet with a valid certificate, put it behind Traefik or another reverse proxy; Nextcloud should never be served over plain HTTP.
What is Nextcloud and what is it for?
Nextcloud is an open-source private cloud platform: a self-hosted replacement for services like Google Drive, Dropbox or iCloud. It was born in 2016 as a fork of ownCloud, led by Frank Karlitschek and much of the original team, and it has since become the reference project for taking back control of your files.
Its core is file synchronisation between computers and phones, but through apps it adds calendar, contacts, collaborative document editing with Nextcloud Office, video calls with Talk, task management and much more. The difference from commercial cloud is simple: the data sits on your server, in a volume that you administer, and nobody analyses or resells it.
What do you need before you start?
You need a Linux machine with Docker and the Compose plugin already installed. If you do not have it yet, follow the guide to install Docker on Ubuntu 24.04 first. For home or small-team use, 2 GB of RAM and a couple of cores are enough, though it is worth moving to 4 GB if you are going to edit documents online.
The setup relies on two data services you may want to get to know separately: the MariaDB database, where Nextcloud stores its metadata, and Redis, which acts as a cache and as a transactional file-locking system. In this tutorial we define them inside the same docker-compose.yml, so there is no need to install them separately.
The Nextcloud docker-compose.yml with MariaDB and Redis
Create a folder for the project and save this docker-compose.yml inside it. Replace each cambia_esta_clave... value with your own strong password before starting:
services:
db:
image: mariadb:11.4
restart: unless-stopped
command: --transaction-isolation=READ-COMMITTED --log-bin=binlog --binlog-format=ROW
volumes:
- db_data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: change_this_root_key
MYSQL_DATABASE: nextcloud
MYSQL_USER: nextcloud
MYSQL_PASSWORD: change_this_key
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
interval: 30s
timeout: 5s
retries: 5
redis:
image: redis:7.4-alpine
restart: unless-stopped
command: redis-server --requirepass change_this_redis_key
volumes:
- redis_data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 30s
timeout: 5s
retries: 5
app:
image: nextcloud:33-apache
restart: unless-stopped
ports:
- "8080:80"
depends_on:
db:
condition: service_healthy
redis:
condition: service_healthy
volumes:
- nextcloud_data:/var/www/html
environment:
MYSQL_HOST: db
MYSQL_DATABASE: nextcloud
MYSQL_USER: nextcloud
MYSQL_PASSWORD: change_this_key
REDIS_HOST: redis
REDIS_HOST_PASSWORD: change_this_redis_key
NEXTCLOUD_ADMIN_USER: admin
NEXTCLOUD_ADMIN_PASSWORD: change_this_admin_key
NEXTCLOUD_TRUSTED_DOMAINS: localhost cloud.mydomain.com
PHP_MEMORY_LIMIT: 512M
volumes:
db_data:
redis_data:
nextcloud_data:
Notice a few details in the file. The application does not start until the database and Redis pass their healthcheck, thanks to depends_on with the service_healthy condition. The container’s port 80 is published on the host’s port 8080, so the cloud will be at http://localhost:8080. And all the important state (data, configuration and apps) lives in the nextcloud_data volume, mounted at /var/www/html.
With the file ready, start the stack in the background and check that all three services are healthy:
docker compose up -d
docker compose ps
docker compose logs -f app
The first time, the image runs an installation script that unpacks Nextcloud and prepares the database, so the boot takes a little longer than usual. When the log stops moving, the cloud is ready.
First boot and configuration
Open http://localhost:8080 in the browser. Because we defined NEXTCLOUD_ADMIN_USER and NEXTCLOUD_ADMIN_PASSWORD in the Compose file, Nextcloud completes the installation with no wizard and takes you straight to the login. Sign in with those credentials and you will see your dashboard with the sample files.
The first thing to review is the security notice in Administration settings → Overview. There Nextcloud checks that Redis is connected, that the trusted-domains header is correct and that the scheduled tasks (cron) work. Maintenance commands use the occ tool, which you run inside the container as the www-data user:
docker compose exec --user www-data app php occ status
docker compose exec --user www-data app php occ config:list system
If you later change domain, add it to the trusted-domains list without recreating the container:
docker compose exec --user www-data app php occ config:system:set trusted_domains 2 --value=cloud.mydomain.com
How do you publish it with Traefik and HTTPS?
Serving Nextcloud over plain HTTP is a bad idea: passwords and files would travel unencrypted. The usual way to give it a valid certificate is to place it behind a reverse proxy that handles TLS for you. If you are following the series, you will already have Traefik with Docker Compose running; in that case, remove the ports section from the app service, connect it to the proxy network and add these labels:
labels:
- "traefik.enable=true"
- "traefik.http.routers.nextcloud.rule=Host(`cloud.mydomain.com`)"
- "traefik.http.routers.nextcloud.entrypoints=websecure"
- "traefik.http.routers.nextcloud.tls.certresolver=le"
- "traefik.http.services.nextcloud.loadbalancer.server.port=80"
Traefik will request the certificate from Let’s Encrypt and renew it automatically. Remember to set NEXTCLOUD_TRUSTED_DOMAINS to your real domain and, after the first HTTPS access, review the administration overview again so no pending warning about the proxy headers remains.
How do I take backups and updates?
A full Nextcloud backup has three pieces: the data volume, the configuration and the database dump. Put the instance into maintenance mode, export the database with mariadb-dump and enable it again:
docker compose exec --user www-data app php occ maintenance:mode --on
docker compose exec db mariadb-dump -u nextcloud -pchange_this_key nextcloud > nextcloud-db.sql
docker compose exec --user www-data app php occ maintenance:mode --off
You back up the nextcloud_data volume with whatever tool you prefer; in this series we automate it with Duplicati later. To update, change the image tag to the new version (or pull the current one) and recreate the container:
docker compose pull
docker compose up -d
The image detects the version mismatch and runs the internal upgrade on boot. One important limit: Nextcloud only allows moving up one major version at a time, so do not jump, for example, from 32 to 34 in one go; pass through 33 first.
Frequently asked questions
Do I really need Redis and MariaDB to use Nextcloud?
You can start Nextcloud with only the SQLite database it ships with by default, but that is not recommended beyond a test. MariaDB handles real load far better, and Redis provides the transactional file locking that avoids conflicts when several devices sync at once. For any serious use, the three containers are the standard configuration.
Why should I not use the image’s latest tag?
Because :latest changes without warning and can drag you into a new major version during a simple restart, when Nextcloud only allows moving from one major version to the next. By pinning nextcloud:33-apache you decide when you update and avoid an automatic update leaving your instance half-migrated.
What is the difference between the apache and fpm images?
The -apache variant includes a ready-to-use Apache web server and listens on port 80, ideal to get started. The -fpm variant only exposes PHP-FPM and needs a web server like Nginx in front of it, a more advanced setup that gives more control but requires an extra container. For a first installation, the Apache one is the simple choice.
Conclusion
With a single docker-compose.yml you have a complete private cloud: application, database and cache, all with data that never leaves your server. The logical next step is to take it to the Internet securely behind Traefik and schedule regular backups of the volume. From there you can enable Nextcloud Office, Talk or the calendar and replace, one by one, the commercial clouds you used to depend on.