Spaces:
Running
Server Mode - Self-Hosting Guide
Self-host OSW Studio with persistence, authentication, and static site publishing.
Overview
OSW Studio supports two deployment modes:
- Browser Mode (default): Pure client-side application using IndexedDB
- Server Mode: Full-stack deployment with publishing
Server Mode adds:
- Local database for persistent storage (no external database needed)
- Admin authentication with JWT sessions
- Sites publishing system with static site serving
- Project sync between browser and server
- Built-in analytics and compliance features
Browser Mode vs Server Mode
Browser Mode (Default)
Characteristics:
- β No backend required
- β Deploy to any static host (Vercel, Netlify, GitHub Pages, HuggingFace)
- β Zero configuration
- β Complete privacy (data never leaves browser)
- β No multi-user support
- β No server-side persistence
- β No static site publishing
Use Cases:
- Personal development environment
- Quick prototyping
- Privacy-focused workflows
- Static deployment (HuggingFace Spaces)
Server Mode
Characteristics:
- β Local persistence (no external database)
- β Admin authentication
- β Multiple sites per project
- β
Static site publishing at
/sites/{siteId}/ - β Built-in analytics
- β Project sync (browser β server)
- β Requires persistent file system
- β Requires server hosting
Use Cases:
- Production deployments
- Multi-user environments
- Publishing static sites
- Persistent project storage
Project Sync
Server Mode uses a hybrid storage approach: projects are edited locally in the browser (for speed) and synced to the server (for persistence). This gives you the best of both worlds - fast local editing with server-side backup.
How Sync Works
Automatic Push (on save): When you save a project in Server Mode, it automatically syncs to the server. You'll see a brief "Project synced β" notification.
Automatic Pull (on load): When you open the Project Manager, OSW Studio checks for any updates from the server and pulls them automatically. Projects that exist on the server but not locally are downloaded.
Manual Sync: For bulk operations or troubleshooting, use the Sync button in the sidebar. This opens a dialog where you can:
- Push to Server - Upload all local projects to the database
- Pull from Server - Download all server projects to your browser
When to Use Manual Sync
- Setting up a new browser - Pull to populate your IndexedDB from the server
- After server restore - Pull to get the restored data locally
- Troubleshooting - Force push/pull if auto-sync isn't working
Quick Start
1. Configure Environment
Create .env file in project root:
# Enable Server Mode
NEXT_PUBLIC_SERVER_MODE=true
# Session security (generate with: openssl rand -base64 32)
SESSION_SECRET=your_random_secret_here
# Admin password
ADMIN_PASSWORD=your_secure_password_here
# Optional: Analytics secret
ANALYTICS_SECRET=your_analytics_secret_here
# Optional: App URL (for SEO/sitemaps)
NEXT_PUBLIC_APP_URL=https://your-domain.com
2. Start Server
npm install
npm run dev
SQLite databases are created automatically:
data/osws.sqlite- Core database (projects, templates, skills)sites/{siteId}/site.sqlite- Per-site databases (files, settings, analytics)
3. Access Application
- Studio: http://localhost:3000/
- Admin panel: http://localhost:3000/admin/login
- Published sites: http://localhost:3000/sites/{siteId}/
Login with ADMIN_PASSWORD from .env
Deployment Options
β οΈ Important: Server Mode requires persistent file system storage because published sites are written to
/public/sites/and databases are stored locally. Serverless platforms like Vercel, Netlify, and Cloudflare Workers will not work for Server Mode.
Option 1: Railway (Recommended)
Why: Simple setup, persistent storage, usage-based pricing
Pricing: $5/month minimum (includes $5 in usage credits). Free trial: 30 days with $5 credits.
Steps:
Create Railway Account:
- Go to https://railway.app
- Sign up with GitHub
New Project:
- Click "New Project"
- Select "Deploy from GitHub repo"
- Choose your OSW Studio fork
Configure Variables:
- Go to project variables
- Add:
NEXT_PUBLIC_SERVER_MODE=true SESSION_SECRET=<generate> ADMIN_PASSWORD=<your password> NEXT_PUBLIC_APP_URL=${{ RAILWAY_PUBLIC_DOMAIN }}
Deploy:
- Railway auto-deploys on push
- Access at:
https://your-project.up.railway.app
Option 2: VPS (Full Control)
Why: Complete control, custom domains, lowest cost at scale
Requirements:
- Ubuntu 22.04+ server
- SSH access
- Domain (optional)
Steps:
Install Dependencies:
# Update system sudo apt update && sudo apt upgrade -y # Install Node.js 18+ curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash - sudo apt install -y nodejs # Install git sudo apt install -y gitClone and Configure:
# Clone repository git clone https://github.com/o-stahl/osw-studio.git cd osw-studio # Install dependencies npm install # Create .env nano .envPaste:
NEXT_PUBLIC_SERVER_MODE=true SESSION_SECRET=<generate with: openssl rand -base64 32> ADMIN_PASSWORD=<your password> NEXT_PUBLIC_APP_URL=http://your-domain.comBuild and Start:
# Production build npm run build # Start with PM2 (process manager) sudo npm install -g pm2 pm2 start npm --name "osw-studio" -- start pm2 save pm2 startupSetup Nginx (Reverse Proxy):
sudo apt install -y nginx sudo nano /etc/nginx/sites-available/osw-studioPaste:
server { listen 80; server_name your-domain.com; location / { proxy_pass http://localhost:3000; 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; } }Enable:
sudo ln -s /etc/nginx/sites-available/osw-studio /etc/nginx/sites-enabled/ sudo nginx -t sudo systemctl restart nginxSetup SSL (Let's Encrypt):
sudo apt install -y certbot python3-certbot-nginx sudo certbot --nginx -d your-domain.com
Access:
- http://your-domain.com (redirects to HTTPS)
- https://your-domain.com/admin/login
Publishing Sites
Once Server Mode is running, you can publish sites directly from OSW Studio.
How Publishing Works
- Create a Site from any project
- Configure Settings: Scripts, analytics, SEO, compliance
- Click "Publish": Static builder compiles project files
- Site Goes Live at:
https://your-osw-instance.com/sites/{siteId}/
Creating a Site
From Projects View:
- Right-click on a project card
- Select "Create Site"
- Enter site name
- Click "Create Site"
From Sites View:
- Click "+ New Site" button
- Select source project
- Enter site details
- Click "Create Site"
Site Settings
General:
- Site name
- URL slug (optional)
- Custom domain (advanced - see below)
- Under construction mode
Scripts:
- Head scripts (analytics, meta tags)
- Body scripts (chat widgets, tracking)
- Async/defer options
CDN Resources:
- External CSS/JS libraries
- Font imports
- Icon libraries
Analytics:
- Built-in (privacy-focused, no cookies)
- Google Analytics 4
- Google Tag Manager
- Plausible
- Custom tracking
SEO:
- Meta title/description
- Open Graph tags
- Twitter Card
- Canonical URLs
- Auto-generated sitemap.xml and robots.txt
Compliance:
- Cookie consent banner
- Opt-in/opt-out modes
- Privacy policy links
- GDPR/CCPA compliance
Publishing Workflow
- Create/edit site settings
- Click "Save & Close"
- Click "Publish Now" (or right-click site β Publish)
- Static builder runs:
- Loads project files from server
- Compiles Handlebars templates
- Injects configured settings (scripts, analytics, SEO)
- Generates sitemap.xml and robots.txt
- Writes to
/public/sites/{siteId}/
- Site is live!
Accessing Published Sites
Default URL:
https://your-osw-instance.com/sites/{siteId}/
Clean URLs (Next.js rewrites):
/sites/{siteId}/about β /sites/{siteId}/about.html
/sites/{siteId}/blog/post β /sites/{siteId}/blog/post.html
Managing Sites
View Sites: Navigate to Sites page (Server Mode only)
Site Actions (right-click menu):
- View Live
- Settings
- Republish
- Copy Link
- View Source Project
- Analytics Dashboard
- Capture Thumbnail
- Unpublish
- Delete
Unpublish: Disables site but keeps settings (can re-publish later)
Delete: Permanently removes site and settings
Custom Domains (Advanced)
β οΈ Note: This section is for advanced users with sysadmin knowledge. OSW Studio does not handle DNS or reverse proxy configuration automatically.
Overview
By default, published sites are available at:
https://your-osw-instance.com/sites/{siteId}/
You can configure a custom domain (e.g., sweetcandies.com) to point to your site using a reverse proxy. OSW Studio will then use your custom domain in SEO meta tags, sitemaps, and canonical URLs.
Prerequisites
- Domain you control
- Access to DNS records
- Reverse proxy (Nginx, Caddy, or Apache)
- SSL certificate (Let's Encrypt recommended)
Architecture
User's Browser
β
sweetcandies.com (DNS)
β
Reverse Proxy (Nginx)
β
your-osw-instance.com/sites/abc123/
β
Static files served
Setup Steps
1. Configure DNS
Point your domain to your server's IP:
For root domain (sweetcandies.com):
Type: A
Name: @
Value: 123.45.67.89 (your server IP)
TTL: 3600
For subdomain (www.sweetcandies.com):
Type: CNAME
Name: www
Value: your-osw-instance.com
TTL: 3600
Wait for DNS propagation (usually < 1 hour, up to 48 hours).
2. Configure Reverse Proxy
Nginx Example:
server {
listen 80;
listen [::]:80;
server_name sweetcandies.com www.sweetcandies.com;
# Redirect to HTTPS
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name sweetcandies.com www.sweetcandies.com;
# SSL certificates (Let's Encrypt)
ssl_certificate /etc/letsencrypt/live/sweetcandies.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/sweetcandies.com/privkey.pem;
# Proxy to OSW Studio site
location / {
proxy_pass https://your-osw-instance.com/sites/abc123/;
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;
# Rewrite location headers
proxy_redirect https://your-osw-instance.com/sites/abc123/ /;
}
}
Save to /etc/nginx/sites-available/sweetcandies.com
Enable:
sudo ln -s /etc/nginx/sites-available/sweetcandies.com /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
3. Setup SSL
sudo certbot --nginx -d sweetcandies.com -d www.sweetcandies.com
4. Configure Custom Domain in OSW Studio
- Go to Sites β Your Site β Settings
- Navigate to General tab
- Enter custom domain:
sweetcandies.com - Save and republish
OSW Studio will now use sweetcandies.com in:
- SEO meta tags
- Sitemap.xml URLs
- Open Graph URLs
- Canonical URLs
Caddy Example (Easier)
Caddy automatically handles HTTPS with Let's Encrypt:
sweetcandies.com, www.sweetcandies.com {
# Rewrite all requests to site path
rewrite * /sites/abc123{uri}
reverse_proxy your-osw-instance.com {
header_up Host {upstream_hostport}
header_up X-Real-IP {remote_host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Proto {scheme}
}
}
Note: The rewrite directive must be outside reverse_proxy. Caddy rewrites the URI first, then proxies to the backend.
What OSW Studio Does
- β Stores custom domain in database
- β Uses it for SEO meta tags
- β Generates sitemap.xml with custom domain
- β Updates canonical URLs
What OSW Studio Doesn't Do
- β DNS management
- β Reverse proxy configuration
- β SSL certificate generation
- β Domain validation
Troubleshooting
Database Issues
Symptoms: "Failed to initialize database"
Solutions:
- Check write permissions on
data/directory - Ensure disk space is available
- Check file system supports SQLite (most do)
- Try deleting
data/osws.sqliteand restarting (loses data)
Migration Failures
Symptoms: Tables not created, "relation does not exist"
Solutions:
- Migrations run automatically on first request
- Check terminal logs for errors
- Restart the server to trigger migrations
Publishing Errors
Symptoms: Site not building, empty /public/sites/
Solutions:
- Check build logs in terminal
- Verify project has files synced to server
- Check Handlebars syntax in templates
- Verify disk permissions:
ls -la public/ chmod 755 public/ - Check available disk space:
df -h
Custom Domain Not Working
Symptoms: Domain doesn't load site
Solutions:
- Verify DNS is configured correctly:
dig sweetcandies.com nslookup sweetcandies.com - Wait for DNS propagation (up to 48 hours)
- Check reverse proxy configuration:
# Nginx sudo nginx -t sudo systemctl status nginx # Check logs sudo tail -f /var/log/nginx/error.log - Verify SSL certificate:
sudo certbot certificates - Test direct access to OSW site path:
https://your-osw-instance.com/sites/{siteId}/ - Hard refresh browser (Ctrl+Shift+R)
- Clear browser cache
Authentication Issues
Symptoms: Can't login to /admin
Solutions:
- Verify
ADMIN_PASSWORDis set in .env - Try resetting password:
# Update .env ADMIN_PASSWORD=new_password_here # Restart server pm2 restart osw-studio # or npm run dev - Clear browser cookies
- Try incognito mode
- Check
SESSION_SECRETis set
Performance Issues
Symptoms: Slow site loads, high memory
Solutions:
- Optimize published sites:
- Compress images
- Minify CSS/JS
- Use CDN for libraries
- Monitor server resources:
htop # or top df -h # disk space free -m # memory - Scale server resources (RAM/CPU)
- Add caching (Nginx cache)
Site Not Updating After Republish
Symptoms: Changes not showing on published site
Solutions:
- Hard refresh browser (Ctrl+Shift+R)
- Check
settingsVersionvslastPublishedVersionin site card - Verify "Publish" was clicked (not just "Save")
- Check build succeeded in terminal logs
- Inspect HTML source for changes
- Clear CDN cache (if using one)
Next Steps
- FAQ - Common Server Mode questions
- Deploying Sites - Deploy user sites to Vercel/Netlify
- Troubleshooting - Fix common issues