Apps / Docker Images
Nextcloud in Docker.
Redis, APCu, proxy-aware.
Nextcloud is an open source platform for file sync and share, calendar, contacts, notes, and real-time collaboration that you run on your own infrastructure. It gives a team a private alternative to hosted file and office suites, with desktop and mobile clients, document editing, and a large app ecosystem.
docker pull ghcr.io/remarkablecloud/nextcloud Current build
34.0.3-r1
Updated Sep 10, 2026
Base
Nextcloud stable (Apache), digest-pinned
What's inside
Redis file locking and cache, APCu, MariaDB pairing, trusted-domain wiring
Upstream license
Nextcloud: AGPL-3.0-or-later
Free to pull and run anywhere. Digest-pinned, updated deliberately; each build is recorded in the changelog.
The image
What our image adds.
Nextcloud is an open source platform for file sync and share, calendar, contacts, notes, and real-time collaboration that you run on your own infrastructure. It gives a team a private alternative to hosted file and office suites, with desktop and mobile clients, document editing, and a lar
Digest-pinned base
The image is built from `nextcloud:stable-apache@sha256:b97df9e0e1ee3c8c6cc009cb3f12ddce915d624d543b3bb93882025fe323a407` (Nextcloud 34.0.3). Pinning by digest keeps rebuilds reproducible: the base changes only when we bump the digest on purpose.
Reverse-proxy config baked in
The image ships `overwriteprotocol=https`, a `trusted_proxies` list for the private container networks, and `overwritehost` plus `overwrite.cli.url` derived from `NC_OVERWRITE_HOST`. The hostname is read from the environment on each request, so canonical links
Redis and APCu caching wired
Redis is used for the distributed cache and for file locking, and APCu is enabled for the fast local cache, which is the configuration Nextcloud recommends for a responsive multi-user instance.
PHP tuned
OPcache is enabled and sized, and `expose_php` is turned off so the PHP version banner is not advertised.
Automatic first-run admin password
On the first install, if no admin password is provided, the image generates a strong random password and prints it once to the container log to be handed to the customer. No default credential is ever baked in.
Healthcheck
A container `HEALTHCHECK` polls `/status.php` so the platform routes traffic only once Nextcloud is up and its code is in place. The current published tag is `ghcr.io/remarkablecloud/nextcloud:34.0.3-r1`. Nextcloud is a trademark of its respective owner. Remar
Rather skip the compose file? Deploy Nextcloud with one click on your own VPS: TLS, domain and database already wired.
Deploy Nextcloud in one clickThe guide
Run it in production.
Architecture at a glance
- Nextcloud (Apache and PHP) serves plain HTTP on port
80. TLS is terminated upstream by a reverse proxy (Traefik on the RemarkableCloud App Platform), so there is no in-container certificate to manage. - MariaDB is a separate database container and holds all metadata (users, shares, file index, app data).
- Redis is a separate container used for the distributed cache and transactional file locking.
- A data volume at
/var/www/htmlholds the Nextcloud code, the mergedconfig/, apps, and user files that must survive a container replacement.
Docker Compose walkthrough
The standalone stack (Nextcloud, MariaDB, Redis, and named volumes) is defined
in the image’s docker-compose.yml:
name: nextcloud
services:
db:
image: mariadb:11
restart: unless-stopped
command: ["--transaction-isolation=READ-COMMITTED", "--log-bin=binlog", "--binlog-format=ROW"]
environment:
MARIADB_DATABASE: nextcloud
MARIADB_USER: nextcloud
MARIADB_PASSWORD: ${DB_PASSWORD:-change-me-db}
MARIADB_ROOT_PASSWORD: ${DB_ROOT_PASSWORD:-change-me-root}
volumes: [db-data:/var/lib/mysql]
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
interval: 10s
timeout: 5s
retries: 12
redis:
image: redis:7-alpine
restart: unless-stopped
command: ["redis-server", "--requirepass", "${REDIS_PASSWORD:-change-me-redis}"]
app:
image: ${NC_IMAGE:-ghcr.io/remarkablecloud/nextcloud:34.0.3-r1}
restart: unless-stopped
depends_on:
db:
condition: service_healthy
ports: ["${HTTP_PORT:-8082}:80"]
environment:
MYSQL_HOST: db
MYSQL_DATABASE: nextcloud
MYSQL_USER: nextcloud
MYSQL_PASSWORD: ${DB_PASSWORD:-change-me-db}
REDIS_HOST: redis
REDIS_HOST_PORT: "6379"
REDIS_HOST_PASSWORD: ${REDIS_PASSWORD:-change-me-redis}
NEXTCLOUD_ADMIN_USER: ${NEXTCLOUD_ADMIN_USER:-admin}
NEXTCLOUD_ADMIN_PASSWORD: ${NEXTCLOUD_ADMIN_PASSWORD:-}
NEXTCLOUD_TRUSTED_DOMAINS: ${NEXTCLOUD_TRUSTED_DOMAINS:-localhost}
NC_OVERWRITE_HOST: ${NC_OVERWRITE_HOST:-}
volumes:
- nc-data:/var/www/html
volumes:
db-data:
nc-data:
Step by step:
- MariaDB is tuned for Nextcloud.
READ-COMMITTEDisolation with row-based binary logging is the configuration Nextcloud recommends. The healthcheck waits until InnoDB is initialized. - Redis requires a password. The
redisservice starts with--requirepass, and the app connects withREDIS_HOST_PASSWORD, so the cache and lock store are not open on the network. - The app waits for the database.
depends_onwithcondition: service_healthyavoids a first-boot race against MariaDB. - The image is pinned.
NC_IMAGElets you override the tag for a local trial. The App Platform does not use this compose file; it deploys the catalog tag directly (currently34.0.3-r1), which is also the compose default here. - The admin password is generated if blank.
NEXTCLOUD_ADMIN_PASSWORDis left empty here, so the image creates one on first install and logs it once. - Only the web port is exposed.
${HTTP_PORT:-8082}:80is for local use. In production Traefik connects to port80on the internal network and nothing is bound on the host. - State lives in volumes.
nc-data(/var/www/html) anddb-datapersist across restarts and upgrades.
To start it locally:
REDIS_PASSWORD=$(openssl rand -hex 16) DB_PASSWORD=$(openssl rand -hex 16) \
NEXTCLOUD_ADMIN_PASSWORD=$(openssl rand -hex 12) docker compose up -d
Then browse to http://localhost:8082. If you leave NEXTCLOUD_ADMIN_PASSWORD
unset, read the generated password from docker compose logs app.
For production, set NC_OVERWRITE_HOST and NEXTCLOUD_TRUSTED_DOMAINS to your
real domain, point the MYSQL_* and REDIS_* variables at your managed
services, and put the container behind a TLS-terminating proxy.
Environment variable reference
These are the values the App Platform backend wires automatically from the
managed MariaDB and Redis ({...} placeholders are filled per install). They
are listed here for standalone and self-hosted runs.
| Variable | Required | Value / default | Purpose |
|---|---|---|---|
MYSQL_HOST | yes | <db_host> | MariaDB host (the db service in Compose). |
MYSQL_DATABASE | yes | <db_name> | Database name. |
MYSQL_USER | yes | <db_user> | Database user. |
MYSQL_PASSWORD | yes | <db_password> | Database password. |
REDIS_HOST | yes | <redis_host> | Redis host for distributed cache and file locking. |
REDIS_HOST_PORT | yes | 6379 | Redis port. |
REDIS_HOST_PASSWORD | yes | <redis_password> | Redis password. |
NEXTCLOUD_ADMIN_USER | yes | admin | Admin account created on first install. |
NEXTCLOUD_ADMIN_PASSWORD | no | (generated) | Admin password. Leave empty to auto-generate on first run; the value is printed once to the container log. |
NEXTCLOUD_TRUSTED_DOMAINS | yes | <hostname> | Domains Nextcloud will answer for. |
NC_OVERWRITE_HOST | yes | <hostname> | Canonical host for links and CLI URLs behind the proxy. |
Only the first install reads NEXTCLOUD_ADMIN_USER and
NEXTCLOUD_ADMIN_PASSWORD; once config/config.php exists they are ignored, and
account changes happen inside Nextcloud.
Hardening notes
- No baked credentials. The admin password is generated at runtime on first install and printed once to the log, never stored in an image layer.
- Reverse-proxy trust is scoped.
trusted_proxiescovers the private container ranges only, andoverwriteprotocol=httpsensures Nextcloud builds HTTPS links behind the proxy without trusting arbitrary forwarded headers. - PHP version hidden.
expose_php=Offremoves theX-Powered-Bybanner. - Digest-pinned base. Each build is auditable and reproducible.
- Healthcheck gates traffic.
/status.phpmust return success before the platform routes requests. - Keep MariaDB and Redis private. Do not publish their ports to the host or the internet; Redis is password-protected in the standalone stack.
- After install, run the security checklist. In Nextcloud’s admin overview,
clear any warnings (for example, add any missing recommended database indices
with
occ). For the background job mode, note that this stack has no cron sidecar; the default is AJAX, and switching to the recommended Cron mode requires a separate cron runner, which is not included here.
Backups
Capture the database and the data volume together for a restorable backup:
- The MariaDB database:
docker compose exec db mysqldump -u root -p"$DB_ROOT_PASSWORD" nextcloud > nextcloud-db.sql - The data volume at
/var/www/html(config, apps, and user files):docker run --rm -v nextcloud_nc-data:/data -v "$PWD":/backup alpine \ tar czf /backup/nextcloud-data.tgz -C /data .
For a fully consistent copy of large instances, enable maintenance mode first
(occ maintenance:mode --on), back up, then turn it off. On the RemarkableCloud
App Platform, database and volume backups follow the platform’s backup schedule.
Upgrades
- Nextcloud upgrades one major version at a time. Do not skip a major release; move 34 to 35 to 36 in order, not straight to a later version.
- New builds ship as new
-rtags. Pull the new tag and recreate the container; the upstream entrypoint runs the upgrade and any migrations on start:docker compose pull app && docker compose up -d app - Always back up first. Keep the database dump and data archive from just before the upgrade.
- Read the changelog. Every build is listed in
CHANGELOG.mdwith the upstream version, base image digest, and any behavior or breaking changes. - Watch app compatibility. Third-party apps may need updates or may be temporarily disabled across a major upgrade.
Updates
Recent builds.
34.0.3-r1
Sep 10, 2026First changelog entry for the RemarkableCloud Nextcloud image. This build packages Nextcloud 34.0.3 (Apache and PHP in a single container) for the RemarkableCloud App Platform.
Or skip the ops
Host Nextcloud on your own private VPS.
One click installs this exact image on a VPS that is yours alone, domain and TLS wizard included. The same server runs as many apps as fit, with no per-app charge.
FAQ
Questions we get.
Does this image include a database or Redis?
No. MariaDB and Redis run as separate containers or managed services. The standalone compose file includes both for convenience.
Can I use MySQL instead of MariaDB?
Yes, Nextcloud supports MySQL 8 as well; point the `MYSQL_*` variables at it. The RemarkableCloud stack ships MariaDB by default.
Where does the admin password come from?
If you set `NEXTCLOUD_ADMIN_PASSWORD`, that value is used. If you leave it empty, the image generates a strong random password on first install and prints it once to the container log.
How does HTTPS work if the container only serves HTTP on port 80?
TLS is terminated at the reverse proxy (Traefik on the App Platform). The image sets `overwriteprotocol=https` and trusts the private proxy network, so Nextcloud builds correct HTTPS links.
Why do I need Redis?
Redis provides the distributed cache and transactional file locking, which keeps a multi-user instance responsive and avoids file-locking errors. APCu handles the fast local cache.
Your server runs. You sleep.
Fully managed hosting from people who have been doing this since 2001.