The Question We Hear Often
“We need file sharing for our team, but we’re not comfortable putting client documents on someone else’s cloud. What are our options?”
We hear this from Canadian businesses every week. Healthcare providers handling PHIPA-protected records. Law firms with privileged client files. Marketing agencies with proprietary campaign assets. They all need collaboration tools, but the mainstream options feel like a compliance gamble.
Dropbox stores your files in US data centres subject to the CLOUD Act. Google Drive scans documents for “security purposes.” OneDrive ties you into the Microsoft ecosystem. For many Canadian organizations, these are deal-breakers.
Enter Nextcloud — a self-hosted alternative that gives you Dropbox-like functionality on infrastructure you control. File sync, sharing, calendar, contacts, real-time document editing, and even video calls — all running on your own server.
Here is how to set up Nextcloud on a VPS the right way: Docker-based deployment, proper SSL, and production-ready configuration.
What You Will Need
Nextcloud is not lightweight. It is a full collaboration suite, and it needs resources to run smoothly. Here is what we recommend:
| Component | Minimum | Recommended |
|---|---|---|
| CPU | 2 cores | 4 cores |
| RAM | 2 GB | 4 GB |
| Storage | 50 GB | 100+ GB (scales with files) |
| OS | Ubuntu 22.04 LTS | Ubuntu 24.04 LTS |
For this setup, we recommend a Cloud VPS from Canadian Web Hosting. Our Vancouver and Toronto data centres keep your data in Canada, with SOC 2 Type II certification and 24/7 support if you need help along the way.
Step-by-Step Installation
1. Prepare Your Server
Start with a fresh Ubuntu server. SSH in and update everything:
sudo apt update && sudo apt upgrade -y
sudo apt install -y docker.io docker-compose-v2
Enable Docker to start on boot:
sudo systemctl enable --now docker
sudo usermod -aG docker $USER
Log out and back in so your group membership takes effect.
2. Create the Project Directory
Nextcloud needs persistent storage for files, database, and configuration. Create a dedicated structure:
mkdir -p ~/nextcloud/{db,html,data,redis}
cd ~/nextcloud
3. Create the Docker Compose File
Create docker-compose.yml with the following configuration. This sets up Nextcloud with MariaDB for the database and Redis for caching (essential for performance):
services:
db:
image: mariadb:10.11
restart: always
volumes:
- ./db:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: your-root-password-here
MYSQL_DATABASE: nextcloud
MYSQL_USER: nextcloud
MYSQL_PASSWORD: your-db-password-here
redis:
image: redis:alpine
restart: always
app:
image: nextcloud:latest
restart: always
volumes:
- ./html:/var/www/html
- ./data:/var/www/html/data
ports:
- "8080:80"
environment:
MYSQL_HOST: db
MYSQL_DATABASE: nextcloud
MYSQL_USER: nextcloud
MYSQL_PASSWORD: your-db-password-here
REDIS_HOST: redis
NEXTCLOUD_TRUSTED_DOMAINS: your-domain.com
depends_on:
- db
- redis
Important: Replace your-root-password-here, your-db-password-here, and your-domain.com with your actual values.
4. Launch Nextcloud
Start the containers:
docker compose up -d
Check that everything is running:
docker compose ps
You should see three containers: nextcloud-db-1, nextcloud-redis-1, and nextcloud-app-1, all showing “Up” status.
Initial Configuration
Create Your Admin Account
Open your browser and navigate to http://your-server-ip:8080. You will see the Nextcloud setup screen:
- Username: Create an admin username (not “admin” — too predictable)
- Password: Use a strong, unique password
- Database: Click “MySQL/MariaDB” and enter:
- Database user:
nextcloud - Database password: (the password you set in docker-compose.yml)
- Database name:
nextcloud - Database host:
db
- Database user:
Click “Install” and wait a few minutes while Nextcloud sets up the database and creates default folders.
Configure Redis Caching
Redis is already running, but Nextcloud needs to know to use it. Edit the configuration:
sudo nano ~/nextcloud/html/config/config.php
Add these lines inside the $CONFIG = array ( block, before the closing );:
'memcache.local' => '\OC\Memcache\Redis',
'memcache.distributed' => '\OC\Memcache\Redis',
'memcache.locking' => '\OC\Memcache\Redis',
'redis' => [
'host' => 'redis',
'port' => 6379,
],
Restart the app container to apply:
docker compose restart app
Verify Everything Works
Before moving to production, verify each component:
1. File Upload Test: Upload a test file through the web interface. Check it appears in ~/nextcloud/data/[username]/files/ on the server.
2. Sync Client Test: Download the Nextcloud desktop client, connect to your server, and verify sync works.
3. Redis Test: Check Redis is being used:
docker compose exec redis redis-cli ping
Should respond with PONG.
4. Database Test: Verify the database has tables:
docker compose exec db mariadb -u nextcloud -p -e "SHOW TABLES;" nextcloud
You should see 80+ tables listed.
Production Hardening
Running Nextcloud on port 8080 without encryption is fine for testing, but not for production. Here is how to secure it properly.
Set Up a Reverse Proxy with SSL
We recommend using Caddy for automatic HTTPS, or Nginx if you prefer manual configuration. Here is the Caddy approach:
Add a Caddy service to your docker-compose.yml:
caddy:
image: caddy:latest
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- caddy_data:/data
- caddy_config:/config
depends_on:
- app
volumes:
caddy_data:
caddy_config:
Create a Caddyfile in the same directory:
cloud.yourdomain.com {
reverse_proxy app:80
encode gzip
header Strict-Transport-Security "max-age=31536000;"
}
Restart everything:
docker compose up -d
Caddy will automatically obtain and renew a Let’s Encrypt SSL certificate for your domain.
Configure Firewall Rules
Only expose the ports you need:
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow ssh
sudo ufw allow http
sudo ufw allow https
sudo ufw enable
Set Up Backups
Nextcloud has three components to back up:
- Files: The
~/nextcloud/datadirectory - Database: Use
mysqldumpor MariaDB backup tools - Configuration: The
~/nextcloud/html/configdirectory
Create a simple backup script:
#!/bin/bash
DATE=$(date +%Y%m%d)
BACKUP_DIR="/backup/nextcloud"
mkdir -p $BACKUP_DIR
docker compose exec db mariadb-dump -u nextcloud -p'your-db-password' nextcloud > $BACKUP_DIR/db-$DATE.sql
tar -czf $BACKUP_DIR/files-$DATE.tar.gz ~/nextcloud/data
tar -czf $BACKUP_DIR/config-$DATE.tar.gz ~/nextcloud/html/config
# Keep only last 30 days
find $BACKUP_DIR -type f -mtime +30 -delete
Schedule it with cron: 0 2 * * * /home/user/backup-nextcloud.sh
For production deployments, consider CloudSafe Backup for offsite, encrypted backups with retention policies.
Enable Two-Factor Authentication
Nextcloud supports TOTP (Google Authenticator compatible). Install the Two-Factor TOTP app from the Nextcloud App Store and enable it for all admin accounts.
Troubleshooting Common Issues
“Internal Server Error” After Setup
Cause: Usually a database connection issue or permission problem.
Fix: Check the Nextcloud logs:
docker compose logs app | tail -50
Common fixes:
- Verify database credentials match between
docker-compose.ymland the Nextcloud config - Check file permissions:
sudo chown -R 33:33 ~/nextcloud/html(33 is www-data)
Upload Fails with “413 Request Entity Too Large”
Cause: Default upload limits are too low for large files.
Fix: Edit ~/nextcloud/html/.htaccess or add to config.php:
'upload_max_filesize' => '10G',
'post_max_size' => '10G',
Also increase PHP memory limit in the container:
docker compose exec app php -d memory_limit=512M occ maintenance:repair
Sync Client Shows “Connection Refused”
Cause: The server is not accessible, or the trusted domains list is incorrect.
Fix: Add your domain to trusted domains in config.php:
'trusted_domains' =>
array (
0 => 'localhost',
1 => 'your-server-ip',
2 => 'cloud.yourdomain.com',
),
Performance is Slow
Cause: Missing Redis caching, or insufficient resources.
Fix: Verify Redis is configured (see above). If Redis is working but still slow:
- Increase RAM allocation to the VPS
- Enable server-side encryption only if required (adds CPU overhead)
- Disable unused apps in Nextcloud settings
When to Upgrade or Seek Help
If your team grows beyond 50 users, or you need enterprise features like SSO integration, audit logging, or advanced sharing controls, consider:
- Upgrading to a Dedicated Server for more resources
- Exploring Nextcloud Enterprise for advanced features
- Contacting CWH Managed Support if you prefer not to manage it yourself
Conclusion
Self-hosting Nextcloud gives you control over your data without sacrificing collaboration features. You get file sync, sharing, calendars, and more — all on infrastructure you own and operate.
The key to a successful deployment is starting with adequate resources, configuring Redis caching from day one, and setting up proper backups before you store anything important.
If you run into issues or want help with the initial setup, contact Canadian Web Hosting. Our team has deployed Nextcloud for dozens of Canadian organizations and can help you get up and running quickly.
Related guides:
Be First to Comment