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 nextcloud image), a MariaDB database and a Redis cache for file locking.
  • The whole installation lives in the /var/www/html volume, 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.

Sources

  1. Official Nextcloud documentation
  2. Nextcloud Docker image (nextcloud/docker on GitHub)
  3. Official nextcloud image on Docker Hub

Route: Self-hosted docs and productivity with Docker