Skip to main content

stack

Search, identify find the alternative best free software solution, from open source software packages, ready to install via docker compose. Also understands the .stack bundle format, can generate new .stack files, and can run .stack files from URL or local path.

Jump to install

Source facts

Repository
codename-co/stack
Last source activity
June 10, 2026 at 06:36
Detected SKILL.md language
English
Stars
46
Forks
3

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
stack
description
Search, identify find the alternative best free software solution, from open source software packages, ready to install via docker compose. Also understands the .stack bundle format, can generate new .stack files, and can run .stack files from URL or local path.
metadata
{"author":"Arnaud Leymet","version":"0.2.0"}
# Stack [stack.lol](https://stack.lol) is a curated catalog of open-source, self-hostable software packages — every entry ships a ready-to-use Docker Compose file. Use this skill whenever a user asks about open-source alternatives, wants to self-host something, needs a Docker Compose setup for a specific tool, or wants to understand, generate, or run `.stack` bundle files. --- ## The .stack bundle format A `.stack` file is a **gzip-compressed tar archive** (`.tar.gz` with a `.stack` extension). It is a self-contained bundle that packages everything needed to run a software stack. ### File structure ``` <name>.stack ← gzip-compressed tar archive ├── stack.yaml ← metadata (required) ├── compose.yaml ← Docker Compose definition (for DockerCompose flavor) ├── .env ← primary environment variables ├── <name>.env ← extra env files (optional, e.g. .apiserver.env) └── config/ ← auxiliary config files (optional) ├── settings.yml └── ... ``` For **StaticWebsite** flavor stacks (no Docker Compose), the archive contains: ``` <name>.stack ├── stack.yaml ├── index.html ├── js/ ├── style/ └── ... ``` For **recipe** bundles (multi-stack combinations), the archive includes nested stacks: ``` <name>.stack ├── stack.yaml ├── compose.yaml ← uses `include:` referencing ./stacks/*/compose.yaml ├── .env └── stacks/ ├── openwebui/ │ ├── stack.yaml │ ├── compose.yaml │ └── .env ├── ollama/ │ ├── stack.yaml │ ├── compose.yaml │ └── .env └── ... ``` ### stack.yaml schema The metadata file follows the schema at `https://stack.lol/schemas/stack.config.schema.yaml`: ```yaml # yaml-language-server: $schema=https://stack.lol/schemas/stack.config.schema.yaml slug: myapp # required — unique identifier (lowercase, hyphens) name: My App # required — display name icon: 🚀 # optional — emoji icon flavor: DockerCompose # required — one of: DockerCompose, DockerService, StaticWebsite version: "1.0.0" # required — version string updated_at: 2026-06-09 # optional — YYYY-MM-DD description: Short description # required — brief description author: Author Name # required — author or organization license: MIT # required — SPDX identifier or URL homepage: https://example.com # optional — product homepage URL repository: https://github.com/... # optional — source code URL stars: 1000 # optional — GitHub stars count tags: # optional — category tags - self-hosted - web alternativeTo: # optional — proprietary tools this replaces - some-tool status: working # optional — one of: untested, broken, starting, working type: stack # optional — "stack" or "recipe" dependencies: # optional — for recipes only - name: openwebui role: Web interface readme: | # optional — markdown description Detailed description here... i18n: # optional — translations fr: description: Description en français ``` ### Flavors | Flavor | Detection | How it runs | |---|---|---| | `DockerCompose` | `compose.yaml` or `docker-compose.yaml` present | `docker compose up -d --wait --remove-orphans` | | `DockerService` | `Dockerfile` present | `docker build` then `docker run` | | `StaticWebsite` | `index.html` present | Served via `nginx:stable-alpine` container | ### compose.yaml conventions Stack compose files follow these conventions: - **Labels** for service discovery: ```yaml labels: dash.url: https://$PROJECT.$DOMAIN traefik.http.routers.<name>.rule: Host(`$PROJECT.$DOMAIN`) traefik.http.services.<name>.loadbalancer.server.port: 8080 ``` - **Environment variables** use `$PROJECT` and `$DOMAIN` (defined in `.env`) - **`.env` always defines** at minimum: `PROJECT=<slug>` and `DOMAIN=stack.localhost` - **Volumes** use named Docker volumes (not bind mounts) for persistent data - **Networks** are stack-scoped (non-external) ### Download URLs Pre-built `.stack` files are available at: - Stacks: `https://stack.lol/downloads/{slug}.stack` - Recipes: `https://stack.lol/downloads/recipes/{slug}.stack` --- ## API Reference ### Endpoints | Endpoint | Method | Description | |---|---|---| | `https://stack.lol/api/stacks` | GET | All individual stacks (201 entries) | | `https://stack.lol/api/recipes` | GET | Curated multi-stack combinations | Both endpoints return `{ items: Stack[] }`. No authentication required. ### Stack object shape ```json { "slug": "plane", "name": "Plane", "version": "1.2.2", "updated_at": "2026-02-28T00:00:00.000Z", "description": "Issue tracking and project management", "license": "AGPL-3.0", "tags": ["issue-tracking", "project-management"], "alternativeTo": ["jira", "asana", "linear", "monday"], "link": "/plane", "stars": 46000 } ``` Key fields: - **`slug`** — unique identifier; also the path key for compose files - **`alternativeTo`** — array of well-known proprietary/popular tools this stack replaces (lowercase slugs, e.g. `"jira"`, `"notion"`, `"github"`) - **`tags`** — 131 unique category tags (e.g. `"issue-tracking"`, `"ai"`, `"wiki"`, `"crm"`) - **`stars`** — GitHub stars (use as a popularity/trust signal) - **`link`** — relative URL; prefixed with `/recipes/` for recipe entries ### Companion file URLs All files for a stack live under the same base URL: ``` # Base (stack) https://raw.githubusercontent.com/codename-co/stack/main/hub/{slug}/ # Base (recipe) https://raw.githubusercontent.com/codename-co/stack/main/recipes/{slug}/ ``` Derive the type from the `link` field: if `link` starts with `/recipes/` it is a recipe, otherwise it is a plain stack. The files that may exist under that base: | File | Present | Notes | |---|---|---| | `compose.yaml` | Always | Main Docker Compose definition | | `.env` | ~95% of stacks | Primary environment variables | | `<name>.env` | Occasional | Extra env files (e.g. `.apiserver.env`, `.db.env`, `settings.env`) | | `config/<file>` | ~10 stacks | Auxiliary config files (YAML, TOML, nginx.conf, etc.) | **Do not guess which companion files exist** — discover them by parsing `compose.yaml` (see below). ### Discovering companion files from compose.yaml After fetching `compose.yaml`, scan it for three patterns: 1. **`env_file:` entries** — each value that does not start with `/` is a relative companion file. ```yaml env_file: .env # → fetch .env env_file: .apiserver.env # → fetch .apiserver.env ``` 2. **`volumes:` local-source mounts** — entries of the form `./local/path:/container/path` where the source starts with `./` are local files/dirs bundled with the stack. ```yaml volumes: - ./config/limiter.toml:/etc/searxng/limiter.toml:ro # → fetch config/limiter.toml - ./config/uwsgi.ini:/etc/searxng/uwsgi.ini:ro # → fetch config/uwsgi.ini ``` 3. **Top-level `configs:` blocks** — two sub-cases: - `content: |` — config is **inline** in compose.yaml; no extra fetch needed, content is already present. - `file: ./path` — config references an external local file; fetch it. For each discovered path, fetch: ``` https://raw.githubusercontent.com/codename-co/stack/main/hub/{slug}/{relative_path} ``` Always attempt to fetch `.env` even if not explicitly listed in `env_file:` — it is the default and present in ~95% of stacks. A 404 simply means that stack has no `.env`. --- ## Use case 1 — Find the best open-source alternative to a specific tool **Trigger phrases:** "alternative to Jira", "self-hosted Notion", "open-source Slack", "replace GitHub", "free alternative to …" ### Procedure 1. `GET https://stack.lol/api/stacks` — fetch the full catalog. 2. Normalize the target tool name to a likely slug (lowercase, spaces → hyphens, strip punctuation). Example: `"Jira"` → `"jira"`. 3. Filter items where `alternativeTo` array **contains** the target slug (case-insensitive). 4. If zero results, also search `https://stack.lol/api/recipes` with the same filter. 5. Sort surviving entries by `stars` descending. 6. Present the top candidates in a comparison table. ### Output format | Tool | Description | License | Stars | Tags | Install | |---|---|---|---|---|---| | **Plane** | Issue tracking and project management | AGPL-3.0 | ⭐ 46k | issue-tracking, project-management | `https://stack.lol/plane` | | **Taiga** | Agile project management platform | MPL-2.0 | ⭐ 17k | issue-tracking, agile | `https://stack.lol/taiga` | Follow the table with a brief recommendation paragraph: highlight the closest feature match, the most active project (stars + `updated_at`), and any notable license caveats. ### Example User: *"What's the best open-source alternative to Jira?"* 1. Fetch `https://stack.lol/api/stacks`. 2. Filter `alternativeTo` ∋ `"jira"`. 3. Sort by stars → Plane (46k ⭐), Taiga (17k ⭐), Linear-alikes, … 4. Return comparison table + recommendation. --- ## Use case 2 — Metadata and Docker Compose for a specific stack **Trigger phrases:** "how do I self-host Plane", "docker compose for Gitea", "deploy Nextcloud", "what's in the Plane stack", "show me the compose file for …" ### Procedure 1. `GET https://stack.lol/api/stacks` — fetch the full catalog. 2. Find the matching entry: exact `slug` match first, then case-insensitive `name` match. 3. If not found in stacks, try `GET https://stack.lol/api/recipes`. 4. Determine base URL: - Stack: `https://raw.githubusercontent.com/codename-co/stack/main/hub/{slug}/` - Recipe: `https://raw.githubusercontent.com/codename-co/stack/main/recipes/{slug}/` 5. Fetch `compose.yaml` from the base URL. 6. Parse `compose.yaml` to discover companion files (see **Discovering companion files** above). 7. Fetch `.env` unconditionally (ignore 404). 8. Fetch every other companion file discovered in step 6. 9. Present: metadata card → compose.yaml → companion files. ### Output format **Metadata card** (always show first): ``` 📦 Plane v1.2.2 Issue tracking and project management License : AGPL-3.0 Stars : ⭐ 46,000 Tags : issue-tracking · project-management Also an alternative to: Jira · Asana · Linear · Monday Updated : 2026-02-28 Detail : https://stack.lol/plane ``` **Docker Compose file** (show in a fenced code block): ```yaml # contents of compose.yaml … ``` **Companion files** — show each one in its own labeled fenced block: ``` # .env POSTGRES_USER=plane … ``` ``` # .apiserver.env (if present) SECRET_KEY=secret … ``` ```yaml # config/limiter.toml (if present) … ``` Label each block with the relative filename so the user knows exactly where to place it. After all files, provide a brief **"Getting started"** note pointing to `https://stack.lol/{slug}` for full setup instructions. ### Example User: *"Show me the metadata and docker compose for Plane."* 1. Fetch `/api/stacks`, find `slug: "plane"`. 2. Base URL → `https://raw.githubusercontent.com/codename-co/stack/main/hub/plane/` 3. Fetch `compose.yaml` → parse → discover `env_file: .env` and `env_file: .apiserver.env`. 4. Fetch `.env` and `.apiserver.env`. 5. Render: metadata card + `compose.yaml` + `.env` + `.apiserver.env`. --- ## Use case 3 — Browse by category / tag **Trigger phrases:** "what self-hosted CRM tools are available", "show me open-source monitoring stacks", "any AI tools on stack.lol" ### Procedure 1. `GET https://stack.lol/api/stacks` (+ `/api/recipes` if relevant). 2. Filter items where `tags` contains the requested category tag. 3. Sort by `stars` descending; cap display at 10 results. 4. Present as a table (same format as use case 1, omitting the "Install" column). **Common tag → user intent mapping** (not exhaustive): | User says | Tag(s) to match | |---|---| | CRM | `crm` | | monitoring / observability | `monitoring`, `observability` |
View on GitHub
This SKILL.md is very large, so SkillsMP previews the first section here. View on GitHub