diff --git a/.github/ISSUE_TEMPLATE/tool-submission.yml b/.github/ISSUE_TEMPLATE/tool-submission.yml new file mode 100644 index 0000000..648ecb8 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/tool-submission.yml @@ -0,0 +1,70 @@ +name: "🚀 New Tool Submission" +description: Suggest a new open-source alternative to be added to The AltStack. +title: "[TOOL]: " +labels: ["enhancement", "tool-request"] +body: + - type: markdown + attributes: + value: | + Thanks for taking the time to suggest a new tool! We appreciate your help in building the Sovereign Infrastructure Engine. + - type: input + id: name + attributes: + label: Tool Name + placeholder: e.g., Supabase + validations: + required: true + - type: input + id: website + attributes: + label: Website URL + placeholder: https://supabase.com + validations: + required: true + - type: input + id: github + attributes: + label: GitHub Repository + placeholder: supabase/supabase + validations: + required: true + - type: dropdown + id: category + attributes: + label: Category + options: + - Backend as a Service + - Analytics + - Communication + - Project Management + - Design + - Productivity + - Security + - DevOps + - Infrastructure + - Other + validations: + required: true + - type: textarea + id: description + attributes: + label: Short Description + placeholder: Why is this tool a great alternative? + validations: + required: true + - type: textarea + id: alternative_to + attributes: + label: Alternative To + placeholder: Which SaaS product does this replace? (e.g., Firebase, Slack) + validations: + required: true + - type: checkboxes + id: checks + attributes: + label: Verification + options: + - label: Is this tool Open Source? + required: true + - label: Is it self-hostable? + required: true diff --git a/.github/workflows/scrape-data.yml b/.github/workflows/scrape-data.yml new file mode 100644 index 0000000..2a4dc33 --- /dev/null +++ b/.github/workflows/scrape-data.yml @@ -0,0 +1,39 @@ +name: Scrape GitHub Data + +on: + schedule: + - cron: '0 0 * * *' # Every day at midnight UTC + workflow_dispatch: # Allow manual trigger + +jobs: + scrape: + runs-on: ubuntu-latest + permissions: + contents: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.10' + + - name: Install dependencies + run: | + if [ -f scraper/requirements.txt ]; then + pip install -r scraper/requirements.txt + fi + + - name: Run scraper + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: python scraper/scraper.py + + - name: Commit and push changes + run: | + git config --global user.name 'github-actions[bot]' + git config --global user.email 'github-actions[bot]@users.noreply.github.com' + git add data/tools.json + git diff --quiet && git diff --staged --quiet || (git commit -m 'chore: nightly data enrichment [skip ci]' && git push) diff --git a/README.md b/README.md index fae007a..a33a698 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,12 @@ Stop paying for what you can host yourself. Build sovereign infrastructure with AltStack.
+ +Explore the Directory • Self-Hosting Guides • @@ -17,9 +23,56 @@ --- -## 🚀 Why This List? +## 🚀 Why Sovereign Infrastructure? -AltStack's mission is to help you own your data and infrastructure. This repository serves as the **Data HQ** for [The AltStack](https://thealtstack.com), powering our searchable directory and self-hosting guides. Every tool listed here is vetted for quality, activity, and self-hostability. +Every SaaS you pay for is a piece of your sovereign control you are leasing. The mission of **AltStack** is to provide the data and deployment configurations necessary to replace the "Big Tech" stack with a **Sovereign Stack** you own. + +This repository serves as the **Data HQ** for [The AltStack](https://thealtstack.com). Every tool listed here is vetted for quality, activity, and self-hostability. + +## 🚀 Quick Start (Mini-Stacks) + +Get up and running in under 2 minutes. These are "Development Mode" snippets. For production-hardened setups (SSL, Backups, Auth), follow the links to The AltStack Documentation. + +### 📦 PocketBase (BaaS) +The fastest way to get a backend with Auth, Database, and Admin UI. +```yaml +# docker-compose.yml +services: + pocketbase: + image: mujo-code/pocketbase:latest + container_name: pocketbase + ports: + - "8090:8080" + volumes: + - ./pb_data:/pb_data + restart: unless-stopped +``` +👉 [Get the Production-Hardened Guide & Best Practices](https://docs.thealtstack.com/deployments/pocketbase) + +### 📊 Plausible Analytics (Privacy-First) +Lightweight, open-source analytics. +```yaml +# docker-compose.yml (Simplified) +services: + plausible: + image: plausible/analytics:latest + ports: + - "8000:8000" + env_file: .env +... +``` +👉 [Full Self-Hosting Guide with ClickHouse Setup](https://docs.thealtstack.com/deployments/plausible) + +--- + +## 🛠️ Browse by Category + +- [🏗️ Backend as a Service](#-backend-as-a-service-baas) → [Compare all on thealtstack.com](https://thealtstack.com/category/backend-as-a-service) +- [💬 Communication](#-communication--collaboration) → [Compare all on thealtstack.com](https://thealtstack.com/category/communication) +- [📊 Analytics & BI](#-analytics--bi) → [Compare all on thealtstack.com](https://thealtstack.com/category/analytics) +- [📁 Project Management](#-project-management) → [Compare all on thealtstack.com](https://thealtstack.com/category/project-management) + +--- ## 📂 The Awesome Alternatives List @@ -96,11 +149,14 @@ AltStack's mission is to help you own your data and infrastructure. This reposit Most tools in this list can be deployed in minutes using Docker. Here is how to get started with the AltStack approach: 1. **Clone this repo**: `git clone https://github.com/altstackHQ/altstack-data.git` -2. **Explore `/deploy-configs`**: Find the Docker Compose file for the tool you want. -3. **Follow the Guide**: Visit [docs.thealtstack.com](https://docs.thealtstack.com) for step-by-step instructions. +2. **Explore `/deployments`**: Find the Docker Compose file for the tool you want. +3. **Go Sovereign**: Visit [docs.thealtstack.com](https://docs.thealtstack.com) for production-hardened guides (SSL, backups, and reverse proxies). + +> [!TIP] +> This repository contains basic community configs. For commercial-grade Sovereign Infrastructure setup, always refer to our [Official Documentation](https://thealtstack.com/docs). ```bash -cd deploy-configs/plausible +cd deployments/plausible docker-compose up -d ``` diff --git a/scraper/requirements.txt b/scraper/requirements.txt new file mode 100644 index 0000000..1190bd8 --- /dev/null +++ b/scraper/requirements.txt @@ -0,0 +1,2 @@ +requests +beautifulsoup4 diff --git a/scraper/scraper.py b/scraper/scraper.py new file mode 100644 index 0000000..b71e65a --- /dev/null +++ b/scraper/scraper.py @@ -0,0 +1,83 @@ +import json +import urllib.request +import urllib.error +import os +import time + +# Paths +BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +DATA_FILE = os.path.join(BASE_DIR, 'data', 'tools.json') + +def load_data(): + with open(DATA_FILE, 'r') as f: + return json.load(f) + +def save_data(data): + with open(DATA_FILE, 'w') as f: + json.dump(data, f, indent=2) + +def fetch_github_stats(repo_name): + print(f"Fetching stats for {repo_name}...") + url = f"https://api.github.com/repos/{repo_name}" + req = urllib.request.Request(url) + # GitHub requires a User-Agent + req.add_header('User-Agent', 'Python-Urllib-Scraper') + + # Use GITHUB_TOKEN if available to avoid rate limits + token = os.environ.get('GITHUB_TOKEN') + if token: + req.add_header('Authorization', f'token {token}') + + try: + with urllib.request.urlopen(req) as response: + if response.status == 200: + data = json.loads(response.read().decode()) + return { + "stars": data.get("stargazers_count", 0), + "description": data.get("description", ""), + "last_commit": data.get("pushed_at", ""), + "language": data.get("language", ""), + "license": data.get("license", {}).get("name", "Unknown") if data.get("license") else "None" + } + else: + print(f"Error fetching {repo_name}: {response.status}") + return None + except urllib.error.HTTPError as e: + print(f"HTTP Error fetching {repo_name}: {e.code}") + # If rate limited, print a warning + if e.code == 403: + print("Warning: API Rate limited. Use GITHUB_TOKEN for higher limits.") + return None + except Exception as e: + print(f"Error fetching {repo_name}: {e}") + return None + +def main(): + tools = load_data() + updated = False + + for tool in tools: + if tool.get("is_open_source") and tool.get("github_repo"): + stats = fetch_github_stats(tool["github_repo"]) + if stats: + tool.update(stats) + updated = True + time.sleep(0.5) # Be nice to API, slightly faster with token + + # Save to root data folder + with open(DATA_FILE, 'w') as f: + json.dump(tools, f, indent=2) + + # Save to web data folder if it exists + web_data_path = os.path.join(BASE_DIR, 'web', 'data', 'tools.json') + if os.path.exists(os.path.dirname(web_data_path)): + with open(web_data_path, 'w') as f: + json.dump(tools, f, indent=2) + + if updated: + print("Data updated successfully!") + else: + print("No updates found.") + +if __name__ == "__main__": + main()