ownCloud is a self-hosted file sync and share platform. This cheatsheet covers daily operations, configuration, and maintenance.
Installation
Docker Compose (Recommended)
services:
owncloud:
image: owncloud/server:latest
restart: unless-stopped
ports:
- "8080:8080"
environment:
OWNCLOUD_ADMIN_USERNAME: admin
OWNCLOUD_ADMIN_PASSWORD: adminpass
OWNCLOUD_DB_TYPE: mysql
OWNCLOUD_DB_NAME: owncloud
OWNCLOUD_DB_USERNAME: owncloud
OWNCLOUD_DB_PASSWORD: dbpass
OWNCLOUD_DB_HOST: db
OWNCLOUD_REDIS_ENABLED: "true"
OWNCLOUD_REDIS_HOST: redis
OWNCLOUD_TRUSTED_DOMAINS: "localhost 192.168.1.100 cloud.example.com"
OWNCLOUD_OVERWRITE_CLI_URL: "https://cloud.example.com"
OWNCLOUD_OVERWRITEPROTOCOL: "https"
volumes:
- owncloud_data:/mnt/data
depends_on:
- db
- redis
db:
image: mariadb:10.11
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: rootpass
MYSQL_DATABASE: owncloud
MYSQL_USER: owncloud
MYSQL_PASSWORD: dbpass
volumes:
- db_data:/var/lib/mysql
redis:
image: redis:7-alpine
restart: unless-stopped
volumes:
owncloud_data:
db_data:docker compose up -d # Start stack
docker compose logs -f owncloud # Watch logs
docker compose exec owncloud occ status # Check statusManual (LAMP Stack)
# Prerequisites: Apache, PHP 8.1+, MariaDB/MySQL
# Download
wget https://download.owncloud.com/server/owncloud-10.15.0.tar.bz2
tar -xjf owncloud-10.15.0.tar.bz2 -C /var/www/
chown -R www-data:www-data /var/www/owncloud
# Apache vhost
cat > /etc/apache2/sites-available/owncloud.conf << 'EOF'
Alias /owncloud "/var/www/owncloud/"
<Directory /var/www/owncloud/>
Options +FollowSymlinks
AllowOverride All
Require all granted
SetEnv HOME /var/www/owncloud
SetEnv HTTP_HOME /var/www/owncloud
</Directory>
EOF
a2ensite owncloud && systemctl reload apache2
# Database
mysql -u root -p -e "CREATE DATABASE owncloud; \
GRANT ALL ON owncloud.* TO 'owncloud'@'localhost' IDENTIFIED BY 'dbpass';"occ CLI
All
occcommands must run as the web server user. In Docker:docker compose exec owncloud occ .... On bare metal:sudo -u www-data php occ ....
Core Commands
occ status # Show version & install status
occ list # List all available commands
occ check # Check environment & dependencies
occ config:system:get version # Get config value
occ config:system:set trusted_domains 1 --value="cloud.example.com"
occ config:system:set maintenance --value=false # Toggle maintenance mode
occ maintenance:mode --on # Enable maintenance mode
occ maintenance:mode --off # Disable maintenance modeUpgrade & Update
occ upgrade # Run upgrade after version bump
occ maintenance:repair # Repair database inconsistencies
occ db:add-missing-indices # Add missing DB indices
occ db:add-missing-columns # Add missing DB columns
occ db:add-missing-primary-keys # Add missing PKs
occ db:convert-type --all mysql # Convert DB storage type
occ migrations:execute <app> <version> # Run specific migrationUser Management
occ user:add --display-name="John Doe" \
--email="[email protected]" \
--password-from-env john # Add user (set OC_PASS env first)
occ user:delete john # Delete user
occ user:list # List all users
occ user:info john # Show user details
occ user:setting john read config # Get user setting
occ user:setting john core language en # Set user language
occ user:setting john files quota "10G" # Set quota
occ user:resetpassword john # Reset password
occ user:report # User statistics reportGroups
occ group:add staff # Create group
occ group:delete staff # Delete group
occ group:list # List all groups
occ group:list-members staff # List members of group
occ group:add-user john staff # Add user to group
occ group:remove-user john staff # Remove user from groupFile Operations
occ files:scan --all # Scan all files for all users
occ files:scan john # Scan files for specific user
occ files:scan --path="/john/files/Photos" # Scan specific path
occ files:scan-app-data # Scan app data directory
occ files:cleanup # Clean up file cache
occ files:transfer-ownership john jane # Transfer all files from john to jane
occ trashbin:cleanup john # Empty trash for user
occ trashbin:cleanup --all # Empty trash for all users
occ versions:cleanup john # Clean versions for user
occ versions:cleanup --all # Clean versions for all users
occ files_external:list # List external storage mounts
occ files_external:verify # Verify external storage configApps Management
occ app:list # List installed apps
occ app:install calendar # Install app from marketplace
occ app:enable calendar # Enable app
occ app:disable calendar # Disable app
occ app:uninstall calendar # Uninstall app
occ app:update --all # Update all apps
occ app:check # Check app compatibility
occ market:install <app-id> # Install from marketplace
occ market:upgrade <app-id> # Upgrade from marketplaceConfiguration (config.php)
Important Settings
<?php
$CONFIG = [
'trusted_domains' => ['cloud.example.com', '192.168.1.100'],
'overwrite.cli.url' => 'https://cloud.example.com',
'overwriteprotocol' => 'https',
'htaccess.RewriteBase' => '/',
'dbtype' => 'mysql',
'dbname' => 'owncloud',
'dbhost' => 'localhost',
'dbuser' => 'owncloud',
'dbpassword' => 'dbpass',
'dbtableprefix' => 'oc_',
'mail_domain' => 'example.com',
'mail_from_address' => 'noreply',
'mail_smtpmode' => 'smtp',
'mail_smtphost' => 'smtp.example.com',
'mail_smtpport' => '587',
'mail_smtpsecure' => 'tls',
'mail_smtpauth' => true,
'mail_smtpname' => 'user',
'mail_smtppassword' => 'pass',
'redis' => [
'host' => 'localhost',
'port' => 6379,
],
'memcache.local' => '\OC\Memcache\APCu',
'memcache.distributed' => '\OC\Memcache\Redis',
'memcache.locking' => '\OC\Memcache\Redis',
'filelocking.enabled' => true,
'debug' => false,
'log_type' => 'owncloud',
'logfile' => '/var/log/owncloud.log',
'loglevel' => 2, // 0=DEBUG, 1=INFO, 2=WARN, 3=ERROR
'log_rotate_size' => 104857600, // 100MB
'maintenance' => false,
];Managing Config via occ
occ config:system:set trusted_domains 1 --value="cloud.example.com"
occ config:system:set overwrite.cli.url --value="https://cloud.example.com"
occ config:system:get trusted_domains
occ config:system:delete debug
occ config:app:set core import_max_size --value="524288000"
occ config:app:get core import_max_sizeS3 / R2 as Primary Storage
occ config:system:set objectstore enabled --value=true
occ config:system:set objectstore class --value="\OC\Files\ObjectStore\S3"
occ config:system:set objectstore arguments bucket --value="owncloud-data"
occ config:system:set objectstore arguments key --value="ACCESS_KEY"
occ config:system:set objectstore arguments secret --value="SECRET_KEY"
occ config:system:set objectstore arguments hostname --value="r2.cloudflarestorage.com"
occ config:system:set objectstore arguments region --value="auto"
occ config:system:set objectstore arguments use_path_style --value=trueExternal Storage (Secondary)
# Enable External Storage app
occ app:enable files_external
# Add S3 external storage
occ files_external:create \
--config '{"bucket":"backup","key":"AK","secret":"SK","hostname":"s3.amazonaws.com","region":"us-east-1"}' \
"S3 Backup" \
amazons3 \
null::null
# List external storages
occ files_external:list
# Verify configuration
occ files_external:verify 1Performance Tuning
Redis Caching
# config.php
occ config:system:set redis host --value="localhost"
occ config:system:set redis port --value=6379 --type=integer
occ config:system:set memcache.local --value="\OC\Memcache\APCu"
occ config:system:set memcache.distributed --value="\OC\Memcache\Redis"
occ config:system:set memcache.locking --value="\OC\Memcache\Redis"
occ config:system:set filelocking.enabled --value=true --type=booleanPHP-FPM Tuning
; /etc/php/8.1/fpm/pool.d/www.conf
pm = dynamic
pm.max_children = 120
pm.start_servers = 12
pm.min_spare_servers = 6
pm.max_spare_servers = 18
pm.max_requests = 500
; php.ini
memory_limit = 512M
upload_max_filesize = 16G
post_max_size = 16G
max_execution_time = 3600
opcache.enable = 1
opcache.memory_consumption = 256
opcache.max_accelerated_files = 20000
apc.enable_cli = 1Background Jobs
# Switch to cron (recommended)
occ config:system:set mode --value="cron" --type=string
# Add cron job (run every 15 min)
echo "*/15 * * * * sudo -u www-data php /var/www/owncloud/occ system:cron" | sudo tee /etc/cron.d/owncloud
# In Docker, use the built-in cron
docker compose exec owncloud occ system:cronSecurity
.htaccess & Headers
occ maintenance:update:htaccess # Regenerate .htaccess
# Ensure AllowOverride All in Apache vhostBrute Force Protection
occ config:system:set auth.bruteforce.protection.enabled --value=true --type=boolean
occ config:system:set auth.bruteforce.protection.max_attempts --value=50 --type=integer
occ config:system:set auth.bruteforce.protection.time_window --value=300 --type=integerTwo-Factor Authentication
occ app:enable twofactor_totp # Enable TOTP 2FA
occ twofactor:enforce john # Enforce 2FA for user
occ twofactor:disable john # Disable 2FA for user
occ twofactor:state john # Check 2FA statefail2ban Integration
# /etc/fail2ban/filter.d/owncloud.conf
[Definition]
failregex = ^.*"remoteAddr":"<HOST>".*"app":"core".*"message":"Login failed:.*".*$
^.*"remoteAddr":"<HOST>".*"app":"core".*"message":"Brute-force attempt".*$
ignoreregex =# /etc/fail2ban/jail.d/owncloud.conf
[owncloud]
enabled = true
filter = owncloud
logpath = /var/www/owncloud/data/owncloud.log
maxretry = 5
bantime = 900
findtime = 300Backup & Restore
Full Backup Procedure
# 1. Enable maintenance mode
occ maintenance:mode --on
# 2. Backup database
mysqldump -u root -p owncloud > owncloud_db_$(date +%F).sql
# 3. Backup data directory
tar -czf owncloud_data_$(date +%F).tar.gz /var/www/owncloud/data/
# 4. Backup config
tar -czf owncloud_config_$(date +%F).tar.gz /var/www/owncloud/config/
# 5. Disable maintenance mode
occ maintenance:mode --offDocker Backup
# Database
docker compose exec db mysqldump -u root -prootpass owncloud > backup.sql
# Data volume
docker run --rm -v $(pwd)/owncloud_data:/backup \
-v project_owncloud_data:/data alpine \
tar -czf /backup/data.tar.gz -C /data .
# Restore
docker compose exec db mysql -u root -prootpass owncloud < backup.sql
docker run --rm -v $(pwd)/owncloud_data:/backup \
-v project_owncloud_data:/data alpine \
tar -xzf /backup/data.tar.gz -C /dataRestore Procedure
# 1. Enable maintenance mode
occ maintenance:mode --on
# 2. Restore database
mysql -u root -p owncloud < owncloud_db_2024-01-01.sql
# 3. Restore data
tar -xzf owncloud_data_2024-01-01.tar.gz -C /var/www/owncloud/
# 4. Restore config
tar -xzf owncloud_config_2024-01-01.tar.gz -C /var/www/owncloud/
# 5. Run repair
occ maintenance:repair
# 6. Disable maintenance mode
occ maintenance:mode --offUpgrade Procedure
Docker Upgrade
# 1. Backup (see backup section above)
# 2. Enable maintenance mode
docker compose exec owncloud occ maintenance:mode --on
# 3. Pull new image
docker compose pull owncloud
# 4. Restart with new image
docker compose up -d owncloud
# 5. Run upgrade
docker compose exec owncloud occ upgrade
# 6. Run repair
docker compose exec owncloud occ maintenance:repair
# 7. Disable maintenance mode
docker compose exec owncloud occ maintenance:mode --off
# 8. Verify
docker compose exec owncloud occ statusManual Upgrade
# 1. Backup everything
# 2. Enable maintenance mode
sudo -u www-data php occ maintenance:mode --on
# 3. Download new version
wget https://download.owncloud.com/server/owncloud-10.15.0.tar.bz2
# 4. Extract over existing (keep data/ and config/)
tar -xjf owncloud-10.15.0.tar.bz2 -C /var/www/
# 5. Run upgrade
sudo -u www-data php occ upgrade
# 6. Run repair
sudo -u www-data php occ maintenance:repair
# 7. Disable maintenance mode
sudo -u www-data php occ maintenance:mode --off
# 8. Verify
sudo -u www-data php occ statusTroubleshooting
Check System
occ status # Version & install status
occ check # Environment check
occ configcheck # Validate config.php
occ integrity:check # Verify file integrity
occ system:report # Full system reportLogs
# View log file
occ log:tail # Tail log (Docker)
tail -f /var/www/owncloud/data/owncloud.log # Bare metal
# Change log level
occ config:system:set loglevel --value=0 --type=integer # DEBUG
occ config:system:set loglevel --value=1 --type=integer # INFO
occ config:system:set loglevel --value=2 --type=integer # WARN (default)
occ config:system:set loglevel --value=3 --type=integer # ERROR
# Log to syslog
occ config:system:set log_type --value="syslog"Stuck in Maintenance Mode
# Force disable maintenance mode
occ config:system:set maintenance --value=false --type=boolean
# If occ fails, edit config.php directly
sed -i "s/'maintenance' => true/'maintenance' => false/" config/config.phpUpgrade Failed
# Check upgrade log
occ upgrade --verbose
# Skip specific migration
occ migrations:execute --dry-run <app>
# Reset upgrade state
occ config:system:set upgraded --value=true --type=boolean
occ maintenance:repair
# Last resort: re-run from scratch
occ upgrade --forceDatabase Issues
# Repair sequences
occ maintenance:repair
# Convert to InnoDB (if still on MyISAM)
occ db:convert-type --all mysql
# Add missing indices
occ db:add-missing-indices
occ db:add-missing-columns
occ db:add-missing-primary-keysFile Scan Issues
# Full rescan (slow)
occ files:scan --all --verbose
# Scan specific user with debug
occ files:scan john -v
# Clean file cache
occ files:cleanup
# Rebuild share cache
occ shares:migrateCommon Problems
# "Trusted domains" error
occ config:system:set trusted_domains 1 --value="cloud.example.com"
# Upload size too small
occ config:system:set max_upload_size --value=17179869184 --type=integer
# Also set in php.ini: upload_max_filesize, post_max_size
# Cron not running
occ system:cron # Manual trigger
occ config:system:set mode --value="cron" # Switch from AJAX to cron
# Redis connection refused
occ config:system:get redis # Verify config
docker compose restart redis # Restart RedisUseful API Endpoints
# Status (public)
curl https://cloud.example.com/status.php
# OCS API - list users (admin auth)
curl -u admin:password \
-H "OCS-APIREQUEST: true" \
https://cloud.example.com/ocs/v1.php/cloud/users
# WebDAV - list files
curl -u john:password \
-X PROPFIND \
-H "Depth: 1" \
https://cloud.example.com/remote.php/dav/files/john/
# Upload file via WebDAV
curl -u john:password \
-T localfile.txt \
https://cloud.example.com/remote.php/dav/files/john/localfile.txt
# Share file via API
curl -u admin:password \
-X POST \
-H "OCS-APIREQUEST: true" \
"https://cloud.example.com/ocs/v1.php/apps/files_sharing/api/v1/shares" \
-d "path=/Photos/test.jpg&shareType=3&permissions=1"