{"id":15136288,"url":"https://github.com/thomassteinreiter/nextcloud-setup-docs","last_synced_at":"2026-01-18T20:33:21.676Z","repository":{"id":198915853,"uuid":"701795654","full_name":"thomassteinreiter/nextcloud-setup-docs","owner":"thomassteinreiter","description":"This is a documentation project for a Nextcloud setup.","archived":false,"fork":false,"pushed_at":"2024-06-23T09:24:30.000Z","size":16,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-02-12T08:36:53.575Z","etag":null,"topics":["apache","docker","docker-compose","elasticsearch","nextcloud","nextcloud-server","redis-server"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thomassteinreiter.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-10-07T15:24:55.000Z","updated_at":"2024-06-23T09:24:33.000Z","dependencies_parsed_at":"2024-06-09T13:32:37.305Z","dependency_job_id":"b8601e51-709d-4300-9009-359f7410fd8d","html_url":"https://github.com/thomassteinreiter/nextcloud-setup-docs","commit_stats":{"total_commits":12,"total_committers":1,"mean_commits":12.0,"dds":0.0,"last_synced_commit":"738b722c2a5272133e4fcfbe8a7afaa33954b7f3"},"previous_names":["thomassteinreiter/nextcloud-setup-docs"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomassteinreiter%2Fnextcloud-setup-docs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomassteinreiter%2Fnextcloud-setup-docs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomassteinreiter%2Fnextcloud-setup-docs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomassteinreiter%2Fnextcloud-setup-docs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thomassteinreiter","download_url":"https://codeload.github.com/thomassteinreiter/nextcloud-setup-docs/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247425452,"owners_count":20936951,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["apache","docker","docker-compose","elasticsearch","nextcloud","nextcloud-server","redis-server"],"created_at":"2024-09-26T06:20:21.375Z","updated_at":"2026-01-18T20:33:21.670Z","avatar_url":"https://github.com/thomassteinreiter.png","language":"PHP","readme":"# Nextcloud Setup Documentation\n\n## Disclaimer\n\nThis is a work in progress and currently very, very incomplete.\n\n\n## Introduction\n\nThis is a documentation project for a [Nextcloud](https://nextcloud.com) setup. I invested a lot of time to get Nextcloud running the way I needed it to. I learned a lot on the way. This documentation contains the knowledge that is most helpful to me and most likely to others as well.\n\n\n## Basic Architecture and Technologies\n\n* [Ubuntu Server](https://ubuntu.com/download/server)\n* [Apache HTTP Server](https://httpd.apache.org/) (as Reverse-Proxy/Gateway)\n  * [Let's encrypt SSL](https://certbot.eff.org/instructions) (EFF certbot)\n* [Docker](https://www.docker.com/get-started/)\n  * [Nextcloud](https://hub.docker.com/_/nextcloud/)\n  * [Redis](https://hub.docker.com/_/redis)\n  * [MariaDB](https://hub.docker.com/_/mariadb)\n  * [Elastic](https://hub.docker.com/_/elasticsearch)\n\n\n### Architecture Motivation\n\nThere is a lot of documentation for Ubuntu Server available and I am already used to Ubuntu.\n\nRegarding Docker: Nextcloud is a complex piece of software requiring countless dependencies. Technically, you can install and maintain (update) everything yourself, but with Docker, everything needed is packaged in an Docker image and there are less possibilites for stuff going wrong. Docker, in a certain way, decouples the OS maintenance (update/upgrade, backup/restore) from the Nextcloud software and data.\n\nIt is possible to directly use the nextcloud container, but I choose to put an Apache Web Server in front of for the following reasons: I have already an Apache Web Server running for different usecases, I am already used to Apache Web Server and I found it hard to get the Let's Encrypt certbot renewal working inside Docker. This is why I am using the Apache Web Server as an \"Reverse Proxy\" to forward the requests to the Docker. I then can use the \"standard way\" of setting up Let's Encrypt, which is good documented.\n\nNextcloud can (in an minimal setup) operate with an embedded Database, but since I am going for a setup with multiple Nextcloud users, I am using a dedicated MariaDB as database and Redis for session/locking handling.\n\nNextcloud has an integrated search feature, but this is limited to the names of files and folders, which is fine most of the time, but files are not named well and you have no idea where to look. Full text search is a game-changer in those situations. I set up Nextcloud with Elastic with full text search.\n\n\n## Apache Web Server Setup\n\nThe following setup is compiled from the following sources:\n * https://docs.nextcloud.com/server/latest/admin_manual/office/example-docker.html#install-the-apache-reverse-proxy\n * https://docs.nextcloud.com/server/latest/admin_manual/configuration_files/big_file_upload_configuration.html#apache-with-mod-proxy-fcgi\n * https://docs.nextcloud.com/server/latest/admin_manual/installation/harden_server.html#enable-http-strict-transport-security\n\n\n```\napt install apache2 # install web server\n\na2enmod proxy # install requirements for reverse-proxy\na2enmod proxy_http\na2enmod headers\na2enmod remoteip\n```\n\nInstall SSL certificates. Follow: https://certbot.eff.org/\n\nCreate config file\n```\n/etc/apache2/conf-enabled/1-nextcloud.conf\n```\nwith contents:\n```\nProxyPreserveHost On\nAllowEncodedSlashes NoDecode\n\n# support slow/large uploads/downloads\nProxyTimeout 3600\n\n# support large uploads via the sync clients\nSetEnv proxy-sendchunked 1\n\n# main reverse proxy rules\nProxyPass \"/\"  \"http://127.0.0.1:11000/\" nocanon\nProxyPassReverse \"/\"  \"http://127.0.0.1:11000/\"\n\n# enable websocket proxying\nRewriteCond %{HTTP:Upgrade} websocket [NC]\nRewriteCond %{HTTP:Connection} upgrade [NC]\nRewriteCond %{THE_REQUEST} \"^[a-zA-Z]+ /(.*) HTTP/\\d+(\\.\\d+)?$\"\nRewriteRule .? \"ws://localhost:11000/%1\" [P,L]\n\n# Enable h2, h2c and http1.1\nProtocols h2 h2c http/1.1\n\n# hardening\nTraceEnable off\n\u003cFiles \".ht*\"\u003e\n  Require all denied\n\u003c/Files\u003e\n\n# Support big file uploads\nLimitRequestBody 0\n\n# SSL hardening\nHeader always set Strict-Transport-Security \"max-age=15552000; includeSubDomains\"\n```\nEnable the conf with:\n```\na2enconf 1-nextcloud\n```\n\nTo get WebDAV working, the following changes needed to be done, unfortunately directly in config file that contains the `\u003cVirualHost *:443\u003e`. For me that is `/etc/apache2/sites-enabled/000-default-le-ssl.conf`\n\nPut this inside the `\u003cVirualHost *:443\u003e` block:\n```\nRewriteEngine On\nRewriteRule ^/\\.well-known/carddav https://%{SERVER_NAME}/remote.php/dav/ [R=301,L]\nRewriteRule ^/\\.well-known/caldav https://%{SERVER_NAME}/remote.php/dav/ [R=301,L]\n```\n\n## Docker Setup\n\n### Install Docker Engine\n\nSince I want to use the latest Docker images and feature, I am not using Docker from the default ubuntu repository, but use the official Docker repository instead.\n\nhttps://docs.docker.com/engine/install/ubuntu/#install-using-the-repository\n\n```\n# https://docs.docker.com/engine/install/ubuntu/#install-using-the-convenience-script\n# Not recommended for production systems\ncurl -fsSL https://get.docker.com -o get-docker.sh\nsh ./get-docker.sh\n\napt install docker-compose\n```\n\n### Install Docker Compose\nDocker Compose handles the downloading of Docker images, creating of containers, networks, volumes, starting and stopping of containers and so on. It is a very powerful tool that makes working with multiple Docker container that need to be connected together very easy. But since it can and will remove containers and volumes, it is very easy to accidentally delete all your data, be careful and always make backups before making changes on production systems.\n\n```\napt install docker-compose\n```\n\n## Docker-Compose Setup\n\nsee [docker-compose-files/nextcloud/](docker-compose-files/nextcloud/) for the complete directory.\n\n\n### [docker-compose.yml](docker-compose-files/nextcloud/docker-compose.yml)\n\n#### database (db) section\n```\n...\n  db:\n    image: mariadb:${MARIADB_VERSION}\n    restart: always\n    stop_grace_period: 5m\n    command: --log-bin=binlog --binlog-format=ROW\n    volumes:\n      - nextcloud_db:/var/lib/mysql\n    environment:\n      - MYSQL_ROOT_PASSWORD=myMySQLRootPassword\n      - MYSQL_PASSWORD=mySqlPassword\n      - MYSQL_DATABASE=nextcloud\n      - MYSQL_USER=nextcloud\n...\n```\n\nThe `command: --log-bin=binlog --binlog-format=ROW` command line arguments are required. see: https://docs.nextcloud.com/server/27/admin_manual/installation/system_requirements.html#database-requirements-for-mysql-mariadb. Note: `stop_grace_period` sets the time before the container is forcefully killed. (The default is insanely low (10s))\n\n#### nextcloud (app) section\n```\n  app:\n    build:\n      context: nc\n      args:\n        - NEXTCLOUD_VERSION=${NEXTCLOUD_VERSION}\n    image: custom-nextcloud:${NEXTCLOUD_VERSION}-apache\n    container_name: nextcloud_app_1\n    restart: always\n    stop_grace_period: 5m\n    depends_on:\n      - db\n      - redis\n      #- elastic\n    ports:\n      - 11000:80\n    volumes:\n      - nextcloud_data:/var/www/html\n      - ./previews.config.php:/var/www/html/config/previews.config.php:ro\n      - ./remoteip.conf:/etc/apache2/conf-available/remoteip.conf:ro\n    environment:\n      - PHP_MEMORY_LIMIT=1024M\n      - NEXTCLOUD_TRUSTED_DOMAINS=localhost,myserver.mydomain.org\n      - TRUSTED_PROXIES=\"localhost 192.168.1.2\"\n      - OVERWRITEHOST=myserver.mydomain.org\n      - OVERWRITEPROTOCOL=https\n      - MYSQL_PASSWORD=mySqlPassword\n      - MYSQL_DATABASE=nextcloud\n      - MYSQL_USER=nextcloud\n      - MYSQL_HOST=db\n      - REDIS_HOST=redis\n```\n##### custom build\nthis points to a Dockerfile in subdirectory [nc](docker-compose-files/nextcloud/nc)\n```\n    build:\n      context: nc\n    image: custom-nextcloud:27.1.2-apache\n    container_name: nextcloud_app_1\n```\nadditionally, set the `image` and `container_name` name. Since this is a custom build, it is good to have a recognizable image name. (e.g. `docker ps`). There seems to be a inconsistency in Docker-Compose with the auto-naming of the container, depending if it is a \"initial\" start of the container or a \"update\" of a running container. e.g. `nextcloud_app_1` vs. `nextcloud-app-1`. This can be problematic if we want to run commands automatically that require the container name. (e.g. cron) To workaround this, we can explicitly set the `container_name`.\n\n##### increase memory\nThe default PHP memory value is 512MB. I ran into issues with thumbnail generation for a hand full of larger images. Increasing to 1024MB (`- PHP_MEMORY_LIMIT=1024M`) fixed this for me.\n\n##### proxy config\nNextcloud has a automatic system and security check here: `https://myserver.mydomain.org/settings/admin/overview` that complains about several problems in the beginning that come from running Nextcloud behind a reverse proxy. To get a proper setup, the following properties must be set:\n```\n      - NEXTCLOUD_TRUSTED_DOMAINS=localhost,myserver.mydomain.org\n      - TRUSTED_PROXIES=\"localhost 192.168.1.2\"\n      - OVERWRITEHOST=myserver.mydomain.org\n      - OVERWRITEPROTOCOL=https\n```\n\n#### redis section\n```\n  redis:\n    image: redis:6.2.13\n    restart: always\n    command: [\"--databases\", \"1\"]\n    volumes:\n      - nextcloud_redis:/data\n```\nthe one adjustment is `command: [\"--databases\", \"1\"]`. Redis has 16 databases per default to improve performance. Since I run this setup only a few users and the hardware is not very powerful, I setting this to the minimal amount to save resources.\n\n#### elastic section\n```\n  elastic:\n    build:\n      context: elastic\n      args:\n        - ELASTIC_VERSION=${ELASTIC_VERSION}\n    image: custom-elasticsearch:${ELASTIC_VERSION}\n    restart: always\n    stop_grace_period: 1m\n    volumes:\n      - nextcloud_elastic_data:/usr/share/elasticsearch/data\n      - nextcloud_elastic_backup:/usr/share/elasticsearch/backup\n      - nextcloud_elastic_logs:/usr/share/elasticsearch/logs\n    environment:\n      - \"discovery.type=single-node\"\n      - \"xpack.security.enabled=false\"\n      - \"ES_JAVA_OPTS=-Xms2048m -Xmx2048m\"\n```\n\n##### custom build\nthis points to a Dockerfile in subdirectory [elastic](docker-compose-files/nextcloud/nc)\n```\n    build:\n      context: elastic\n    image: custom-elasticsearch:8.10.2\n```\n\n##### elastic setup\n```\n    environment:\n      - \"discovery.type=single-node\"\n      - \"xpack.security.enabled=false\"\n      - \"ES_JAVA_OPTS=-Xms2048m -Xmx2048m\"\n```\nWe only need elastic on one node: `- \"discovery.type=single-node\"`. Since elastic version 8, authentication and other security featues are enabled per default, which complicates the setup. In my case, elastic runs inside an internal docker network (automatically created by docker-compose) so I can disable authentication to make the setup easier. The line `- \"ES_JAVA_OPTS=-Xms2048m -Xmx2048m\"` sets the max memory of elastic to 2 GiB\n\nTODO: explain the files in detail\n\nTODO: cron, thumbnailing,\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthomassteinreiter%2Fnextcloud-setup-docs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthomassteinreiter%2Fnextcloud-setup-docs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthomassteinreiter%2Fnextcloud-setup-docs/lists"}