Technology Encyclopedia Home >How to Install Nextcloud on a VPS — Your Own Private Cloud Storage

How to Install Nextcloud on a VPS — Your Own Private Cloud Storage

I used cloud storage for everything — files, photos, calendars, contacts. It was convenient until I started thinking about where all that data actually lives and who can access it.

Nextcloud gives you the same functionality — synced files, photo library, calendar, contacts — with your data staying on your own server. The Android and iOS sync apps work seamlessly in the background, the web interface is polished, and you can share files with others just like you would with any cloud storage service.

Good news for Lighthouse users: You don't need to go through a full Docker Compose setup. Lighthouse has a pre-built Nextcloud application image — select it at instance creation and Nextcloud is fully installed and ready to configure in under 10 minutes. This guide covers both the image path (fastest) and the manual Docker Compose path (for those who want custom configuration).

I run Nextcloud on Tencent Cloud Lighthouse. The Nextcloud application image is the easiest way to get started — everything is pre-installed when the server provisions, and you go straight to the web setup wizard. For personal cloud storage, Lighthouse's CBS cloud disk expansion is the key feature: when your storage needs grow, you can attach additional volumes (up to 32 TB) without migrating the server or reconfiguring Nextcloud. The high bandwidth packages handle file syncs and uploads without unexpected overage charges.


Table of Contents

  1. What Nextcloud Replaces
  2. Prerequisites
  3. Part 1 — Server Setup
  4. Part 2 — Deploy Nextcloud with Docker Compose
  5. Part 3 — Configure Nginx Reverse Proxy
  6. Part 4 — Enable HTTPS
  7. Part 5 — Complete Nextcloud Setup
  8. Part 6 — Performance Tuning
  9. Part 7 — Connect Desktop and Mobile Clients
  10. Part 8 — Install Apps
  11. Part 9 — Backups
  12. The Gotcha: Trusted Domains Error
  13. Maintenance Commands

  • Key Takeaways
  • Use the appropriate Lighthouse application image to skip manual installation steps where available
  • Lighthouse snapshots provide one-click full-server backup before major changes
  • OrcaTerm browser terminal lets you manage the server from any device
  • CBS cloud disk expansion handles growing storage needs without server migration
  • Console-level firewall + UFW = two independent protection layers

What Nextcloud Replaces {#what-replaces}

Nextcloud app Replaces
Files Google Drive, Dropbox
Photos Google Photos
Calendar Google Calendar
Contacts Google Contacts
Talk Slack (basic), Zoom (video)
Notes Google Keep
Office (Collabora) Google Docs
Mail Gmail web interface

You get all of these on your own server, with your own data.


Prerequisites {#prerequisites}

Requirement Notes
Cloud server Tencent Cloud Lighthouse Ubuntu 22.04
4 GB+ RAM Nextcloud with Redis and MySQL needs headroom
Storage 100 GB SSD minimum; add a data disk for large file storage
Domain name Required for HTTPS and mobile client setup

Part 1 — Server Setup {#part-1}

Option A — Nextcloud Application Image (Recommended, Fastest)

  1. Go to Lighthouse → New Instance
  2. Click Application Images → select Nextcloud
  3. Choose a plan (4 GB RAM recommended for personal use) and region
  4. Click Create

The server provisions in under 2 minutes. When it's ready:

  • Open the Lighthouse console and click Application Management on your instance
  • You'll see the Nextcloud admin URL, initial admin credentials, and database information
  • Navigate to the URL in your browser and complete the setup wizard (set admin password, create first user)

That's it for basic setup. Skip to Part 3 — Configure HTTPS and Domain for the next required step. Parts 1 and 2 (Docker setup) are only needed if you chose Option B.


Option B — Manual Docker Compose Setup (For Custom Configurations)

Use this path if you need a custom Nextcloud version, specific plugins pre-installed, or want to integrate with an existing Docker stack.

💡 Shorter path: Select Application Image → Docker CE instead of Ubuntu to skip the Docker install commands below.

ssh ubuntu@YOUR_SERVER_IP
sudo apt update && sudo apt upgrade -y

# Install Docker (skip if you chose the Docker CE application image)
curl -fsSL https://get.docker.com | sudo sh
sudo usermod -aG docker $USER
newgrp docker

sudo apt install -y nginx
sudo ufw allow ssh
sudo ufw allow 'Nginx Full'
sudo ufw enable

Part 2 — Deploy Nextcloud with Docker Compose {#part-2}

mkdir -p ~/apps/nextcloud && cd ~/apps/nextcloud

Create docker-compose.yml:

version: '3.8'

services:
  nextcloud-db:
    image: mariadb:10.11
    container_name: nextcloud-db
    restart: unless-stopped
    command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW
    volumes:
      - nextcloud_db:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_DATABASE: nextcloud
      MYSQL_USER: nextcloud
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}

  nextcloud-redis:
    image: redis:7-alpine
    container_name: nextcloud-redis
    restart: unless-stopped

  nextcloud:
    image: nextcloud:28-apache
    container_name: nextcloud
    restart: unless-stopped
    ports:
      - "8080:80"
    volumes:
      - nextcloud_data:/var/www/html
      - ${DATA_PATH:-./data}:/var/www/html/data
    environment:
      MYSQL_HOST: nextcloud-db
      MYSQL_DATABASE: nextcloud
      MYSQL_USER: nextcloud
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}
      NEXTCLOUD_ADMIN_USER: ${ADMIN_USER}
      NEXTCLOUD_ADMIN_PASSWORD: ${ADMIN_PASSWORD}
      NEXTCLOUD_TRUSTED_DOMAINS: ${NEXTCLOUD_TRUSTED_DOMAINS}
      REDIS_HOST: nextcloud-redis
      PHP_MEMORY_LIMIT: 512M
      PHP_UPLOAD_LIMIT: 10G
    depends_on:
      - nextcloud-db
      - nextcloud-redis

volumes:
  nextcloud_db:
  nextcloud_data:

Create .env:

nano .env
MYSQL_ROOT_PASSWORD=generate_strong_root_password
MYSQL_PASSWORD=generate_strong_nextcloud_password
ADMIN_USER=admin
ADMIN_PASSWORD=your_strong_admin_password

# Space-separated list of allowed domains
NEXTCLOUD_TRUSTED_DOMAINS=yourdomain.com cloud.yourdomain.com

# Local path for user data (point to a data disk if available)
DATA_PATH=./data
chmod 600 .env

mkdir -p ./data

# Start Nextcloud
docker compose up -d

# Watch startup (takes 1-2 minutes on first run)
docker compose logs -f nextcloud
# Wait for: Nextcloud is ready.

Part 3 — Configure Nginx Reverse Proxy {#part-3}

sudo nano /etc/nginx/sites-available/nextcloud
upstream nextcloud_backend {
    server 127.0.0.1:8080;
    keepalive 32;
}

server {
    listen 80;
    server_name cloud.yourdomain.com;

    # Allow large file uploads
    client_max_body_size 10G;
    client_body_timeout 120s;

    # Required for Nextcloud
    add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;
    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 "noindex, nofollow" always;
    add_header X-XSS-Protection "1; mode=block" always;

    location = /robots.txt {
        allow all;
        log_not_found off;
        access_log off;
    }

    location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/) {
        return 404;
    }

    location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) {
        return 404;
    }

    location / {
        proxy_pass http://nextcloud_backend;
        proxy_http_version 1.1;

        proxy_set_header Host              $host;
        proxy_set_header X-Real-IP         $remote_addr;
        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        proxy_connect_timeout  3600s;
        proxy_send_timeout     3600s;
        proxy_read_timeout     3600s;

        proxy_buffering off;
        proxy_request_buffering off;
    }
}
sudo ln -s /etc/nginx/sites-available/nextcloud /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx

Part 4 — Enable HTTPS {#part-4}

sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d cloud.yourdomain.com

Part 5 — Complete Nextcloud Setup {#part-5}

Visit https://cloud.yourdomain.com — if you set the admin credentials in .env, you'll go directly to the dashboard. If not, the setup wizard appears.

Recommended first steps:

  1. Install recommended apps when prompted
  2. Settings → Overview — fix any warnings
  3. Settings → Background jobs → change to Cron (more reliable)

Set up the cron job:

# Add to crontab
(crontab -l; echo "*/5 * * * * docker exec --user www-data nextcloud php -f /var/www/html/cron.php") | crontab -

Part 6 — Performance Tuning {#part-6}

Enable Redis caching (already configured in docker-compose.yml)

Verify Redis is being used:

docker exec --user www-data nextcloud php occ config:system:get memcache.distributed
# Should return: \OC\Memcache\Redis

Enable APCu for local caching

docker exec --user www-data nextcloud php occ config:system:set memcache.local --value='\OC\Memcache\APCu'

Increase PHP memory limit

Already set to 512 MB in docker-compose.yml. For heavy usage, increase to 1G in the environment section.

Check Nextcloud's built-in performance recommendations

docker exec --user www-data nextcloud php occ check
docker exec --user www-data nextcloud php occ status

Part 7 — Connect Desktop and Mobile Clients {#part-7}

Desktop (Windows, macOS, Linux)

Download the Nextcloud desktop client from nextcloud.com/install.

  1. Click Log in (not the + button)
  2. Enter your server URL: https://cloud.yourdomain.com
  3. Authorize in your browser
  4. Choose which folders to sync

Mobile (iOS, Android)

Install the Nextcloud app from App Store / Google Play.

  1. Tap Log in
  2. Enter https://cloud.yourdomain.com
  3. Enter username and password

For iOS Photos auto-upload: open the app → three-line menu → Auto Upload → enable.


Part 8 — Install Apps {#part-8}

Nextcloud has an app store with hundreds of extensions. Notable ones:

App What it adds
Calendar CalDAV calendar sync
Contacts CardDAV contacts sync
Notes Markdown note-taking
Talk Video calls and group chat
Collabora Online Real-time document editing (Office-compatible)
Nextcloud Office Built-in document editing (simpler than Collabora)
Maps Photo maps based on GPS metadata
Memories Google Photos-style photo viewer

Install from: Nextcloud admin → Apps → browse and enable.


Part 9 — Backups {#part-9}

nano ~/backup_nextcloud.sh
#!/bin/bash
BACKUP_DIR=~/backups/nextcloud
DATE=$(date +%Y%m%d_%H%M%S)
mkdir -p $BACKUP_DIR

source ~/apps/nextcloud/.env

# Enable maintenance mode during backup
docker exec --user www-data nextcloud php occ maintenance:mode --on

# Backup database
docker exec nextcloud-db mysqldump -u nextcloud -p"$MYSQL_PASSWORD" nextcloud | \
  gzip > $BACKUP_DIR/nextcloud_db_$DATE.sql.gz

# Backup Nextcloud config
docker cp nextcloud:/var/www/html/config $BACKUP_DIR/config_$DATE

# Backup user data (can be large — adjust path as needed)
# tar czf $BACKUP_DIR/data_$DATE.tar.gz ~/apps/nextcloud/data/

# Disable maintenance mode
docker exec --user www-data nextcloud php occ maintenance:mode --off

# Keep 7 days
find $BACKUP_DIR -mtime +7 -delete

echo "Nextcloud backup complete: $DATE"
chmod +x ~/backup_nextcloud.sh
(crontab -l; echo "0 2 * * * ~/backup_nextcloud.sh") | crontab -

The Gotcha: Trusted Domains Error {#gotcha}

After setup, you may see: "Access through untrusted domain"

This happens when you access Nextcloud via a domain that isn't in the trusted domains list.

Fix:

# Add your domain to trusted domains
docker exec --user www-data nextcloud php occ config:system:set trusted_domains 1 --value='cloud.yourdomain.com'
docker exec --user www-data nextcloud php occ config:system:set trusted_domains 2 --value='yourdomain.com'

Or edit the config directly:

docker exec -it nextcloud nano /var/www/html/config/config.php
# Add to 'trusted_domains' array

Maintenance Commands {#maintenance}

# Enable/disable maintenance mode
docker exec --user www-data nextcloud php occ maintenance:mode --on
docker exec --user www-data nextcloud php occ maintenance:mode --off

# Run database maintenance
docker exec --user www-data nextcloud php occ db:add-missing-indices
docker exec --user www-data nextcloud php occ db:convert-filecache-bigint

# Check system status
docker exec --user www-data nextcloud php occ status
docker exec --user www-data nextcloud php occ check

# Rescan user files (after manual upload)
docker exec --user www-data nextcloud php occ files:scan --all

# Update Nextcloud
docker compose pull nextcloud
docker compose up -d --remove-orphans
docker exec --user www-data nextcloud php occ upgrade

Troubleshooting {#troubleshooting}

Issue Likely Cause Fix
Connection refused Service not running or wrong port Check systemctl status SERVICE and verify firewall rules
Permission denied Wrong file ownership or permissions Check file ownership with ls -la and use chown/chmod to fix
502 Bad Gateway Backend service not running Restart the backend service; check logs with journalctl -u SERVICE
SSL certificate error Certificate expired or domain mismatch Run sudo certbot renew and verify domain DNS points to server IP
Service not starting Config error or missing dependency Check logs with journalctl -u SERVICE -n 50 for specific error
Out of disk space Logs or data accumulation Run df -h to identify usage; clean logs or attach CBS storage
High memory usage Too many processes or memory leak Check with htop; consider upgrading instance plan if consistently high
Firewall blocking traffic Port not open in UFW or Lighthouse console Open port in Lighthouse console firewall AND sudo ufw allow PORT

Frequently Asked Questions {#faq}

How much disk space do I need for Nextcloud?
Start with the base system disk (40–80 GB). For media-heavy uses, attach a CBS cloud disk — Lighthouse supports expansion up to 32 TB. Add storage as your collection grows without re-provisioning the server.

How do I migrate Nextcloud data to a larger disk?
On Lighthouse, you can attach an additional CBS disk and move data to it. For the OS disk itself, take a snapshot and restore to a larger instance. The guide covers storage expansion options.

Is data on a cloud VPS truly private?
Data on your Lighthouse instance is stored in Tencent Cloud's infrastructure. For maximum privacy, enable encryption at the application layer. Lighthouse provides data center compliance but you're ultimately trusting the cloud provider's infrastructure security.

How do I handle backups for large media collections?
For Nextcloud specifically: use Lighthouse snapshots for full system recovery plus application-level exports for granular recovery. For very large collections, consider versioned backups and retention policies.

What happens to my data if I stop paying for the server?
Cloud servers are terminated after a grace period if payment lapses. Always maintain your billing and export critical data regularly to an independent location (external storage, another cloud provider).

Set up your private cloud today:
👉 Tencent Cloud Lighthouse — VPS for self-hosted applications
👉 View current pricing and promotions
👉 Explore all active deals and offers