Nextcloud FPM stack (Nginx + MariaDB + Redis + Cron) with ffmpeg + ImageMagick added for RPi 4 & 5
10K+
Nextcloud FPM running behind Nginx, with MariaDB, Redis, and a cron worker. Designed for Raspberry Pi 5 (ARM64), but also usable on other Docker hosts.
This stack uses:
iamjavadali/nextcloudpi for the PHP-FPM app containernginx:stable-alpine as the web front-endmariadb:11.8redis:alpinenextcloud-cron containerThe compose file uses:
./app and ./db8080:80 on the web containernextcloud networkproxy network for reverse proxy integrationBrowser / Reverse Proxy
│
▼
nextcloud-web (nginx:stable-alpine, port 80 inside container)
│
▼
nextcloud-app (iamjavadali/nextcloudpi, PHP-FPM :9000)
│
┌────┴────┐
▼ ▼
nextcloud-db nextcloud-redis
(MariaDB 11.8) (redis:alpine)
nextcloud-cron shares the app bind mount and runs background jobs via /cron.sh.
docker-compose.yml — full Nextcloud stack.env.example — starter environment variablesnginx.conf — internal Nginx config for the web containerREADME.md — this filecp .env.example .env
nano .env
docker compose up -d
You do not need to create the app and db folders manually first. Docker Compose will create those bind-mounted host directories automatically on first startup.
Then open Nextcloud using one of these patterns, depending on your setup:
http://<host-ip>:8080https://cloud.yourdomain.comUse this when you want to open Nextcloud directly on your server IP and port 8080.
Example:
http://192.168.1.115:8080
.env values# ---- DOMAIN / OVERWRITE NEXTCLOUD ----
OVERWRITECLIURL=http://192.168.1.115:8080
OVERWRITEHOST=192.168.1.115:8080
OVERWRITEPROTOCOL=http
NEXTCLOUD_TRUSTED_DOMAINS=localhost 192.168.1.115 nextcloud-app
# Private proxy ranges cover most normal home/LAN setups
TRUSTED_PROXIES_NEXTCLOUD=127.0.0.0/8 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16
OVERWRITEPROTOCOL=http is correct for direct non-TLS access.OVERWRITEHOST should match the exact hostname or IP and port used in the browser.OVERWRITECLIURL should match the full URL you want Nextcloud to generate for links and CLI jobs.NEXTCLOUD_TRUSTED_DOMAINS.Use this when Nextcloud is behind something like:
Example public URL:
https://cloud.yourdomain.com
.env values# ---- DOMAIN / OVERWRITE NEXTCLOUD ----
OVERWRITECLIURL=https://cloud.yourdomain.com
OVERWRITEHOST=cloud.yourdomain.com
OVERWRITEPROTOCOL=https
NEXTCLOUD_TRUSTED_DOMAINS=cloud.yourdomain.com nextcloud-app
TRUSTED_PROXIES_NEXTCLOUD=127.0.0.0/8 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16
OVERWRITEPROTOCOL=https is required when users access Nextcloud over HTTPS.OVERWRITEHOST should be the public hostname only, without https://.OVERWRITECLIURL should be the full public URL.web container is attached to the external proxy network specifically for reverse-proxy integration..env)Copy .env.example to .env and update these values at minimum.
| Variable | Description |
|---|---|
MYSQL_ROOT_PASSWORD | MariaDB root password |
MYSQL_PASSWORD | MariaDB app user password |
MYSQL_DATABASE | MariaDB database name |
MYSQL_USER | MariaDB app user |
MYSQL_HOST | Database service hostname, default db |
REDIS_HOST | Redis service hostname, default redis |
NEXTCLOUD_ADMIN_USER | Initial admin username |
NEXTCLOUD_ADMIN_PASSWORD | Initial admin password |
OVERWRITECLIURL | Full browser/CLI URL |
OVERWRITEHOST | Hostname or IP:port used by browser logins |
OVERWRITEPROTOCOL | http for direct local use, https behind TLS proxy |
NEXTCLOUD_TRUSTED_DOMAINS | Space-separated allowed hostnames/IPs |
TRUSTED_PROXIES_NEXTCLOUD | Proxy IP ranges |
| SMTP variables | Mail server settings for notifications and password resets |
.env.example# ---- DATABASE ----
MYSQL_ROOT_PASSWORD=CHANGE_ME_ROOT
MYSQL_PASSWORD=CHANGE_ME_DBUSER
MYSQL_DATABASE=nextclouddb
MYSQL_USER=admin
MYSQL_HOST=db
# ---- REDIS ----
REDIS_HOST=redis
# ---- NEXTCLOUD ADMIN DASHBOARD ----
NEXTCLOUD_ADMIN_USER=admin
NEXTCLOUD_ADMIN_PASSWORD=Change_Me_Admin123$
nextcloud-web is attached to both:
nextcloud networkproxy networkdb, redis, and cron stay on the internal nextcloud network onlyweb exposes 8080 on the host with 8080:80This stack uses bind mounts next to the compose file:
| Path | Contents |
|---|---|
./app/ | Nextcloud files, config, apps, and data |
./db/ | MariaDB data files |
Both directories are intended to stay outside git and should be backed up regularly.
docker exec nextcloud-db sh -c \
'mysqldump -u"$MYSQL_USER" -p"$MYSQL_PASSWORD" "$MYSQL_DATABASE"' > backup.sql
The included nginx.conf is written as an internal web container config. It explicitly says no public server_name is needed because domain routing is expected to happen externally. It also sets fastcgi_param HTTPS on, which is useful for reverse-proxy-style deployments but worth remembering if you are troubleshooting direct local HTTP behavior.
After the stack is running and you've logged in for the first time, continue with the full post-install guide here:
That guide covers:
occ commandsdocker exec nextcloud-app php occ config:system:set server_id \
--value="nextcloudpi-primary"
docker exec -u www-data nextcloud-app php occ config:system:set default_phone_region --value="US"
docker exec -u www-data nextcloud-app php occ config:system:set maintenance_window_start --type=integer --value=1
docker exec -u www-data nextcloud-app php occ db:add-missing-indices
docker exec -u www-data nextcloud-app php occ maintenance:repair --include-expensive
docker exec -u www-data nextcloud-app php occ status
docker exec -u www-data nextcloud-app php occ config:list system --private
docker compose logs -f web app db
docker exec -u www-data -it nextcloud-app php occ status
docker exec -u www-data -it nextcloud-app php occ app:list
docker exec -u www-data -it nextcloud-app php occ user:resetpassword admin
docker exec -it nextcloud-app /bin/bash
docker compose pull
docker compose up -d
docker compose down --volumes
rm -rf app db
docker compose up -d
The upstream nextcloud:fpm image ships the imagick PHP extension compiled for x86_64. On ARM64 (aarch64) this causes SIGSEGV worker crashes when processing images. This image fixes it by recompiling imagick via PECL during the Docker build.
PHP 8.x OPcache JIT is also unstable on ARM64 and causes additional SIGSEGV crashes. The Dockerfile disables it via zzz-arm64-jit-disable.ini, named with the zzz- prefix so it loads after opcache-recommended.ini.
# Use official Nextcloud FPM image (pulls linux/arm64 natively on Raspberry Pi 5)
FROM nextcloud:fpm
RUN set -ex; \
apt-get update; \
apt-get install -y --no-install-recommends \
ffmpeg \
ghostscript \
libmagickwand-dev \
libmagickcore-7.q16-10-extra \
; \
rm -rf /var/lib/apt/lists/*; \
pecl uninstall imagick; \
pecl install imagick; \
docker-php-ext-enable imagick
# Disable OPcache JIT — unstable on ARM64
RUN { \
echo 'opcache.jit=disable'; \
echo 'opcache.jit_buffer_size=0'; \
} > /usr/local/etc/php/conf.d/zzz-arm64-jit-disable.ini
A Dockerfile is included if you want to build the image yourself instead of pulling from Docker Hub.
docker build -t iamjavadali/nextcloudpi:local .
Then update docker-compose.yml to use a local build instead of the published image.
Example approach:
app:
build:
context: .
image: iamjavadali/nextcloudpi:local
The current compose file uses image: iamjavadali/nextcloudpi for both app and cron.
Use this folder if you want a Nextcloud stack with:
For local use, set the .env for http and your IP:port.
For reverse proxy use, set the .env for https and your public hostname.
Content type
Image
Digest
sha256:8d869420a…
Size
696.9 MB
Last updated
6 months ago
docker pull iamjavadali/nextcloudpi