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.
- Key Takeaways
| 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 |
| Gmail web interface |
You get all of these on your own server, with your own data.
| 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 |
The server provisions in under 2 minutes. When it's ready:
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.
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
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.
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
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d cloud.yourdomain.com
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:
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 -
Verify Redis is being used:
docker exec --user www-data nextcloud php occ config:system:get memcache.distributed
# Should return: \OC\Memcache\Redis
docker exec --user www-data nextcloud php occ config:system:set memcache.local --value='\OC\Memcache\APCu'
Already set to 512 MB in docker-compose.yml. For heavy usage, increase to 1G in the environment section.
docker exec --user www-data nextcloud php occ check
docker exec --user www-data nextcloud php occ status
Download the Nextcloud desktop client from nextcloud.com/install.
https://cloud.yourdomain.comInstall the Nextcloud app from App Store / Google Play.
https://cloud.yourdomain.comFor iOS Photos auto-upload: open the app → three-line menu → Auto Upload → enable.
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.
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 -
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
# 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
| 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 |
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.
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