Skip to content

Self-Hosting Guide

OpenSuite is designed to be easy to self-host. The entire application is static HTML, CSS, and JavaScript served by nginx. A pre-built Docker image is available on Docker Hub.

Docker Hub

The official Docker image is available at:

dseegers/opensuite

docker pull dseegers/opensuite:latest

Quick Start with Docker

Run OpenSuite locally with a single command:

docker run -d -p 8080:80 dseegers/opensuite:latest

Then open http://localhost:8080 in your browser.

URL Application
http://localhost:8080 OpenSuite landing page
http://localhost:8080/sheets.html OpenSheets (Spreadsheet)
http://localhost:8080/docs.html OpenDocs (Word Processor)
http://localhost:8080/presentation.html OpenPresentation (Presentations)
http://localhost:8080/docs/ Documentation

Docker Compose

Create a docker-compose.yml file:

services:
  opensuite:
    image: dseegers/opensuite:latest
    ports:
      - "8080:80"
    restart: unless-stopped

Start it:

docker compose up -d

Building from Source

If you want to build the Docker image yourself:

Prerequisites

Clone and Build

git clone https://github.com/your-repo/opensuite.git
cd opensuite
docker build -t opensuite .

Run Your Custom Build

docker run -d -p 8080:80 opensuite

Using Make

The repository includes a Makefile with convenient commands:

make build          # Build the Docker image
make run            # Run the container locally on port 8080
make stop           # Stop the running container
make push           # Push image to Docker Hub (requires docker login)

What's Inside the Image

The Docker image is a multi-stage build:

  1. Build stage: Uses Python to build the MkDocs documentation site
  2. Runtime stage: Uses nginx:1.27-alpine (~20 MB) to serve the static files

The image contains:

  • nginx as the web server
  • All OpenSuite HTML, CSS, and JavaScript files
  • Pre-built documentation site (served at /docs/)

Image Details

Property Value
Base image nginx:1.27-alpine
Image size ~20 MB
Exposed port 80
Health check GET /health

Architecture

Container (port 80)
├── /                        → Landing page (index.html)
├── /sheets.html             → OpenSheets
├── /docs.html               → OpenDocs
├── /presentation.html       → OpenPresentation
├── /css/                    → Stylesheets
├── /js/                     → JavaScript application code
└── /docs/                   → MkDocs documentation site

nginx Configuration

The included nginx.conf provides:

  • Gzip compression for text, CSS, JavaScript, and SVG files
  • Static asset caching with 1-hour expiry for JS, CSS, images, and fonts
  • Health check endpoint at /health for container orchestration
  • Clean URL routing with fallback to index.html

Running Without Docker

Since OpenSuite is entirely static, you can serve it with any web server:

Python (quick development server)

cd opensuite
python3 -m http.server 8080

Node.js (using npx)

cd opensuite
npx serve -p 8080

nginx (manual setup)

Copy the HTML, CSS, and JS files to your nginx web root:

cp index.html sheets.html docs.html presentation.html /usr/share/nginx/html/
cp -r css/ /usr/share/nginx/html/css/
cp -r js/ /usr/share/nginx/html/js/

Documentation site

The /docs/ documentation site requires building with MkDocs first:

pip install mkdocs mkdocs-material
mkdocs build
Then copy the site/ output to your web server.

Sharing Still Works Locally

Even when self-hosting, you can still share your spreadsheets, documents, and presentations with anyone. When you click Save & Share, your data is compressed and encoded as a base64 string directly in the URL. The recipient does not need access to your server -- the data is embedded in the link itself. They simply need any running instance of OpenSuite (or the hosted version at opensuite.fly.dev) to open it.

Environment Variables

OpenSuite does not require any environment variables. All data is stored client-side in the browser (localStorage and URL hash). No database or backend service is needed.

Reverse Proxy

If running behind a reverse proxy (e.g., Traefik, Caddy, or another nginx), make sure to:

  1. Forward the Host header
  2. Allow WebSocket connections (for live reload during development)
  3. Set appropriate X-Forwarded-Proto headers for HTTPS

Example: Traefik with Docker Compose

services:
  opensuite:
    image: dseegers/opensuite:latest
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.opensuite.rule=Host(`suite.example.com`)"
      - "traefik.http.routers.opensuite.tls=true"
      - "traefik.http.routers.opensuite.tls.certresolver=letsencrypt"
      - "traefik.http.services.opensuite.loadbalancer.server.port=80"
    restart: unless-stopped

Example: Caddy

suite.example.com {
    reverse_proxy opensuite:80
}

Updating

To update to the latest version:

docker pull dseegers/opensuite:latest
docker compose down
docker compose up -d

Or with plain Docker:

docker pull dseegers/opensuite:latest
docker stop opensuite
docker rm opensuite
docker run -d --name opensuite -p 8080:80 dseegers/opensuite:latest