Documentation
Install
Two ways to run Casual Drive — a one-line Docker command for the impatient, or a from-source build for the curious. Either way, you're done in 30 seconds.
Docker (recommended)
The fastest path. One command, one container, persistent storage on the host.
docker run -d \
--name casual-drive \
-p 8080:8080 \
-v $HOME/drive-data:/data \
-e DRIVE_BIND=0.0.0.0:8080 \
-e DRIVE_APP_ORIGIN=https://drive.your-server \
-e DRIVE_USERCONTENT_ORIGIN=https://usercontent-drive.your-server \
-e DRIVE_STORAGE_BACKEND=fs \
-e DRIVE_FS_ROOT=/data \
ghcr.io/schnsrw/casual-drive:latest
That’s it. Visit https://drive.your-server in your browser, complete the first-run admin setup, and you have a working Drive.
The image is a multi-stage cargo-chef build on top of debian:trixie-slim. Compressed image size is around 90 MB.
From source
You’ll need:
- Rust 1.85+ (toolchain pinned in
rust-toolchain.toml) - pnpm 9+ (Node 20+)
- A C toolchain for SQLite (Debian:
build-essential; macOS: Xcode CLT)
git clone https://github.com/schnsrw/casual-drive.git
cd casual-drive
# Build the SPA — its dist/ is embedded into the Rust binary via rust-embed.
cd web
pnpm install
pnpm build
cd ..
# Build + run the server.
cargo run --release -p drive
Default port is :8080. The single binary serves the SPA, the JSON API, the WOPI endpoints, and the user-content origin.
Required environment
These five are non-negotiable in production:
| Var | Purpose |
|---|---|
DRIVE_BIND | TCP bind address. Use 0.0.0.0:8080 behind a reverse proxy. |
DRIVE_APP_ORIGIN | The origin the app lives on (https://drive.example.com). Cookies + CSP scope here. |
DRIVE_USERCONTENT_ORIGIN | The origin that serves raw bytes (https://usercontent-drive.example.com). Must differ from DRIVE_APP_ORIGIN. |
DRIVE_STORAGE_BACKEND | fs, s3, minio, or memory. |
DRIVE_DATABASE_URL | sqlite:///data/drive.db or postgres://user:pass@host/db. |
Drive will refuse to start if DRIVE_APP_ORIGIN == DRIVE_USERCONTENT_ORIGIN in production. That’s a deliberate safety rail — see the two-origin architecture.
The full env-var table — including storage credentials, session knobs, and editor URLs — lives on Configuration.
First-run checklist
- Open the app.
https://drive.your-server— you should see the Setup screen. - Create the admin. Username + 12+ character password. Argon2id-hashed, stored in
users. - Upload a file. Pick anything; we sniff its magic bytes and store the metadata in the
filestable. - Click it. A
.xlsxopens in Casual Sheet, a.docxin Casual Document, anything else previews inline (image, PDF, video, audio, Markdown, plain text). - Configure backups. See Configuration → Backup — Drive’s data lives in the database + the storage backend; both need their own backup plan.
Reverse proxy
Drive itself listens on plain HTTP and expects a reverse proxy to terminate TLS. A minimal Caddy config:
drive.your-server {
reverse_proxy localhost:8080
}
usercontent-drive.your-server {
reverse_proxy localhost:8080
}
Both hostnames point at the same Drive process — the request Host header is what selects the origin. Nginx, Traefik, Cloudflare Tunnel all work the same way.
Upgrading
Pull the new image and restart. SQL migrations run automatically on boot via sqlx::migrate!(). The migration log is in audit_events, action system.migration_applied.