{"id":31588645,"url":"https://github.com/willc33/ambrosia","last_synced_at":"2025-10-29T18:05:24.329Z","repository":{"id":310205157,"uuid":"1039071363","full_name":"WillC33/ambrosia","owner":"WillC33","description":" Ambrosia is a containerised BEAM based server for gemini capsules, that provides easy to use and configure defaults for users looking to self-host on the Geminispace","archived":false,"fork":false,"pushed_at":"2025-09-24T15:31:58.000Z","size":65,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-09-24T17:43:08.533Z","etag":null,"topics":["elixir","gemini","gemini-protocol","server"],"latest_commit_sha":null,"homepage":"","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/WillC33.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-08-16T12:21:14.000Z","updated_at":"2025-09-24T15:32:02.000Z","dependencies_parsed_at":"2025-08-16T14:32:42.131Z","dependency_job_id":"af571906-0555-460b-9baa-22a1b3bae567","html_url":"https://github.com/WillC33/ambrosia","commit_stats":null,"previous_names":["willc33/ambrosia"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/WillC33/ambrosia","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WillC33%2Fambrosia","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WillC33%2Fambrosia/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WillC33%2Fambrosia/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WillC33%2Fambrosia/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/WillC33","download_url":"https://codeload.github.com/WillC33/ambrosia/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WillC33%2Fambrosia/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278547821,"owners_count":26004775,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-06T02:00:05.630Z","response_time":65,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["elixir","gemini","gemini-protocol","server"],"created_at":"2025-10-06T02:11:55.803Z","updated_at":"2025-10-06T02:12:12.947Z","avatar_url":"https://github.com/WillC33.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"**⚠️ WARNING: Currently, Ambrosia is preproduction software with known security limitations. \nUse only in trusted environments or for development purposes.**\n\n# 🏛️ Ambrosia\n\nA fault-tolerant, concurrent Gemini protocol server written in Elixir. Built for immortality on the BEAM. Ambrosia is designed for serving high-uptime\nCapsules on the Geminispace.\n\n## What is Ambrosia?\n\nAmbrosia is a Gemini server that leverages the Erlang VM's legendary fault tolerance and concurrency to serve your Gemini capsule. It's designed to be simple to deploy, secure by default, and resilient under load. Whether you're running a personal capsule or hosting multiple sites, Ambrosia keeps serving.\n\n## Features\n\n- **Fault Tolerant**: Built on the BEAM VM with supervision trees - if something crashes, it restarts\n- **Concurrent by Design**: Handles a ton of concurrent connections without breaking a sweat\n- **Docker Ready**: Single container deployment with automatic certificate generation\n- **Monitoring Built-in**: Prometheus metrics endpoint for observability\n- **Minimal Resource Usage**: Runs comfortably on a Raspberry Pi hovering about 75-100MB memory\n- **Gemtext Native**: Serves `.gmi` files with proper MIME types\n- **Directory Listings**: Auto-generates navigable directory indices\n\n## Quick Start\n\n### Using Docker (Recommended)\n\n```bash\n# Create your content directory\nmkdir -p gemini certs\n\n# Create docker-compose.yml (see below)\n# Add your .gmi files to ./gemini/\n\n# Run it\nHOSTNAME=your-domain.com docker-compose up -d\n```\n\nBasic `docker-compose.yml`:\n```yaml\nservices:\n  ambrosia:\n    image: ghcr.io/willc33/ambrosia:latest\n    ports:\n      - \"1965:1965\"\n    volumes:\n      - ./gemini:/app/gemini:ro\n      - ./certs:/certs:ro  # Optional: provide your own certs\n    environment:\n      - HOSTNAME=your-capsule.com\n    restart: unless-stopped\n```\n\nThat's it. Ambrosia will generate self-signed certificates if you don't provide them.\nYou are also welcome to use the compose files in the repository\n\n### From Source\n\n```bash\n# Prerequisites: Elixir 1.15+, Erlang/OTP 25+\ngit clone https://codeberg.org/WillC33/ambrosia.git\ncd ambrosia\n\n# Install dependencies\nmix deps.get\n\n# Generate certificates\nopenssl req -x509 -newkey rsa:2048 -nodes \\\n  -keyout certs/key.pem -out certs/cert.pem \\\n  -days 365 -subj \"/CN=localhost\"\n\n# Run in development\nHOSTNAME=localhost mix run --no-halt\n\n# Or build a release\nMIX_ENV=prod mix release\nHOSTNAME=your-domain.com _build/prod/rel/ambrosia/bin/ambrosia start\n```\n\n## Configuration\n\nEnvironment variables control Ambrosia's behaviour:\n\n| Variable | Default | Description |\n|----------|---------|-------------|\n| `HOSTNAME` | (required in prod) | Your capsule's domain name |\n| `GEMINI_PORT` | 1965 | Port to listen on |\n| `ROOT_DIR` | /app/gemini | Directory containing your .gmi files |\n| `CERT_FILE` | /certs/cert.pem | Path to TLS certificate |\n| `KEY_FILE` | /certs/key.pem | Path to TLS private key |\n| `MAX_CONNECTIONS` | 1000 | Maximum concurrent connections |\n| `REQUEST_TIMEOUT` | 10000 | Request timeout in milliseconds |\n| `RATE_LIMIT_REQUESTS` | 10 | Requests allowed per window |\n| `RATE_LIMIT_WINDOW_MS` | 1000 | Rate limit window duration |\n| `METRICS_ENABLED` | false | Enable internal Prometheus metrics endpoint |\n| `METRICS_PORT` | 9568 | Port for metrics endpoint |\n\n## Content Structure\n\nOrganise your Gemini content like this:\n\n```\ngemini/\n├── index.gmi          # Homepage\n├── about.gmi          # About page\n├── blog/\n│   ├── index.gmi      # Blog index\n│   ├── 2024-01-01.gmi # Blog posts\n│   └── 2024-01-15.gmi\n└── page/\n    ├── index.gmi      # Whatever else pleases you\n    └── ambrosia.gmi   # Other stuff\n```\n\nAmbrosia automatically:\n- Serves `index.gmi` or `index.gemini` for directories\n- Generates directory listings when no index exists\n- Only serves `.gmi` and `.gemini` files (by design)\n- The architecture allows MIME type extension\n\n## Monitoring\n\nEnable Prometheus metrics for production monitoring:\n\n```yaml\nenvironment:\n  - METRICS_ENABLED=true\n  - METRICS_PORT=9568\nports:\n  - \"127.0.0.1:9568:9568\"  # Metrics (localhost only)\n```\n\nAvailable metrics:\n- Active connections\n- Request duration\n- Memory usage\n- Process count\n- Rate limit hits\n\n## Security\n\nAmbrosia takes security seriously:\n\n- **Path Traversal Protection**: Multiple layers of validation prevent directory escapes\n- **Rate Limiting**: Token bucket algorithm prevents abuse\n- **TLS Only**: It's Gemini. No plaintext connections\n- **Input Validation**: URL length limits and sanitisation\n- **Resource Limits**: Connection caps and timeouts\n- **Minimal Attack Surface**: Only serves Gemtext files\n\nThe codebase includes testing against common attack patterns for the file system\n\n## Testing\n\nAmbrosia includes extensive test coverage:\n\n```bash\n# Run all tests\nmix test\n\n# Run with coverage\nmix test --cover\n\n# Security-specific tests\nmix test test/file_server_security_test.exs\n```\n\nTests cover:\n- Path traversal attempts\n- Rate limiting\n- Concurrent connections\n- Request parsing\n- File serving\n- Directory listings\n- Edge cases\n\n## Development\n\n### Architecture\n\nAmbrosia uses OTP supervision trees for fault tolerance:\n\n```\nAmbrosia.Supervisor\n├── Telemetry (Metrics collection)\n├── RateLimiter (Token bucket)\n├── ConnectionManager (Connection tracking)\n├── Ranch Listener (TCP acceptor pool)\n└── MetricsExporter (Prometheus endpoint)\n```\n\nEach connection runs in its own supervised process. If one crashes, others continue serving.\n\n### Contributing\n\nWe welcome contributions! Whether it's:\n- Bug fixes\n- Performance improvements\n- Documentation updates\n- Feature suggestions\n- Security reports\n\nPlease open an issue or PR on [Codeberg](https://codeberg.org/WillC33/ambrosia).\n\nFurther testing, fixes, and features are definitely needed before this is ready to use\n\n## Use Cases\n\nAmbrosia works brilliantly for:\n\n- **Personal Capsules**: Your blog, wiki, or digital garden\n- **Project Documentation**: Minimalist docs that load instantly\n- **Community Spaces**: Shared capsules for groups\n- **Archive Mirrors**: Resilient content hosting\n- **Educational Resources**: Distraction-free learning materials\n- **Creative Writing**: Fiction, poetry, journaling\n\n## Alternatives\n\nThe Gemini ecosystem has several excellent servers. This one exists because I love BEAM, not because the other's aren't great:\n\n- **Agate** (Rust): Excellent performance, minimal dependencies\n- **Molly Brown** (Go): Feature-rich with CGI support\n- **Jetforce** (Python): Great for scripting and extensions\n- **GLV-1.12556** (C): Lightweight and portable\n- **Gemserv** (Rust): Advanced features like virtual hosting\n\nChoose Ambrosia if you value:\n- Erlang's fault tolerance\n- Concurrent connection handling\n- Simple Docker deployment\n- Built-in monitoring\n\n## Thanks\n\nMassive thanks to the Gemini community for creating this wonderful protocol and ecosystem.\nThis project exists because of your collective work towards a better, lighter internet.\n\n## Philosophy\n\nAmbrosia follows the Gemini philosophy:\n- Content over presentation\n- Privacy by default\n- Simplicity as a feature\n- Technical decisions with moral dimensions\n\nWe believe the internet can be different. Gemini proves it.\n\n## Licence\n\nAGPL-3.0 - If you improve Ambrosia, share those improvements with the community.\n\n## Etymology\n\nIn Greek mythology, ambrosia granted immortality to those who consumed it. This server aims for similar resilience - it should run forever, serving your content reliably across time.\n\n---\n\n*Built with love for the small internet.*\n\n*Find me in Geminispace: gemini://gem.williamcooke.net*\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwillc33%2Fambrosia","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwillc33%2Fambrosia","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwillc33%2Fambrosia/lists"}