Sign inSign up

oxisoft/oxitick

By oxisoft

•Updated 8 days ago

Self-hosted sync server for OxiTick: private, offline-first tasks and notes (amd64/arm64).

Buildkit cache
Image
Web servers
Databases & storage
0

5.0K

oxisoft/oxitick repository overview

⁠OxiTick Server

Self-hosted sync server for OxiTick⁠ — a private, offline-first app for personal or collaborative to-do lists and notes. The app works fully offline; point it at this server to sync your data across devices and share lists with the people you choose. Your data never leaves infrastructure you control: no third-party cloud, no tracking, no ads.

⚠️ Never store passwords in OxiTick. A to-do/notes manager is private, but it is not a vault — passwords, recovery codes, and other secrets belong in a specialized password manager with encryption at rest and a secret-specific security model. Our recommendation for a personal, private password manager without cloud sync: IntelliWallet⁠.

Images: linux/amd64 and linux/arm64 (Raspberry Pi 4/5, Apple Silicon hosts, ARM VPS).

⁠Quick start

docker run -d --name oxitick -p 15773:15773 -v ./data:/app/data oxisoft/oxitick:latest

That's it — no configuration required. Auth secrets are generated automatically on first start and stored in the data volume. Or with compose:

# docker-compose.yml
services:
  oxitick:
    image: oxisoft/oxitick:latest
    ports:
      - "15773:15773"
    volumes:
      - ./data:/app/data
    environment:
      # Recommended: create the admin account at first start (see below)
      - ADMIN_USERNAME=admin
      - ADMIN_PASSWORD=change-me-min-8-chars
    restart: unless-stopped
docker compose up -d

Then open http://your-host:15773/admin, log in, and create app user accounts under Users. In the OxiTick app: Settings → Sync Settings → enter the server URL and the user credentials.

⁠First-run admin account

Two ways to create the admin (for the /admin panel):

  1. Environment bootstrap (recommended): set ADMIN_USERNAME and ADMIN_PASSWORD — the account is created before the server accepts its first request, so there is no window where an unauthenticated visitor could claim /admin/setup. Once an admin exists, these variables are ignored (they never overwrite).
  2. Interactive setup: without those variables, the first visit to /admin redirects to a one-time setup page. Fine for trusted networks; on anything internet-reachable, prefer option 1.

App user accounts are admin-created only — there is no public registration endpoint.

⁠Environment variables

VariableRequiredDefaultDescription
JWT_SECRETnoautoSigning secret for auth tokens. If unset, a strong secret is generated on first start and stored at DATA_DIR/jwt_secret (keep the volume — losing it logs every device out). Set it explicitly only if you rotate secrets yourself or run multiple instances against one database.
ADMIN_USERNAMEno—Bootstrap admin account name (min 3 chars). Ignored once an admin exists.
ADMIN_PASSWORDno—Bootstrap admin password (min 8 chars). Both variables must be set together.
PORTno15773HTTP listen port inside the container. OxiTick deliberately defaults to its own unique port instead of a common one like 8080, so it never collides with other services.
HOSTno0.0.0.0Listen address.
DB_PATHno/app/data/oxitick.dbSQLite database path (inside the volume by default).
DATA_DIRno/app/dataDirectory for admin config, file-attachment uploads, and the generated JWT secret.
JWT_EXPIRYno24hAccess token lifetime (Go duration).
REFRESH_TOKEN_EXPIRYno720hRefresh token lifetime.

⁠Volumes

PathContents
/app/dataSQLite database, admin configuration, uploaded file attachments, and the generated JWT secret — this is all your state; back it up.

⚠️ Always mount /app/data to a named volume or host directory. If you run the container without a mount, Docker puts /app/data in an anonymous volume: your data survives restarts, but recreating the container (docker rm + run, image update, compose recreate) silently starts with an empty database and a fresh JWT secret — all data is gone and every device is logged out. With a real mount (-v ./data:/app/data), containers are disposable and your state isn't.

⁠Storing data in a specific host directory

To keep the data at a fixed path on the host (easy to find, easy to back up), bind-mount an absolute directory instead of the relative ./data:

# docker-compose.yml — data lives in /srv/oxitick/data on the host
services:
  oxitick:
    image: oxisoft/oxitick:latest
    ports:
      - "15773:15773"
    volumes:
      - /srv/oxitick/data:/app/data
    environment:
      - ADMIN_USERNAME=admin
      - ADMIN_PASSWORD=change-me-min-8-chars
    restart: unless-stopped

The container runs as a non-root user (UID 1000), so the host directory must be writable by it:

sudo mkdir -p /srv/oxitick/data
sudo chown -R 1000:1000 /srv/oxitick/data

Backing up is then just copying /srv/oxitick/data (stop the container first, or use SQLite's .backup, so the database isn't copied mid-write).

Alternatively, a named volume (- oxitick_data:/app/data plus a top-level volumes: {oxitick_data:}) lets Docker manage the location and permissions for you — best when you don't care where the files physically live.

⁠Health & version

GET /health → {"status":"ok","service":"oxitick","version":"v1.2.3"} — the running version is also shown on the admin dashboard.

⁠HTTPS

The container serves plain HTTP; run it behind your reverse proxy of choice. Self-contained automatic HTTPS with a DOMAIN variable works well with a Caddy sidecar:

services:
  oxitick:
    image: oxisoft/oxitick:latest
    volumes: [ "./data:/app/data" ]
    restart: unless-stopped
  caddy:
    image: caddy:2
    ports: [ "80:80", "443:443" ]
    environment: [ "DOMAIN=${DOMAIN}" ]
    volumes:
      - caddy_data:/data
      - ./Caddyfile:/etc/caddy/Caddyfile
    restart: unless-stopped
volumes:
  caddy_data:
# Caddyfile
{$DOMAIN} {
    reverse_proxy oxitick:15773
}

DNS for DOMAIN must point at the host and ports 80/443 must be reachable; certificates are obtained and renewed automatically.

⁠Tags

  • latest — most recent release
  • X.Y.Z — exact release (recommended for production)
  • X.Y — latest patch of a minor line

Made by OxiSoft⁠ · App website: oxitick.com⁠

Tag summary

Content type

Image

Digest

sha256:692617824…

Size

24.4 MB

Last updated

8 days ago

docker pull oxisoft/oxitick