Skip to content

Instantly share code, notes, and snippets.

@robertoschwald
Last active June 17, 2024 21:33
Show Gist options
  • Save robertoschwald/f852803908edda5d9360bbeabb647cbb to your computer and use it in GitHub Desktop.
Save robertoschwald/f852803908edda5d9360bbeabb647cbb to your computer and use it in GitHub Desktop.
Configure NextCloud Docker with nginx-proxy, MariaDB, Redis, LetsEncrypt and Cron Support
#!/usr/bin/env bash
# Create Nextcloud host directory structure, .env and docker-compose.yml files
# 2020 robertoschwald
# Consists of the following containers:
# nginx-proxy (frontend proxy)
# nginx-proxy-letsencrypt (LetsEncrypt issuing)
# nextcloud-app (Nextcloud application server)
# nextcloud-cron (Nextcloud cron server. Executes cron.php every few minutes)
# nextcloud-redis (Redis Server for Nextcloud file locking)
# nextcloud-mariadb (DB Server)
# All transaction data is stored on the Docker host, so you can take down / upgrade servers any time.
# Prerequisite
# For this script to work, you must at least have port 80 open to the internet,
# so LetsEncrypt certificates can be created successfully.
# Arm based Docker servers (like Pi):
# If you use an ARM based system like the Raspberry Pi,
# use the "andrewmacheret/docker-letsencrypt-nginx-proxy-companion" image instead in letsencrypt-companion
##############
# KNOWN ISSUES
##############
# CentOS8 / RHEL8 /Fedora 29 Container DNS fails:
# Prepare firewalld, otherwise containers cannot access the internet for DNS
# firewall-cmd --zone=public --add-masquerade --permanent
# firewall-cmd --reload
#
# cron.php not executed:
# Currently, the nextcloud-cron container executes cron.php, but this is not reflected in the nextcloud-app container
# See https://github.com/nextcloud/docker/issues/914
# Workaround:
# add file /etc/cron.d/nextcloud on the Docker host:
# */5 * * * * root docker exec --user www-data nextcloud-app php -f cron.php
##############
# Installation:
##############
# 1. Save this script
# 2. Modify the config section. The DATA_DIR is the toplevel host directory to store persisted files in.
# 3. Execute the script. This creates all directories and files needed
# 4. Create the docker networks manually. In this case, you can up / down the composables independently:
# docker network create --driver bridge nginx-proxy
# docker network create --driver bridge nextcloud
# 5. Execute 'docker-compose up -d' in the nginx-proxy/docker-build dir to startup the proxy with LE support
# 6. Execute 'docker-compose up -d' in the nextcloud/nextcloud-docker-build dir to startup all nextcloud containers.
# 7. After some minutes, you are able to access your installation with SSL cert installed.
# 8. Add missing indices and int values in db by executing the given occ commands.
# If you already have nginx-proxy running, you can skip step 4. Ensure to modify the nginx-proxy network name
# in this case to the existing one.
# DO NOT FORGET TO SECURE THIS FILE (e.g. chmod 700 prepare_nextcloud_docker.sh)
# Config. Modify as needed!
###############################################
DATA_DIR="/data/applications"
DOMAIN_NAME="cloud.example.com"
EMAIL="[email protected]"
DB_ROOT_PW="MySuperSecurePasswordForDbRoot"
DB_PW="MySuperSecureNexcloudDbPw"
REDIS_PW="MySuperSecureRedisPw"
###############################################
# macOS Catalina problem, so get from the symlink. Works on most OSs.
TIME_ZONE=`ls -al /etc/localtime | sed 's/.*\/zoneinfo\///g'`
mkdir -p ${DATA_DIR}/../ssl_certs
mkdir -p ${DATA_DIR}/nginx-proxy/etc/nginx/conf.d
mkdir -p ${DATA_DIR}/nginx-proxy/etc/nginx/vhost.d
mkdir -p ${DATA_DIR}/nginx-proxy/etc/nginx/htpasswd
mkdir -p ${DATA_DIR}/nginx-proxy/html
mkdir -p ${DATA_DIR}/nginx-proxy/docker-build
mkdir -p ${DATA_DIR}/nextcloud-mariadb/var/lib
mkdir -p ${DATA_DIR}/nextcloud-mariadb/etc/mysql/conf.d
mkdir -p ${DATA_DIR}/nextcloud-redis/etc
mkdir -p ${DATA_DIR}/nextcloud/etc/apache2/conf-enabled
mkdir -p ${DATA_DIR}/nextcloud/etc/php/conf.d
mkdir -p ${DATA_DIR}/nextcloud/html
mkdir -p ${DATA_DIR}/nextcloud/data
mkdir -p ${DATA_DIR}/nextcloud/var/log
mkdir -p ${DATA_DIR}/nextcloud/nextcloud-docker-build
echo " "
echo " "
if [ ! -f ${DATA_DIR}/nextcloud/nextcloud-docker-build/db.env ]; then
echo "Create ${DATA_DIR}/nextcloud/nextcloud-docker-build/db.env"
cat <<EOF > ${DATA_DIR}/nextcloud/nextcloud-docker-build/db.env
MYSQL_ROOT_PASSWORD="${DB_ROOT_PW}"
MYSQL_PASSWORD="${DB_PW}"
MYSQL_DATABASE=nextcloud
MYSQL_USER=nextcloud
EOF
fi
if [ ! -f ${DATA_DIR}/nextcloud/nextcloud-docker-build/nextcloud.env ]; then
echo "Create ${DATA_DIR}/nextcloud/nextcloud-docker-build/nextcloud.env"
cat <<EOF > ${DATA_DIR}/nextcloud/nextcloud-docker-build/nextcloud.env
# NextCloud does not know it runs behind a SSL Proxy
# See https://github.com/nextcloud/docker/issues/742
OVERWRITEPROTOCOL=https
EOF
fi
if [ ! -f ${DATA_DIR}/nextcloud/nextcloud-docker-build/redis.env ]; then
echo "Create ${DATA_DIR}/nextcloud/nextcloud-docker-build/redis.env"
cat <<EOF > ${DATA_DIR}/nextcloud/nextcloud-docker-build/redis.env
REDIS_HOST_PASSWORD="${REDIS_PW}"
EOF
fi
if [ ! -f ${DATA_DIR}/nextcloud-mariadb/etc/mysql/conf.d/override.conf ]; then
echo "Create ${DATA_DIR}/nextcloud-mariadb/etc/mysql/conf.d/override.conf"
cat <<EOF > ${DATA_DIR}/nextcloud-mariadb/etc/mysql/conf.d/override.conf
# Add override settings to this file as needed and restart the container.
[mysqld]
max_allowed_packet=32M
EOF
fi
if [ ! -f ${DATA_DIR}/nextcloud/etc/php/conf.d/override.ini ]; then
echo "Create ${DATA_DIR}/nextcloud/etc/php/conf.d/override.ini"
cat <<EOF > ${DATA_DIR}/nextcloud/etc/php/conf.d/override.ini
# PHP config overrides.
upload_max_filesize = 2048M
post_max_size = 2048M
max_execution_time = 900
EOF
fi
if [ ! -f ${DATA_DIR}/nextcloud/etc/apache2/conf-enabled/override.conf ]; then
echo "Create ${DATA_DIR}/nextcloud/etc/apache2/conf-enabled/override.conf"
cat <<EOF > ${DATA_DIR}/nextcloud/etc/apache2/conf-enabled/override.conf
# Add Nextcloud Apache2 config overrides in this file
EOF
fi
if [ ! -f ${DATA_DIR}/nextcloud/etc/php/conf.d/override-cron.ini ]; then
echo "Create ${DATA_DIR}/nextcloud/etc/php/conf.d/override-cron.ini"
cat <<EOF > ${DATA_DIR}/nextcloud/etc/php/conf.d/override-cron.ini
# PHP config overrides for nextcloud-cron Container.
# max_execution_time = 900
EOF
fi
if [ ! -f ${DATA_DIR}/nginx-proxy/etc/nginx/conf.d/override.conf ]; then
echo "Create ${DATA_DIR}/nginx-proxy/etc/nginx/conf.d/override.conf"
cat <<EOF > ${DATA_DIR}/nginx-proxy/etc/nginx/conf.d/override.conf
server_tokens off;
client_max_body_size 2000m;
EOF
fi
chmod 400 ${DATA_DIR}/nextcloud/nextcloud-docker-build/*.env
echo "Create ${DATA_DIR}/nginx-proxy/docker-build/docker-compose.yml"
cat <<EOF > ${DATA_DIR}/nginx-proxy/docker-build/docker-compose.yml
version: '3.5'
services:
# The NGINX proxy. This is the only container exposed to the world.
nginx-proxy:
image: jwilder/nginx-proxy
container_name: nginx-proxy
restart: unless-stopped
labels:
- "com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy=true"
ports:
- 80:80
- 443:443
volumes:
- ${DATA_DIR}/nginx-proxy/etc/nginx/conf.d/override.conf:/etc/nginx/conf.d/override.conf
- ${DATA_DIR}/nginx-proxy/etc/nginx/htpasswd:/etc/nginx/htpasswd
- ${DATA_DIR}/nginx-proxy/etc/nginx/vhost.d:/etc/nginx/vhost.d
- ${DATA_DIR}/nginx-proxy/html:/usr/share/nginx/html
- ${DATA_DIR}/../ssl_certs:/etc/nginx/certs:ro
- /var/run/docker.sock:/tmp/docker.sock:ro
environment:
- TZ=${TIME_ZONE}
networks:
- nginx-proxy
# The Companion to update Letsencrypt certificates.
letsencrypt-companion:
image: jrcs/letsencrypt-nginx-proxy-companion
container_name: nginx-proxy-letsencrypt
restart: unless-stopped
volumes:
- ${DATA_DIR}/nginx-proxy/etc/nginx/conf.d:/etc/nginx/conf.d
- ${DATA_DIR}/nginx-proxy/etc/nginx/vhost.d:/etc/nginx/vhost.d
- ${DATA_DIR}/nginx-proxy/html:/usr/share/nginx/html
- ${DATA_DIR}/../ssl_certs:/etc/nginx/certs:rw
- /var/run/docker.sock:/var/run/docker.sock:ro
depends_on:
- nginx-proxy
environment:
- TZ=${TIME_ZONE}
networks:
- nginx-proxy
networks:
nginx-proxy:
name: nginx-proxy
external: true
EOF
echo "Create ${DATA_DIR}/nextcloud/nextcloud-docker-build/docker-compose.yml"
cat <<EOF > ${DATA_DIR}/nextcloud/nextcloud-docker-build/docker-compose.yml
version: '3.5'
services:
# The MariaDB Database
db:
image: mariadb
container_name: nextcloud-mariadb
command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW
restart: unless-stopped
volumes:
- ${DATA_DIR}/nextcloud-mariadb/etc/mysql/conf.d/override.conf:/etc/mysql/conf.d/override.conf
- ${DATA_DIR}/nextcloud-mariadb/var/lib:/var/lib/mysql
- ${DATA_DIR}/nextcloud-mariadb/var/log:/var/log
environment:
- TZ=${TIME_ZONE}
env_file:
- db.env
networks:
- nextcloud
# Redis In-Memory store
redis:
image: redis
container_name: nextcloud-redis
restart: always
environment:
- TZ=${TIME_ZONE}
env_file:
- redis.env
networks:
- nextcloud
# Main NextCloud Container
app:
image: nextcloud
container_name: nextcloud-app
restart: unless-stopped
volumes:
- ${DATA_DIR}/nextcloud/html:/var/www/html
- ${DATA_DIR}/nextcloud/data:/var/www/html/data
- ${DATA_DIR}/nextcloud/etc/php/conf.d/override.ini:/usr/local/etc/php/conf.d/override.ini
environment:
- MYSQL_HOST=nextcloud-mariadb
- VIRTUAL_HOST=${DOMAIN_NAME}
- LETSENCRYPT_HOST=${DOMAIN_NAME}
- LETSENCRYPT_EMAIL=${EMAIL}
- REDIS_HOST=nextcloud-redis
- TZ=${TIME_ZONE}
env_file:
- db.env
- nextcloud.env
- redis.env
depends_on:
- db
- redis
links:
- db:clouddatabase
networks:
- nginx-proxy
- nextcloud
# NextCloud instance which runs crond on the same shared volume as the app
cron:
image: nextcloud
container_name: nextcloud-cron
restart: unless-stopped
volumes:
- ${DATA_DIR}/nextcloud/html:/var/www/html
- ${DATA_DIR}/nextcloud/data:/var/www/html/data
- ${DATA_DIR}/nextcloud/etc/php/conf.d/override-cron.ini:/usr/local/etc/php/conf.d/override-cron.ini
environment:
- TZ=${TIME_ZONE}
entrypoint: /cron.sh
env_file:
- db.env
depends_on:
- app
networks:
nginx-proxy:
external: true
nextcloud:
name: nextcloud
external: true
EOF
echo " "
echo " "
echo "FILES CREATED"
echo " "
echo "1. Power up your nginx-proxy containers (only if not already running)"
echo "cd ${DATA_DIR}/nginx-proxy/docker-build"
echo "docker-compose up -d"
echo " "
echo "2. Power up your nextcloud containers:"
echo "cd ${DATA_DIR}/nextcloud/nextcloud-docker-build"
echo "docker-compose up -d"
echo " "
echo "3. Access https://${DOMAIN_NAME} and create an admin user"
echo " "
echo "4. Create optional Nextcloud db indexes"
echo "docker exec --user www-data nextcloud-app php occ db:add-missing-indices"
echo "docker exec --user www-data nextcloud-app php occ db:convert-filecache-bigint"
echo " "
# end
@QuentinFonteneau
Copy link

Hi !
I solved the Redis problem by adding this in docker-compose.yml (redis service) :
command: redis-server --requirepass myPasswordRedis

@dirtyharrywk
Copy link

Keep getting "Access through untrusted domain

Please contact your administrator. If you are an administrator, edit the "trusted_domains" setting in config/config.php like the example in config.sample.php."
When I enter the URL into my browser. The config.php file was empty. This is what baffles me about containers, I do not know which container to edit the config.php file. I have six containers running, nextcloud-cron, next cloud-app, nextcloud-mariadb, nextcloud-redis, nginx-proxy-letsencrypt and nginx-proxy. Any help would be greatly appreciated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment