Skip to content

Repository files navigation

Centauri

A Phoenix 1.8 web app for browsing and managing your GitHub starred repositories with pagination included. Sign in with GitHub OAuth, sync your stars into a local cache, and browse them with search, language filter, sort, etc. in a LiveView UI. More features are planned, but the current version is already useful for personal star management with a better browsing experience than GitHub's own starred-repos page.

Status: v0.1.0 — This is an early release. The app is functional and useful, but the UI and feature set are still evolving. Please report any bugs or feature requests via GitHub Issues, thank you :)

Features

  • GitHub OAuth sign-in — no password to manage, the user's GitHub identity and OAuth token are reused for the sync API call
  • One-click sync — pull every starred repo into a local cache so the UI stays fast and works offline against your data
  • Search across name, description, and language
  • Filter by language with a dropdown populated from your actual stars
  • Sort by recently-starred, oldest-starred, name, or repo star count
  • URL-driven state — every filter, page, and per-page value is in the query string so views are shareable and browser-navigable
  • Light / dark theme with system preference detection
  • Streaming repo grid for fast first paint and incremental updates

Tech stack

  • Elixir ~> 1.20
  • Phoenix 1.8
  • Phoenix LiveView 1.1
  • Ecto with SQLite across dev, test, and production (single-user, sync-on-demand workload. SQLite handles it comfortably and keeps hosting costs near zero)
  • daisyUI on top of Tailwind CSS 4
  • Ueberauth + ueberauth_github for OAuth
  • Req for HTTP requests to the GitHub API

Quick start (self-hosted via Docker)

The fastest way to run Centauri is with the prebuilt image from GitHub Container Registry.

1. Create a GitHub OAuth app

Go to https://github.com/settings/developers and create a new OAuth app with this callback URL for now:

http://localhost:8080/auth/github/callback

Note the Client ID and generate a Client secret. You can optionally add a second callback URL when you have a public hostname.

2. Get the compose stack

mkdir centauri && cd centauri
curl -fsSL https://raw.githubusercontent.com/mdi48/centauri/main/docker-compose.yml > docker-compose.yml
curl -fsSL https://raw.githubusercontent.com/mdi48/centauri/main/.env.example > .env

Open .env and fill in GITHUB_CLIENT_ID and GITHUB_CLIENT_SECRET.

3. Start it

docker compose up -d

Open http://localhost:8080, sign in with GitHub, and click Sync.

The data lives in a Docker named volume called centauri_data (SQLite database at /data/centauri_prod.db plus the auto-generated /data/secret_key_base). To inspect it:

docker compose exec centauri ls -la /data

4. Expose it to the internet (optional)

For a public deployment, add a second callback URL to your GitHub OAuth app pointing at your real hostname:

https://your-host.example.com/auth/github/callback

Then set PHX_HOST=your-host.example.com in .env and restart:

docker compose up -d

It goes without saying that putting Centauri behind a reverse proxy (Caddy, Nginx, Traefik, etc.) is recommended for production so you get TLS termination and a real certificate. The app's GET /health endpoint is suitable for upstream health checks. A more detailed reverse-proxy guide is on the roadmap.

Upgrading

docker compose pull
docker compose up -d

Migrations run automatically on the next start (a one-shot migrate service runs before the app service).

Configuration

All runtime configuration is via environment variables, mostly set in .env.

Variable Required Default Purpose
GITHUB_CLIENT_ID yes GitHub OAuth client id
GITHUB_CLIENT_SECRET yes GitHub OAuth client secret
PHX_HOST no localhost Public hostname, no scheme/port. Used for OAuth callback URLs and force_ssl.
CENTAURI_HTTP_PORT no 8080 Host port mapped to the container's port 4000.
DATABASE_PATH no /data/centauri_prod.db SQLite file path inside the container.
SECRET_KEY_BASE no auto Phoenix secret key. If unset, a random one is generated and persisted to /data/secret_key_base on first run.
PORT no 4000 Internal HTTP port. Don't change unless you also update the port mapping.
POOL_SIZE no 10 Repo connection pool size.

DEV_GITHUB_CLIENT_ID / DEV_GITHUB_CLIENT_SECRET are used by local development via mix phx.server and the dev Docker compose stack — see the sections below.

Local development (without Docker)

  1. Install Elixir and Erlang. The ELIXIR_VERSION and OTP_VERSION args at the top of Dockerfile are the canonical versions.

  2. Clone and bootstrap:

    git clone <this-repo>
    cd centauri
    mix setup
    

    mix setup is an alias that runs deps.get, ecto.setup (creates and migrates the dev SQLite DB), assets.setup, and assets.build.

  3. Create a .env file in the project root with your GitHub OAuth dev credentials:

    cp .env.example .env
    # then edit .env and fill in DEV_GITHUB_CLIENT_ID / DEV_GITHUB_CLIENT_SECRET
    

    config/runtime.exs auto-loads .env on mix phx.server start. The same .env also drives the local Docker dev stack — see "Local development (with Docker)" below.

  4. Start the server:

    mix phx.server
    

    Open http://localhost:4000 and click "Continue with GitHub".

Local development (with Docker)

To exercise the same image the production stack uses, but built from your local checkout:

docker compose -f docker-compose.dev.yml up -d --build

This builds the image from the local Dockerfile, tags it centauri:dev, and starts a stack with a separate centauri_dev_data volume so it won't clobber the production stack.

The dev stack reads DEV_GITHUB_CLIENT_ID / DEV_GITHUB_CLIENT_SECRET from your .env (the same vars mix phx.server uses) and maps them onto the container's GITHUB_CLIENT_ID / GITHUB_CLIENT_SECRET. If DEV_* are unset they default to dummy, so migrations and the health endpoint still boot for a smoke test — to exercise the full OAuth flow, fill them in .env.

Database

  • SQLite across all environments. Dev and test use a file at the project root (centauri_dev.db, centauri_test.db); the Docker stack uses a file on the centauri_data named volume at /data/centauri_prod.db. The adapter is pinned at compile time in lib/centauri/repo.ex to Ecto.Adapters.SQLite3 — no environment-specific adapter switch.

All migrations in priv/repo/migrations/ are append-only. To drop a column or table that the app no longer uses, write a new migration that drops it.

Running tests

mix test

Or for a single file:

mix test test/centauri_web/live/stars_test.exs

To re-run only the previously-failed tests:

mix test --failed

Linting and pre-commit

mix precommit

This alias runs compile --warnings-as-errors, deps.unlock --unused, format, and test in sequence. Run it before opening a PR.

Project structure

lib/
  centauri/             # domain contexts
    accounts.ex         # user upsert + get_user
    accounts/user.ex
    github.ex           # thin client over the GitHub REST API
    stars.ex            # starred-repo queries and sync
    stars/starred_repo.ex
    repo.ex
    application.ex      # supervision tree (Repo, TaskSupervisor, Endpoint)
  centauri_web/         # web layer
    controllers/        # AuthController, HealthController
    live/               # LoginLive, StarsLive
    components/         # CoreComponents, Layouts
    plugs/              # session-loading + require_auth
    router.ex
    endpoint.ex
config/                 # per-env + runtime config
priv/repo/migrations/   # append-only DB migrations
assets/                 # JS / CSS / vendor (daisyUI, heroicons)
test/                   # ExUnit cases
docker-compose.yml      # end-user self-hosted stack
docker-compose.dev.yml  # local Docker-from-source stack
.github/workflows/      # CI for GHCR image publish

For the conventions a contributor should follow, see AGENTS.md (architecture, auth flow, background-task pattern, daisyUI usage, etc.).

Contributing

  1. Fork & branch from main.
  2. Make your changes. Keep mix precommit green.
  3. Read AGENTS.md for the project-specific conventions.
  4. Open a PR with a clear description of the change.

Bug reports and feature requests are welcome via GitHub Issues :)

License

GNU Affero General Public License v3.0 — see LICENSE.

About

A GitHub pagination web app

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages