Skip to content

Repository files navigation

Meteor History

Meteor History

Build Release Docker

Node.js React Vite Express

SVG Cards Theme Storage Sync Security

Meteor History is a self-hosted GitHub repository gallery and SVG card service. It synchronizes repository and profile data on a schedule, stores star history as persistent JSON, and provides copyable image URLs and Markdown for project README files.

text1

Deployment

Cloudflare Workers

Deploy to Cloudflare

The deployment flow creates a Worker, provisions a KV namespace for persistent JSON data, uploads the frontend as Workers Static Assets, and configures scheduled background synchronization. Enter the following secrets when Cloudflare asks for bindings:

  • GITHUB_TOKEN: a fine-grained GitHub token with only Metadata → Read-only access.
  • EMBED_SIGNING_KEY: a unique random value containing at least 32 characters.

PUBLIC_BASE_URL is optional. Leave it empty to generate links from the Worker request origin; image hotlink protection is then forced off. When it is set, EMBED_HOTLINK_PROTECTION can be enabled and EMBED_ALLOWED_HOSTS can be customized in the Worker variables.

The deploy command starts the initial repository synchronization as soon as Wrangler publishes the Worker and waits briefly for its result. The Cron Trigger also checks every minute and performs synchronization only when the six-hour refresh interval has elapsed. If the deployment environment cannot determine the public Worker URL, the first read of a completely empty repository cache starts the same one-time bootstrap as a fallback. All later updates remain schedule-driven.

One-click Linux installation

Run the interactive installer as root:

curl -fsSL https://raw.githubusercontent.com/MengMengCode/Meteor-History/main/deploy.sh | sudo sh

The installer detects x86_64 or ARM64 on Linux with glibc 2.28 or later, downloads the matching self-contained runtime from the latest GitHub Release, verifies its SHA-256 checksum, and installs a systemd or OpenRC service. Node.js and Docker are not required on the host. It asks for the fine-grained GitHub token and an optional public HTTPS URL. If a public URL is configured, it also asks whether image hotlink protection should be enabled for GitHub and the deployment site. The token is stored in a root-only environment file and is never added to the command line.

When hotlink protection is enabled, SVG requests carrying a Referer are accepted only from GitHub hosts or the deployment itself. Same-origin previews on the web interface continue to work. Requests without a Referer remain available for GitHub's image proxy, while signed URLs and per-client rate limiting reduce abuse.

Leaving the public URL empty makes generated links use the current request origin and automatically disables image hotlink protection.

When provided, the public URL must point to the server through a trusted HTTPS reverse proxy. The one-click service listens on 127.0.0.1:8666 so the application port is not exposed directly.

After installation, open the management menu with:

meteor-history

The menu can change the GitHub token, update to the latest Release, or uninstall the service. The same actions are also available directly:

meteor-history key
meteor-history update
meteor-history uninstall

Docker image

Create a compose.yaml file. Replace the required token and signing key before starting it; every adjustable setting is documented beside the value:

name: meteor-history # Compose project name

services:
  meteor-history:
    image: ghcr.io/mengmengcode/meteor-history:latest # Image tag; pin a release tag for reproducible deployments
    container_name: meteor-history # Container name shown by Docker
    restart: unless-stopped # Restart policy
    ports:
      - "8666:8666" # Host port:container port
    volumes:
      - meteor-history-cache:/app/.cache # Persistent repository and star-history JSON
    environment:
      GITHUB_TOKEN: "github_pat_xxx" # Required: fine-grained token with Metadata read access
      EMBED_SIGNING_KEY: "replace-with-at-least-32-random-characters" # Required: signs image URLs
      PUBLIC_BASE_URL: "" # Optional: public HTTPS origin; empty uses the request origin and disables hotlink protection
      PORT: "8666" # Internal HTTP port
      CACHE_TTL_MINUTES: "360" # Minutes before cached JSON is considered stale
      REFRESH_INTERVAL_MINUTES: "360" # Minutes between scheduled GitHub synchronization runs
      EMBED_RATE_LIMIT_PER_MINUTE: "120" # SVG requests allowed per client each minute
      API_RATE_LIMIT_PER_MINUTE: "240" # JSON API requests allowed per client each minute
      EMBED_HOTLINK_PROTECTION: "false" # Enable only when PUBLIC_BASE_URL is configured
      EMBED_ALLOWED_HOSTS: "github.com,*.githubusercontent.com,*.github.io" # Allowed Referer hosts when protection is enabled
      TRUST_PROXY: "false" # Set true only behind a trusted reverse proxy
      INCLUDE_PRIVATE_REPOSITORIES: "false" # Keep false for public deployments

volumes:
  meteor-history-cache: # Docker-managed persistent volume

Start the deployment from the directory containing the file:

docker compose up -d

The application listens on port 8666. Generated JSON is stored in the meteor-history-cache Docker volume.

To update an existing Docker deployment, pull and recreate the container. The named cache volume is preserved:

docker compose pull
docker compose up -d --force-recreate

Build from source

Clone the repository:

git clone https://github.com/MengMengCode/meteor-history.git
cd meteor-history

Create and configure the environment file:

cp .env.example .env

Set GITHUB_TOKEN, EMBED_SIGNING_KEY, and PUBLIC_BASE_URL in .env, then build and start the service:

docker compose up -d --build

Check the container status:

docker compose ps

Environment variables

Variable Required Default Description
GITHUB_TOKEN Yes None GitHub token used by scheduled background synchronization.
EMBED_SIGNING_KEY Yes None Secret used to sign image URLs. It must contain at least 32 characters.
PUBLIC_BASE_URL No Request origin Public HTTPS origin used in generated image URLs and Markdown.
CACHE_DIR No .cache Directory used for persistent repository and star history JSON.
HOST No 0.0.0.0 Network interface used by the application listener.
PORT No 8666 in Docker Application port inside the container.
HOST_PORT No 8666 Host port used by compose.yaml.
METEOR_IMAGE No GHCR latest image Container image used by compose.yaml.
CACHE_TTL_MINUTES No 360 Time before cached JSON is considered stale.
REFRESH_INTERVAL_MINUTES No 360 Interval between scheduled GitHub synchronization runs.
GITHUB_API_VERSION No 2026-03-10 GitHub REST API version used by the server.
EMBED_RATE_LIMIT_PER_MINUTE No 120 Maximum SVG requests per client each minute.
API_RATE_LIMIT_PER_MINUTE No 240 Maximum JSON API requests per client each minute.
EMBED_HOTLINK_PROTECTION No true Enables Referer validation for SVG image endpoints.
EMBED_ALLOWED_HOSTS No GitHub hosts Comma-separated Referer allowlist for SVG images.
TRUST_PROXY No false Trusts the first reverse proxy hop when enabled.
INCLUDE_PRIVATE_REPOSITORIES No false Includes private repository metadata and charts when enabled.

GitHub token setup

  1. Create a token on GitHub.
  2. Option A (Fine-grained Personal Access Token):
    • Resource owner: your user account or organization.
    • Repository access: All repositories or selected repositories.
    • Repository permissions: Grant Metadata → Read-only AND Contents → Read and write.
  3. Option B (Classic Personal Access Token):
    • Grant the public_repo (or repo) scope.

Note

Since GitHub restricted the stargazers API in July 2026, reading timestamped star history requires the token to have Contents: Read and write permissions (for fine-grained PAT) or the public_repo scope (for classic PAT), and the token owner must be a repository administrator or collaborator.

Features

Area What Meteor History provides
Repository gallery Displays repositories from the configured GitHub account with star and fork counts, descriptions, and repository detail dialogs.
Star history Generates cumulative Star History-style SVG charts from scheduled GitHub stargazer synchronization.
Profile cards Generates GitHub Readme Stats-style profile cards with contribution statistics and rank information.
Customization Supports multiple chart styles, custom colors, dimensions, line width, labels, markers, and light, dark, or automatic themes.
Sharing Provides independent image URLs and ready-to-copy Markdown for repository charts and profile cards.
Data storage Stores repository indexes, profile statistics, and star histories as JSON in a persistent cache directory.
Background jobs Synchronizes data automatically on the configured interval without visitor-triggered GitHub requests.
Security Includes signed image URLs, Referer controls, request rate limits, private repository filtering, security headers, and redacted server errors.

Technology stack

  • Frontend: React 19, Vite 8, Lucide React, Inter, and the xkcd font
  • Backend: Node.js 22, Express 5, GitHub REST API, and GitHub GraphQL API
  • Storage: Persistent JSON files under .cache
  • Runtime: Docker or a standard Node.js production environment
  • Automation: GitHub Actions and GitHub Container Registry

Service endpoints

Endpoint Description
/api/health Service status, cache state, and background synchronization status.
/api/repositories Cached repository gallery and GitHub profile data.
/api/history/:owner/:repo Cached repository star history and generated share URLs.
/api/embed/:owner/:repo.svg Repository star history SVG image.
/api/profile/:owner.svg GitHub profile statistics SVG image.

Preview

text2 text3 text4

Meteor-History

MengMengCode/Meteor-History Star History

About

Meteor History is a self-hosted GitHub repository gallery and SVG card service. It synchronizes repository and profile data on a schedule, stores star history as persistent JSON, and provides copyable image URLs and Markdown for project README files.

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages