A comprehensive, self-hosted cloud storage platform with admin-managed user system, file upload/download capabilities, folder management, and a modern user interface.
- Admin-Managed Users - Streamlined user management without email verification requirements
- File Management - Complete file lifecycle management including upload, download, and deletion
- Folder Organization - Hierarchical folder structure for efficient file organization
- File Sharing - Share files securely via public links
- Storage Quotas - Configurable storage limits per user
- Modern Interface - Built with React and Tailwind CSS for a responsive, intuitive experience
- Mobile Apps - Native Android and iOS apps via Capacitor
- PWA Support - Progressive Web App for installable web experience
- Docker Support - Containerized deployment for easy setup and maintenance
- JWT Authentication - Secure token-based authentication system
- Quick Start for Local Network Use
- Quick Start for Online Use with Docker and HTTPS
- Manual Installation (without Docker)
- Mobile App Setup (Android/iOS)
- Usage Guide
- Configuration
- Production Deployment
- Project Structure
- Security Features
- Database
- Troubleshooting
- Technology Stack
- API Endpoints
- Using External Storage
- Support
- Contributing
For home networks with direct access without HTTPS or reverse proxy complexity.
See here for Production/Online use Configuration
- Docker and Docker Compose installed
- Network-connected device (Raspberry Pi, server, or desktop)
- Minimum 1GB available storage space
- Navigate to the project directory
cd mycloud- Create a local network configuration
cp .env.local.example .env
nano .env.env before proceeding!
Required changes:
JWT_SECRET- Set a strong, random secret key (minimum 32 characters)ADMIN_PASSWORD- Set a secure administrator password
Generate a secure JWT_SECRET:
openssl rand -base64 32- Build and launch
sudo docker compose -f docker-compose.local.yml up -d --buildNote: The
docker-compose.local.ymlconfiguration usesBASE_PATH=/which is correct for local/direct access. If you're deploying behind a reverse proxy to a subdirectory (e.g.,/cloud), use the standarddocker-compose.ymlwhich setsBASE_PATH=/cloud.
- Find your device's IP address
# On Linux/Mac
hostname -I | awk '{print $1}'
# Or
ip addr show | grep "inet " | grep -v 127.0.0.1- Access MyCloud from any device on your network
Open a browser and navigate to:
http://[YOUR-IP]:6868(e.g.,http://192.168.1.100:6868)- OR
http://[HOSTNAME].local:6868(e.g.,http://pi5.local:6868)
Default credentials:
- Username:
admin - Password:
admin123(or the value you set in.env)
For consistent access, configure a static IP on your device:
On Raspberry Pi/Ubuntu:
# Edit netplan configuration
sudo nano /etc/netplan/01-netcfg.yamlExample configuration:
network:
version: 2
ethernets:
eth0:
dhcp4: no
addresses:
- 192.168.1.100/24
gateway4: 192.168.1.1
nameservers:
addresses: [8.8.8.8, 1.1.1.1]Apply changes:
sudo netplan apply# View logs
docker compose -f docker-compose.local.yml logs -f
# Restart
docker compose -f docker-compose.local.yml restart
# Stop
docker compose -f docker-compose.local.yml down
# Update and rebuild
docker compose -f docker-compose.local.yml down
docker compose -f docker-compose.local.yml up -d --build- Ensure your mobile device is on the same WiFi network
- Open browser and navigate to
http://[YOUR-IP]:6868 - Add to home screen for quick access (works like a native app)
- Firewall: Ensure port 6868 is open if using a firewall
- Router DNS: Consider adding a DNS entry in your router for easier access
- Security: This setup uses HTTP (not HTTPS). Only use within trusted local networks
- Port Forwarding: Do NOT expose port 6868 to the internet without proper security measures
For the public or online use, or in production
- Docker and Docker Compose installed
- Letsencrypt or other certificate service installed
- Apache2 or Nginx installed
- Minimum 1GB available storage space
- Navigate to the project directory
cd mycloud- Configure environment variables
cp .env.example .env.env before proceeding!
Required changes:
JWT_SECRET- Set a strong, random secret key (minimum 32 characters)ADMIN_PASSWORD- Set a secure administrator password
Example of generating a secure JWT_SECRET:
openssl rand -base64 32
# Or use any random string generator- Configure Web Server / Reverse Proxy
- Apache Web Server is tested, Nginx should work too.
- Generate Certificates with Letsencrypt
- See the detailed Web Server Configuration section below for complete setup instructions.
- Build the frontend
cd client
npm install
npm run build
cd ..- Launch with Docker Compose
sudo docker compose up -dNote: The standard
docker-compose.ymlusesBASE_PATH=/cloudfor subdirectory deployment behind a reverse proxy. If you're deploying to the root of a domain (e.g.,https://mycloud.example.com), editdocker-compose.ymland changeBASE_PATH: /cloudtoBASE_PATH: /in both thebuild.argsandenvironmentsections.
- Access MyCloud
Open your browser and navigate to:
https://yourdomain.com/cloud
Default credentials:
- Username:
admin - Password:
admin123(or the value set in.env)
- Node.js 18 or higher
- npm or yarn
- Install dependencies
npm install- Configure environment
cp .env.example .env.env and change at minimum:
JWT_SECRET- Strong secret key (minimum 32 characters)ADMIN_PASSWORD- Secure password (NOT "admin123")
- Start the server
npm startThe server will be available at http://localhost:6868
- Navigate to client directory
cd client- Install dependencies
npm install- Start development server
npm run devThe frontend will be available at http://localhost:6869 with hot-reload enabled
The BASE_PATH determines where the application expects to be served from:
- Use
BASE_PATH=/for local/direct access (e.g.,http://localhost:6868orhttp://192.168.1.50:6868) - Use
BASE_PATH=/cloud(or other path) for subdirectory deployment behind a reverse proxy (e.g.,https://yourdomain.com/cloud)
For Local/Direct Access:
# Build frontend for local access
cd client
npm run build
# Start server in production mode
cd ..
NODE_ENV=production npm startFor Subdirectory Deployment (e.g., behind Apache/Nginx):
# Build frontend with custom base path
cd client
BASE_PATH=/cloud npm run build
# Start server in production mode
cd ..
NODE_ENV=production npm startAccess the application at http://localhost:6868 (or your server's IP/hostname).
- ✅ Native iOS and Android apps
- ✅ Installable from app stores or as APK/IPA
- ✅ Camera and file picker integration
- ✅ Splash screen and app icons
- ✅ Offline detection
- ✅ Configurable server URL
- ✅ Full feature parity with web version
-
Install dependencies:
cd client npm install -
Build the web app:
npm run build
-
Initialize Capacitor:
cd .. npx cap init -
Add platforms:
# For Android npx cap add android npm run sync npm run android # Opens Android Studio # For iOS (macOS only) npx cap add ios npm run sync npm run ios # Opens Xcode
Server configuration happens entirely within the app:
- On first launch, mobile apps automatically prompt for your server URL
- Tap the settings icon (⚙️) on the login screen to change server URL anytime
- Configuration is stored locally - no code changes or rebuilding required
For complete setup instructions, requirements, troubleshooting, and build configurations, see:
📱 MOBILE_SETUP.md - Comprehensive mobile app setup guide 🎨 ICON_GUIDE.md - App icon creation and customization guide
-
Login with admin credentials
-
Access Admin Panel via the settings icon in the header
-
Create Users:
- Click "Create User"
- Enter username, email, and password
- Set storage quota (in GB)
- Click "Create User"
-
Manage Users:
- View all users and their storage utilization
- Delete users as needed
-
Login with credentials provided by administrator
-
Upload Files:
- Drag and drop files into the upload zone
- Or click to select files manually
-
Create Folders:
- Click "New Folder"
- Enter folder name
-
Manage Files:
- Download: Click the download icon
- Share: Click the share icon (link copied to clipboard)
- Delete: Click the trash icon
-
Navigate:
- Click folders to open them
- Click the back arrow to navigate to parent folder
# Server Configuration
PORT=6868 # Server port
NODE_ENV=production # Environment: production or development
# Security
JWT_SECRET=your-secret-key # CRITICAL: Change this in production!
# Database
DB_PATH=./data/database.sqlite
# File Storage
UPLOAD_PATH=./data/uploads
MAX_FILE_SIZE=524288000 # 500MB in bytes
# Default Admin User
ADMIN_USERNAME=admin
ADMIN_PASSWORD=admin123 # CRITICAL: Change this in production!
ADMIN_EMAIL=admin@mycloud.localDefault quota per user: 10 GB
This can be customized when creating users in the Admin Panel.
- Transfer files to server
scp -r mycloud user@your-server.com:/home/user/- Connect to server
ssh user@your-server.com
cd mycloud- Configure environment (CRITICAL - DO NOT SKIP!)
nano .envJWT_SECRET- Use a strong random string (minimum 32 characters)ADMIN_PASSWORD- Use a secure password
Generate a secure JWT_SECRET:
openssl rand -base64 32- Start Docker containers
docker-compose up -d- Configure Reverse Proxy (Optional)
You can deploy MyCloud either at the root of a domain or in a subdirectory.
This configuration serves MyCloud at https://yourdomain.com/cloud
Enable required Apache modules:
sudo a2enmod proxy proxy_http rewrite headers ssl
sudo systemctl restart apache2Add to your Apache VirtualHost configuration:
<VirtualHost *:443>
ServerName yourdomain.com
# SSL Configuration
SLEngine on
SSLCertificateFile /etc/letsencrypt/live/yourdomain.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/yourdomain.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
# MyCloud Proxy Configuration
ProxyPreserveHost On
ProxyRequests Off
# Allow large file uploads (500MB)
LimitRequestBody 524288000
# Rewrite Engine for MyCloud
RewriteEngine On
# Forward all /cloud/* requests to backend
RewriteCond %{REQUEST_URI} ^/cloud
RewriteRule ^/cloud/?(.*) http://localhost:6868/$1 [P,L]
ProxyPassReverse /cloud http://localhost:6868/
<Location /cloud>
RequestHeader set X-Forwarded-Proto "https"
RequestHeader set X-Real-IP %{REMOTE_ADDR}s
RequestHeader set X-Forwarded-For %{REMOTE_ADDR}s
</Location>
</VirtualHost>Restart Apache:
sudo systemctl restart apache2Access your MyCloud at: https://yourdomain.com/cloud
This configuration serves MyCloud at https://cloud.yourdomain.com
Create /etc/nginx/sites-available/mycloud:
server {
listen 80;
server_name cloud.yourdomain.com;
client_max_body_size 500M;
location / {
proxy_pass http://localhost:6868;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
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;
}
}Enable site and configure SSL with Let's Encrypt:
sudo ln -s /etc/nginx/sites-available/mycloud /etc/nginx/sites-enabled/
sudo certbot --nginx -d cloud.yourdomain.com
sudo systemctl reload nginxAccess your MyCloud at: https://cloud.yourdomain.com
This configuration serves MyCloud at https://yourdomain.com/cloud
server {
listen 80;
server_name yourdomain.com;
client_max_body_size 500M;
location /cloud {
rewrite ^/cloud/(.*) /$1 break;
proxy_pass http://localhost:6868;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
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;
}
}# View logs
docker-compose logs -f
# Restart containers
docker-compose restart
# Stop containers
docker-compose down
# Update containers
docker-compose pull
docker-compose up -d --buildmycloud/
├── server/ # Backend (Node.js/Express)
│ ├── index.js # Main server file
│ ├── database/ # Database initialization
│ ├── middleware/ # Authentication middleware
│ └── routes/ # API routes
├── client/ # Frontend (React)
│ ├── src/
│ │ ├── components/ # React components
│ │ ├── pages/ # Application pages
│ │ ├── store/ # State management
│ │ └── api/ # API client
│ └── package.json
├── data/ # Runtime data (created on first run)
│ ├── database.sqlite # SQLite database
│ └── uploads/ # User uploaded files
├── docker-compose.yml # Docker configuration
├── Dockerfile
└── README.md
- JWT-based authentication
- Password hashing with bcrypt
- CORS protection
- Helmet.js security headers
- Rate limiting
- Input validation
- IMPORTANT: Change
JWT_SECRETandADMIN_PASSWORDbefore production deployment!
The application uses SQLite for simplified deployment. The database is automatically initialized on first startup.
Tables:
users- User account informationfiles- File metadatafolders- Folder structureshared_files- File sharing information
- Verify server is running:
docker-compose ps - Check logs:
docker-compose logs - Ensure port 6868 is available
- Administrator can increase quota in Admin Panel
- User can delete old files to free up space
- SQLite supports only one concurrent write operation
- Consider migrating to PostgreSQL/MySQL for high-traffic deployments
Backend:
- Node.js
- Express.js
- SQLite
- JWT for authentication
- bcrypt for password hashing
Frontend:
- React
- Tailwind CSS
- Zustand for state management
- Vite for build tooling
POST /api/auth/login- User loginPOST /api/auth/register- Create new user (admin only)
GET /api/files- List filesPOST /api/files/upload- Upload fileGET /api/files/download/:id- Download fileDELETE /api/files/:id- Delete filePOST /api/files/share/:id- Create share link
GET /api/folders- List foldersPOST /api/folders- Create folderDELETE /api/folders/:id- Delete folder
GET /api/users- List all usersPOST /api/users- Create userDELETE /api/users/:id- Delete user
By default, MyCloud stores data in a Docker volume. To use an external disk or different location:
Edit your docker-compose.yml or docker-compose.local.yml:
services:
mycloud:
# ... other settings ...
volumes:
- /mnt/external-disk/mycloud-data:/app/dataLinux/Raspberry Pi example:
volumes:
- /mnt/usb-drive/mycloud:/app/dataWindows example:
volumes:
- D:/MyCloud/data:/app/datavolumes:
mycloud-data:
driver: local
driver_opts:
type: none
o: bind
device: /mnt/external-disk/mycloud-dataIf you already have existing data and want to move it:
# 1. Stop the container
sudo docker compose -f docker-compose.local.yml down
# 2. Create directory on external disk
sudo mkdir -p /mnt/external-disk/mycloud-data
# 3. Copy existing data from Docker volume
sudo docker run --rm \
-v mycloud-data:/from \
-v /mnt/external-disk/mycloud-data:/to \
alpine cp -a /from/. /to/
# 4. Set proper permissions
sudo chown -R 1000:1000 /mnt/external-disk/mycloud-data
# 5. Update docker-compose file with new path
# Change volumes section to use bind mount:
# volumes:
# - /mnt/external-disk/mycloud-data:/app/data
# And REMOVE the volumes: definition at the bottom (mycloud-data:)
# 6. Remove old Docker volume completely
# ⚠️This will delete your data if not copied before!⚠️
sudo docker volume rm mycloud_mycloud-data
# If it fails, use: sudo docker compose -f docker-compose.local.yml down -v
# 7. Verify volume is removed
sudo docker volume ls | grep mycloud
# 8. Start container with new location
sudo docker compose -f docker-compose.local.yml up -d
# 9. Verify it's using the correct location
docker inspect mycloud | grep -A 5 Mounts
ls -la /mnt/external-disk/mycloud-data/This guide explains how to build and run MyCloud as a native Android/iOS mobile app using Capacitor.
- Node.js 16+ and npm
- Android Studio (latest version)
- Java Development Kit (JDK) 11 or later
- Android SDK (installed via Android Studio)
- Node.js 16+ and npm
- Xcode 14+ (from Mac App Store)
- CocoaPods (
sudo gem install cocoapods) - iOS SDK (installed via Xcode)
# Navigate to the client directory
cd client
# Install all dependencies including Capacitor packages
npm install# From the root directory
npm run buildThis creates an optimized production build in client/dist with PWA support.
Note: Set "http" in capacitor.config.ts to "https" if used in production/online mode.
# From the root project directory
npx cap add androidThis creates an android/ directory with a native Android project.
# Copy web build to native project
npm run sync
# Or use Capacitor CLI directly:
npx cap sync androidnpm run android
# This opens Android Studio with the projectOr manually:
npx cap open androidIn Android Studio:
- Wait for Gradle sync to complete
- Connect an Android device via USB (with USB debugging enabled) or start an emulator
- Click the "Run" button (green play icon) or press Shift+F10
- Select your device from the list
The app will install and launch on your device.
# From the root project directory
npx cap add iosThis creates an ios/ directory with a native iOS Xcode project.
npm run sync
# Or use Capacitor CLI directly:
npx cap sync ioscd ios/App
pod install
cd ../..npm run ios
# This opens Xcode with the projectOr manually:
npx cap open iosIn Xcode:
- Select your development team in the "Signing & Capabilities" tab
- Select a target device or simulator
- Click the "Run" button (play icon) or press Cmd+R
The app will install and launch on your device/simulator.
After modifying the web app code:
-
Rebuild the web app:
cd client npm run build -
Sync changes to native projects:
npm run sync
-
Rerun the app in Android Studio or Xcode
For issues or questions:
- Check logs:
docker-compose logs -f - Verify all environment variables are properly set
- Ensure port 6868 is not already in use
- Review the troubleshooting section above
Contributions are welcome.
MyCloud - Your data, your control
