Deploying Glassy with Docker
Deploy Glassy as a self-hosted single-user appliance with Docker Compose — four required environment variables and you're running in minutes.
Before you start
- getting-started/01-welcome-to-glassy
What you'll learn
- Clone the glassy-selfhost appliance repository
- Configure the four required environment variables
- Start the appliance and retrieve the initial admin password
- Sign in and set a permanent password
- Verify the instance is healthy
Reference documentation
Read the technical docs for this feature →Self-hosting Glassy runs it on your own machine as a single-user personal appliance. This unlocks features the cloud can’t offer — live Obsidian vault sync, Ollama, and the Agent Gateway — because the server can reach your 127.0.0.1.
Prerequisites
- A server running Linux (Ubuntu 22.04+ recommended) with:
- 2 GB RAM minimum (4 GB recommended)
- 20 GB disk space
- Docker 24+ and Docker Compose v2+
- An active Glassy membership (Clear or Pro)
- Basic command-line familiarity
Quick start
Clone the appliance
git clone https://github.com/0Reliance/glassy-selfhost.git
cd glassy-selfhost Create your .env file
cp .env.example .envEdit .env and fill in four required fields:
GLASSY_MEMBER_EMAIL=your@glassy-account-email
GLASSY_SELFHOST_TOKEN=<pairing token from Settings → Self-hosting on app.glassy.fyi>
JWT_SECRET=$(openssl rand -hex 32)
API_KEY_ENCRYPTION_KEY=$(openssl rand -hex 32)The GLASSY_SELFHOST_TOKEN is a pairing token you generate in Settings → Self-hosting on app.glassy.fyi. It prevents anyone who merely knows your email from spinning up an unlocked instance using your membership — the cloud checks both your email and your token on first boot.
Generate the secrets on the command line:
echo "JWT_SECRET=$(openssl rand -hex 32)"
echo "API_KEY_ENCRYPTION_KEY=$(openssl rand -hex 32)" Start the appliance
docker compose up -dWait for initialization:
docker compose logs -fWhen you see the server listening, the appliance is ready.
Retrieve your initial password
On first boot, the appliance verifies your membership, creates your local admin account, and prints a random initial password once:
# First boot only — the password is printed to the logs once:
docker compose logs glassy | grep -A2 "Default admin created"
# Survives container recreation (deleted after your first password change):
docker exec glassy cat /app/data/.initial_admin_password Sign in
Open http://localhost:3000 in your browser. Sign in with your membership email and the password from the logs. You will be immediately prompted to set a permanent password on first login.
Registration is permanently disabled — this is a single-owner appliance.
What happens on first boot
Your email → Cloud: "membership active?" → Yes (cached 30 days)
↓
First boot → Create local admin (random password, printed once)
↓
Every login → Local JWT auth → No network, no phone-home
The appliance sends your email and a pairing token you control to app.glassy.fyi to verify your membership. No passwords or note content ever leave your machine. The result is cached for 30 days, so the appliance works offline within that window.
We cover this in detail in How Your Account Works.
All premium features unlocked
The appliance runs with INSTANCE_ID=self_hosted, which auto-unlocks every premium feature:
- GlassyKeep (bookmarks and web clipping)
- Voice Studio (recording and transcription)
- Knowledge Base / Second Brain / MCP server (Claude, Cursor, Windsurf, OpenCode, Hermes, Openclaw, Pi, and any MCP-compatible client)
- Agent Gateway
- All themes
No subscription billing runs on the appliance. No upsells, no commerce routes.
Verify your instance
Health check
curl http://localhost:3000/readyReturns JSON: {"status":"ready",...} when healthy. If you get HTML, the container is still starting — wait a few seconds.
Check the UI
The dashboard should show no upsells, no “upgrade” prompts, and no marketing surfaces. All features are unlocked.
What’s in the compose file
The docker-compose.yml sets these for you (no action needed):
| Variable | Default | Purpose |
|---|---|---|
INSTANCE_ID | self_hosted | Activates single-user gating — do not change |
DEPLOYMENT_LOCALITY | local | Hides the cloud-limitation banner in Obsidian settings |
OBSIDIAN_HOST_OVERRIDE | host.docker.internal | Bridges container to host for Obsidian connections |
ENABLE_MCP_SERVER | true | Enables MCP server and Second Brain |
ENABLE_AGENT_GATEWAY | true | Enables Agent Gateway |
Troubleshooting
What’s next?
Understand how your account works on the appliance — membership verification, local auth, and the 30-day offline window.