this post was submitted on 23 Jun 2026
40 points (93.5% liked)

Selfhosted

60074 readers
635 users here now

A place to share alternatives to popular online services that can be self-hosted without giving up privacy or locking you into a service you don't control.

Rules:

  1. Be civil: we're here to support and learn from one another. Insults won't be tolerated. Flame wars are frowned upon.

  2. No spam.

  3. Posts here are to be centered around self-hosting. Please ensure it is clear in your post how it relates to self-hosting.

  4. Don't duplicate the full text of your blog or git here. Just post the link for folks to click.

  5. Submission headline should match the article title.

  6. No trolling.

Resources:

Any issues on the community? Report it using the report flag.

Questions? DM the mods!

founded 3 years ago
MODERATORS
 

I've tried NextCloud before and didn't really love it and I'm now happy with a combination of syncthing and LibreOffice. But my wife wants the full google drive, with sheets, docs etc. without the google, and I think NextCloud is my best option for that.

I'm and experienced *nix admin and already have a Linux server running with both VMs and docker containers and also have a working OpenVPN setup for remote access. But I found the NextCloud setup frustrating. We had a discussion about it (here I think) and determined that this was because NextCloud would rather sell their hosted service, so they don't go out of their way to make the self hosted option easy. I get that and don't hold it against them at all.

But, now that I'm wanting to try it again, I'm looking for pointers to guides for setting up self hosted NextCloud. I've searched, but nothing I found seemed like "the one".

you are viewing a single comment's thread
view the rest of the comments
[–] rtxn@lemmy.world 5 points 6 hours ago* (last edited 6 hours ago)

I use Docker Compose to run my Nextcloud server using the community image, which in turn lives inside an unprivileged LXC container.

compose.yaml

volumes:
  db:

services:
  db:
    image: mariadb:lts
    container_name: mariadb
    restart: always
    command: --transaction-isolation=READ-COMMITTED --log-bin=binlog --binlog-format=ROW
    volumes:
      - db:/var/lib/mysql
    secrets:
      - mysql_root_password
      - mysql_nextcloud_password
    environment:
      - MYSQL_ROOT_PASSWORD_FILE=/run/secrets/mysql_root_password
      - MYSQL_PASSWORD_FILE=/run/secrets/mysql_nextcloud_password
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud

  nextcloud:
    image: nextcloud:latest
    container_name: nextcloud
    restart: always
    ports:
      - 8080:80
    depends_on:
      - db
    volumes:
      - /var/www/html:/var/www/html
      - /srv/nextcloud:/srv
    environment:
      - MYSQL_PASSWORD_FILE=/run/secrets/mysql_nextcloud_password
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud
      - MYSQL_HOST=db

secrets:
  mysql_root_password:
    file: ./secrets/mysql_root_password.txt
  mysql_nextcloud_password:
    file: ./secrets/mysql_nextcloud_password.txt

Nextcloud's file storage is a mount point at /srv/nextcloud, which is backed by a ZRAID pool. The secrets are stored in files with 600 permissions. The web server is initially exposed on port 8080.

When you run the container for the first time, it will show a first time setup dialog. You'll have to fill it out manually, using mariadb for the database type and db for the database hostname.

If Nextcloud works through HTTP, you can then set up a proxy for HTTPS. I used Nginx running on the same LXC. I can't guarantee that my config is adequately secure, use it at your own risk.

10-nextcloud.conf

upstream php-handler {
	server 127.0.0.1:9000;
}

server {
	listen 80;
	listen [::]:80;
	server_name nextcloud.your.domain;
	return 301 https://$host$request_uri;
}

server {
	listen 443 ssl http2;
	listen [::]:443 ssl http2;
	server_name nextcloud.your.domain;
	keepalive_timeout 70;
	client_max_body_size 32G;

	ssl_certificate /etc/nginx/ssl/ssl.crt;
	ssl_certificate_key /etc/nginx/ssl/ssl.key;
	ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
	ssl_ciphers HIGH:!aNULL:!MD5;

	add_header Referrer-Policy "no-referrer" always;
	add_header X-Content-Type-Options "nosniff" always;
	add_header X-Download-Options "noopen" always;
	add_header X-Frame-Options "SAMEORIGIN" always;
	add_header X-Permitted-Cross-Domain-Policies "none" always;
	add_header X-Robots-Tag "none" always;
	add_header X-XSS-Protection "1; mode=block" always;

	fastcgi_hide_header X-Powered-By;

	location / {
		proxy_pass http://127.0.0.1:8080/;
	}
}

To allow the web app to work using the DNS name, you'll have to edit /var/www/html/config/config.php and change/add these values:

config.php (partial)

'trusted_domains' => array(
    0 => '127.0.0.1:8080',
    1 => 'nextcloud.your.domain',
    // 2 => whatever other addresses you want to use
),
'overwrite.cli.url' => 'https://nextcloud.your.domain/',
'overwriteprotocol' => 'https',
'overwritehost' => 'nextcloud.ng.local'

If at any point you need to start over, remember to delete the contents of /var/www/html.

(edit) Forgot to mention: the web server will accept connections from all addresses, you'll need to set up a strict firewall to only allow 443 (maybe 80) and 22.