Documentation

Nexora Guide

Everything you need to install, configure, secure, and get the most out of your private file workspace — from first docker pull to daily operations.

docker pull ghcr.io/suryaprakash251201/nexora:latest-8141398

Quick Start

Docker Compose is the recommended deployment path. It builds both applications and exposes Nexora on port 80.

terminal — bash
# 1. Configure the instance
cp .env.example .env
openssl rand -hex 32  # set as NEXORA_SESSION_SECRET

# 2. Start Nexora
docker compose up -d --build
docker compose ps

# 3. Verify it's healthy
curl -f http://localhost/healthz
 {"service":"nexora","status":"ok","version":"1.9.0"}

# 4. Open your browser and complete first-run setup
open http://localhost
If the session secret is blank, Nexora generates one and persists it in SQLite. Supplying a stable secret is recommended for managed deployments.

Installation

Three supported ways to run Nexora — pick whichever fits your workflow.

Option A — Docker Compose (recommended)

terminal — bash
git clone https://github.com/suryaprakash251201/nexora.git
cd nexora
cp .env.example .env
docker compose up -d --build

The included Compose file mounts these host folders:

Host folderContainer pathAccess
./data/files/mnt/filesRead/write
./data/media/mnt/mediaRead-only
./data/backups/mnt/backupsRead/write
./data/shared/mnt/sharedRead/write

The named nexora-data volume contains SQLite, the thumbnail cache, and the temporary archive workspace. Back it up alongside the mounted storage folders.

Option B — Docker Run from GHCR

Pull the official image from GitHub Container Registry and run it directly — no build required:

terminal — bash
# 1. Pull the official image
docker pull ghcr.io/suryaprakash251201/nexora:latest-8141398

# 2. Run it — web UI on http://localhost:8080
docker run -d --name nexora \
  -p 8080:80 \
  -v nexora-data:/app/data \
  -v ./data/files:/mnt/files \
  -e NEXORA_LISTEN_ADDR=:80 \
  -e NEXORA_SESSION_SECRET=$(openssl rand -hex 32) \
  ghcr.io/suryaprakash251201/nexora:latest-8141398
The single container serves both the compiled web app and the Go API — there is nothing else to install.

Option C — From source

Prerequisites: Go 1.26+, Node.js 20+, and npm. Local development works when storage root paths are valid for your host operating system.

terminal — bash
# Terminal 1 — API (http://localhost:8080)
go run ./cmd/nexora

# Terminal 2 — web app (http://localhost:5173)
cd web && npm install && npm run dev

The Vite dev server proxies /api and /healthz to http://localhost:8080. For a local root, replace the Docker-oriented defaults in .env:

.env
NEXORA_DEFAULT_ROOTS=Files:./data/files:false

First-Run Setup

  1. Open http://localhost in your browser.
  2. Complete the Setup Wizard to create your administrator account.
  3. Nexora auto-creates the configured default storage roots from NEXORA_DEFAULT_ROOTS and grants that administrator access.
  4. Start browsing — upload files, mount more roots from the Admin panel, and invite users.
Leave NEXORA_SECURE_COOKIES=false while testing on plain http://localhost — secure cookies are only sent over HTTPS, so enabling them early will lock you out of logging in. Flip it to true once a TLS proxy is in front (see the next section).

HTTPS & Reverse Proxy

Nexora serves HTTP inside its container. For an internet-facing server, place Caddy, Nginx, Traefik, Cloudflare Tunnel, or another TLS proxy in front of it.

  1. Configure the proxy to forward your domain to Nexora's HTTP port.
  2. Set NEXORA_BASE_URL to the public HTTPS URL (used for generated share links).
  3. Set NEXORA_SECURE_COOKIES=true.
  4. Set NEXORA_TRUSTED_PROXIES only to the proxy networks that should be trusted for X-Forwarded-For and X-Real-IP.
  5. Prevent direct public access to the HTTP port when the proxy is on the same server.

Minimal proxy configs

Two copy-paste starting points. Caddy handles certificates automatically; Nginx needs certbot or your own certificate.

Caddyfile
files.example.com {
    reverse_proxy 127.0.0.1:8080
}
nginx.conf
server {
    listen 443 ssl;
    server_name files.example.com;
    client_max_body_size 0;   # no upload ceiling at the proxy
    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
client_max_body_size 0 (Nginx) matters — Nginx caps request bodies at 1 MB by default, which surfaces as mysterious failed uploads.
.env
# Public URL for generated share links; no trailing slash
NEXORA_BASE_URL=https://files.example.com

# Use a stable random secret for sessions
NEXORA_SESSION_SECRET=replace-with-a-long-random-secret

# Required when HTTPS is terminated by a reverse proxy
NEXORA_SECURE_COOKIES=true

# Set only when a trusted proxy supplies client-IP headers
# NEXORA_TRUSTED_PROXIES=172.16.0.0/12

Configuration Reference

Copy .env.example to .env for documented defaults. Key settings:

VariablePurpose
NEXORA_LISTEN_ADDRHTTP listen address; Compose sets this to :80.
NEXORA_BASE_URLPublic base URL for generated share links.
NEXORA_DATA_DIRDatabase, cache, and archive-workspace directory.
NEXORA_DATABASE_TYPEMetadata store: sqlite (default) or postgres.
NEXORA_DATABASE_PATH / NEXORA_DATABASE_URLSQLite path or PostgreSQL connection URL.
NEXORA_SESSION_SECRETSession-signing secret (generate with openssl rand -hex 32).
NEXORA_SESSION_LIFETIMESession lifetime, e.g. 168h.
NEXORA_SECURE_COOKIESSet to true for HTTPS.
NEXORA_MAX_UPLOAD_SIZEMaximum upload size, e.g. 512GB (default: effectively unlimited).
NEXORA_ALLOWED_MIMEOptional comma-separated upload allowlist.
NEXORA_DEFAULT_ROOTSRoots created on first setup: Name:/path:readOnly[:indexed].
NEXORA_RATE_LIMIT_PER_MINLogin rate limit (default 60).
NEXORA_LOCKOUT_ATTEMPTS / NEXORA_LOCKOUT_WINDOWAccount lockout policy (default 5 / 15m).
NEXORA_TRUSTED_PROXIESProxy CIDRs allowed to send client-IP headers.
NEXORA_CORS_ORIGINSAllowed browser origins; empty disables CORS.
NEXORA_ENABLE_FFMPEG_THUMBSEnables FFmpeg video thumbnail generation.
NEXORA_THUMBNAIL_MAX_SIZE / NEXORA_THUMBNAIL_TTLThumbnail cache policy (default 20MB / 168h).
NEXORA_ENABLE_PROMETHEUSEnables the /metrics endpoint.
NEXORA_MAX_EDITABLE_SIZEMaximum file size for the built-in editor.
NEXORA_LOG_LEVELLog verbosity: debug, info (default), warn, or error.
NEXORA_LOG_FORMATLog output format: text (default) or json.
NEXORA_THUMBNAIL_CACHE_DIROverride the thumbnail cache location (inside NEXORA_DATA_DIR by default).

Features Guide

File Browser

Right-click any file for the full action menu: download, preview, rename, move, copy, delete (to trash), archive as ZIP, or add to favorites.

  • Upload — drag-and-drop anywhere, or use the Upload button.
  • Preview — images, video, audio, PDFs, Markdown, and code in one click.
  • Bulk operations — multi-select files for batch download, move, delete, or bulk rename.
  • Views — grid or list, with density control and a column picker.

Multiple Storage Roots

Named locations managed from one UI, with per-user read or write access on each root. Configure defaults in .env:

.env
NEXORA_DEFAULT_ROOTS=Files:/mnt/files:false,Media:/mnt/media:true,Backups:/mnt/backups:false

Search & Organization

  • Instant search — type in the search bar at the top of the file browser.
  • Global search — full-text search across all roots from the Search view.
  • Filters — by type: All, Documents, Images, Videos, Audio, Archives, Folders.
  • Smart folders — saved searches that auto-update, e.g. “Images modified this week”.
  • Tags & favorites — organize anything, from anywhere.
  • Duplicate discovery — find duplicate files by checksum.

Sharing

Create revocable public links with optional expiry, password protection, and download limits. The shared page works for anyone — no account required.

Playlists & Media

  • Audio playlists — public and collaborative playlists with a lossless-friendly player.
  • Video — HTTP Range streaming for instant seeking, subtitles, theater mode, browser fullscreen.
  • FFmpeg — optional video thumbnails and transcoding.

Administration

Users, roles, root access, storage settings, storage analytics dashboards, audit history, search reindexing, and file versioning — all from the Admin panel.

Keyboard Shortcuts

Press ? (or Cmd+/ / Ctrl+/) anywhere to see the full searchable overlay.

Global

ShortcutAction
Cmd+K / Ctrl+KOpen command palette
? / Cmd+/ / Ctrl+/Keyboard shortcuts overlay
EscClose modal / clear selection

File operations

ShortcutAction
Cmd+N / Ctrl+NNew folder
Cmd+Shift+N / Ctrl+Shift+NNew text file
Cmd+U / Ctrl+UUpload files
F5Refresh view
Cmd+D / Ctrl+DDownload selected
Cmd+Shift+S / Ctrl+Shift+SShare selected
Cmd+Shift+F / Ctrl+Shift+FToggle favorite
F2Rename selected item
Cmd+Shift+M / Ctrl+Shift+MMove selection

Security & Operations

  • Passwords use Argon2id; sessions are server-side and use HTTP-only cookies.
  • State-changing requests require CSRF validation.
  • Login attempts are rate-limited and protected by account lockouts; optional TOTP two-factor authentication.
  • Storage access is permission-scoped, and path validation prevents traversal outside an authorized root.
  • The Docker image runs as an unprivileged user with a read-only root filesystem, dropped capabilities, and a temporary /tmp filesystem.
  • Audit records cover authentication, administration, and file activity.

Health checks

  • GET /healthz — liveness
  • GET /readyz — database readiness

Backup & Upgrade

Backup

Back up the nexora-data volume and every mounted storage folder before upgrades. The volume holds:

  • SQLite database (or PostgreSQL if configured)
  • Thumbnail cache
  • Archive workspace
terminal — bash
docker run --rm \
  -v nexora-data:/data \
  -v $(pwd):/backup alpine \
  tar czf /backup/nexora-data.tar.gz -C /data .

Upgrade

terminal — bash
# From source builds
docker compose up -d --build
docker compose logs -f nexora

# From a GHCR image, just pull the new tag and recreate
docker pull ghcr.io/suryaprakash251201/nexora:latest-8141398
Migrations run forward at startup. Restoring the database and the prior image is the safe rollback method.

API & Health Checks

Application endpoints live under /api/v1; public health checks are /healthz and /readyz. The complete route list is in internal/api/server.go in the repository.

terminal — curl
curl -f http://localhost/healthz
 {"service":"nexora","status":"ok"}

curl -f http://localhost/readyz
 {"status":"ready"}

Design tokens and visual guidance are in docs/design-system.md; a complete feature walkthrough is in docs/features.md — both in the GitHub repository.

FAQ

Is Nexora free?

Yes — it's open source under the MIT license. Run it forever, modify it, host it for as many users as you like.

Can I use PostgreSQL instead of SQLite?

Yes. Set NEXORA_DATABASE_TYPE=postgres and provide NEXORA_DATABASE_URL. SQLite remains the zero-config default. See docker-compose.postgres.yml in the repo.

Where do I report security issues?

Follow the instructions in SECURITY.md — do not open a public issue for vulnerabilities.

How do I expose only a subfolder of a drive?

Mount the exact folder into the container and register it as its own root — roots are paths, not whole drives.

Troubleshooting

The failure modes people actually hit, and the fix for each.

Uploads fail with large files behind a reverse proxy

Nginx caps request bodies at 1 MB by default. Set client_max_body_size 0; in your server block (see the config above). Caddy and Traefik have no default cap.

Can't log in after switching to HTTPS

If NEXORA_SECURE_COOKIES=true is set while the site is still served over HTTP, the browser silently drops the session cookie. Only enable it once TLS is actually in front — or test locally with it set to false.

No video thumbnails / playback won't start

Thumbnails and transcoding need FFmpeg inside the container (the official image includes it). Verify with docker exec nexora ffmpeg -version, and confirm NEXORA_ENABLE_FFMPEG_THUMBS=true. Direct streaming still works without it via HTTP Range requests.

TOTP codes always rejected

Two-factor codes depend on server clock accuracy. Check docker exec nexora date against real time — drift breaks RFC 6238 validation. On hosts without RTC (some VPS/ARM boards), enable NTP.

Search results are stale or missing files

Newly added files are picked up automatically, but if an external process modified the storage folder directly, trigger Admin → Reindex to rebuild the search index.

session secret must be at least 32 bytes on startup

The config validator enforces a strong signing key. Generate one with openssl rand -hex 32 and put it in NEXORA_SESSION_SECRET — or leave it empty once and Nexora will generate and persist one for you.