Open source · AGPL-3.0

Your cycle. Your data. Your self-hosted period tracker.

An open source self-hosted menstrual cycle tracker you can run with one Docker command. Browser UI, phone home-screen install, portable export, and no ads or third-party trackers.

Go · SQLite by default · Docker · amd64 · arm64 · Latest v0.8.5
self-hosted ovumcy-web
Latest v0.8.5
Follicular · Cycle day 6 · Next period: Apr 3, 2026 - Apr 11, 2026 · Ovulation: Mar 23, 2026
Today journal March 15, 2026, Sunday
Period day
Symptoms
Cramps Headache Mood swings Bloating Breast tenderness Acne
Mood
Notes
Mild cramps today, otherwise feeling good.

Why this self-hosted period tracker fits real ops.

Self-hosted control without giving up the practical parts: predictions, export, phone install, and a supported path from simple SQLite setups to more advanced operator workflows.

Zero-knowledge default

Your health data never leaves your infrastructure. No telemetry, no call-home, no third-party services.

Browser and home install

Use the server-rendered web app in any browser or install it to a phone home screen without changing the self-hosted model.

Portable export

CSV, JSON, and PDF export keep your records usable for backup, migration, and personal review instead of trapping them in one setup.

SQLite first, Postgres later

SQLite is the supported baseline. There is also an official Postgres path for more advanced self-hosted deployments.

Five UI languages

English, Russian, Spanish, French, and German are already supported, with operator defaults and user-side switching in the app.

Docker or one Go binary

Start with the container path for the easy install, or run the application directly if a binary-based deployment fits your environment better.

Resource footprint

Operators usually want to know whether a small VPS or NAS is enough before they deploy. We measured the supported SQLite baseline locally and kept the numbers tied to a real owner flow instead of a cold-start-only demo.

Measured amd64 baseline

Small by default, honest about real use.

The local Docker baseline measured about 51 MB for the image. After registration, onboarding, dashboard save, calendar edits, stats, and export on SQLite, the container settled around 50 MiB RAM on the test machine.

Image ~51 MB Post-flow idle ~50 MiB RAM SQLite baseline

No sidecar stack required

The supported self-host path stays intentionally narrow: one Go service, SQLite by default, and no Redis, queue workers, or object storage required for the baseline setup.

arm64 compatibility was checked too

arm64 images also built and booted locally under emulation, and the same owner flow plus CSV, JSON, and PDF export passed there too. Treat that result as compatibility validation, not native hardware sizing.

For people who verify first.

If you are putting health software on your own server, you should be able to inspect the repository, release history, and license before you run a single command.

Built in the open

Review the repo before you deploy.

The self-host path stays inspectable: public source, visible releases, and a clear license before anything touches your server.

16 releases Latest v0.8.5 AGPL-3.0
Open repository →

Open source under AGPL-3.0

Read it, audit it, fork it, and keep the self-host path real instead of hidden behind a managed-only product story.

Docs you can verify

The source, deployment instructions, and container image references stay public before you install anything on your own infrastructure.

Browser, home screen, your server.

ovumcy-web runs as a single Go service. Open it in any browser or install it to a phone home screen today, while your data stays on your own server the whole time.

If you want the dedicated local-first mobile app, use ovumcy.app today. Self-hosted web stays the browser and installable-home-screen path on your own server.

If your home server lives behind Portainer, Unraid, or Synology Container Manager, start from the same Docker-first baseline and add Postgres, OIDC, or a richer proxy setup only when your operator needs actually grow into them.

Client surface Browser or phone home screen Server-rendered UI today, installable on a phone without changing the self-hosted model.
Desktop browser Mobile browser Home-screen install
HTTPS / private network
Application Your Ovumcy server One Go service behind your proxy, with /healthz and a narrow trusted-proxy contract.
Docker or one binary Port 8080 Trust proxy only when needed
Storage / identity
Operator options SQLite first, Postgres and OIDC later Start with the narrow baseline, then add reverse proxy, Postgres, or OIDC only when you truly need them.
SQLite baseline Postgres examples Caddy / Nginx / OIDC

Self-hosted period tracker Docker quick start.

Pull the tagged base compose path, set one secret, verify /healthz, and only then move to the dedicated proxy examples for public HTTPS.

Download the tagged base compose files.
mkdir -p ovumcy && cd ovumcy
curl -fsSL -o docker-compose.yml \
  https://raw.githubusercontent.com/ovumcy/ovumcy-web/v0.8.5/docker-compose.yml
curl -fsSL -o .env \
  https://raw.githubusercontent.com/ovumcy/ovumcy-web/v0.8.5/.env.example

# edit .env once:
# - set SECRET_KEY to a long random value
# - keep OVUMCY_IMAGE=ghcr.io/ovumcy/ovumcy-web:v0.8.5

docker compose up -d
docker compose ps
curl -fsS http://127.0.0.1:8080/healthz

This path stays release-pinned: both downloaded files and the default OVUMCY_IMAGE inside the compose file point at v0.8.5.

Compose excerpt worth reading before you run it.
services:
  ovumcy:
    image: ${OVUMCY_IMAGE:-ghcr.io/ovumcy/ovumcy-web:v0.8.5}
    read_only: true
    tmpfs:
      - /tmp
    volumes:
      - ovumcy_data:/app/data
    ports:
      - "${HOST_BIND_ADDRESS:-127.0.0.1}:${PORT:-8080}:${PORT:-8080}"

The baseline bind stays on 127.0.0.1. For public HTTPS, move to the dedicated reverse-proxy stacks instead of exposing 8080 directly.

Run it safely in production.

The official self-hosted path is intentionally narrow: HTTPS at the edge, persistent storage, a strong secret, and only the reverse proxy exposed to the public internet.

Official Caddy baseline Nginx example →
ovumcy.example.com {
    encode zstd gzip
    reverse_proxy ovumcy:8080
}

This is the upstream Caddyfile. Use the dedicated proxy stacks so only the proxy publishes 80/443 and the app stays private on the internal network.

Routine upgrade path
docker compose pull
docker compose up -d
docker compose ps
curl -fsS http://127.0.0.1:8080/healthz

Back up the database before every version change, then verify the container is healthy before trusting the rollout.

Required env baseline

Before public HTTPS, set a strong SECRET_KEY or SECRET_KEY_FILE, keep persistent data at /app/data, and switch to COOKIE_SECURE=true behind TLS.

Persistent data and backups

Back up the SQLite volume before upgrades, keep rollback copies, and store .env plus the application secret separately from the database archive.

Trust only your own proxy

Enable TRUST_PROXY_ENABLED=true only behind your own reverse proxy and keep TRUSTED_PROXIES limited to the exact proxy IPs or subnet you control.

Prefer managed hosting?

If you want the same privacy stance without running your own server, Cloud handles backups, updates, and everyday continuity for you.

Managed path

Ovumcy Cloud

EU hosting, automatic updates, daily backups, and no server maintenance on your side.

Choose Cloud when you want the same product with continuity handled for you, not by your own infrastructure.

Open Cloud
What Cloud takes off your plate
  • EU hosting for the managed path
  • Automatic updates handled for you
  • Daily backups on the hosted side
  • No server maintenance on your side