mirror of
https://github.com/altstackHQ/altstack-data.git
synced 2026-04-17 23:53:14 +02:00
feat: enhance SEO, add automation, and conversion snippets
This commit is contained in:
70
.github/ISSUE_TEMPLATE/tool-submission.yml
vendored
Normal file
70
.github/ISSUE_TEMPLATE/tool-submission.yml
vendored
Normal file
@@ -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
|
||||||
39
.github/workflows/scrape-data.yml
vendored
Normal file
39
.github/workflows/scrape-data.yml
vendored
Normal file
@@ -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)
|
||||||
66
README.md
66
README.md
@@ -9,6 +9,12 @@
|
|||||||
Stop paying for what you can host yourself. Build sovereign infrastructure with AltStack.
|
Stop paying for what you can host yourself. Build sovereign infrastructure with AltStack.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<a href="https://github.com/altstackHQ/altstack-data/stargazers"><img src="https://img.shields.io/github/stars/altstackHQ/altstack-data?color=ffdd00&label=Stars&logo=github&style=for-the-badge" alt="GitHub stars" /></a>
|
||||||
|
<a href="https://github.com/altstackHQ/altstack-data/blob/main/LICENSE"><img src="https://img.shields.io/github/license/altstackHQ/altstack-data?color=blue&label=License&style=for-the-badge" alt="License" /></a>
|
||||||
|
<a href="https://github.com/altstackHQ/altstack-data/issues"><img src="https://img.shields.io/badge/PRs-Welcome-brightgreen?style=for-the-badge&logo=git&logoColor=white" alt="PRs Welcome" /></a>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://thealtstack.com"><strong>Explore the Directory</strong></a> •
|
<a href="https://thealtstack.com"><strong>Explore the Directory</strong></a> •
|
||||||
<a href="https://docs.thealtstack.com"><strong>Self-Hosting Guides</strong></a> •
|
<a href="https://docs.thealtstack.com"><strong>Self-Hosting Guides</strong></a> •
|
||||||
@@ -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
|
## 📂 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:
|
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`
|
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.
|
2. **Explore `/deployments`**: 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.
|
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
|
```bash
|
||||||
cd deploy-configs/plausible
|
cd deployments/plausible
|
||||||
docker-compose up -d
|
docker-compose up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
2
scraper/requirements.txt
Normal file
2
scraper/requirements.txt
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
requests
|
||||||
|
beautifulsoup4
|
||||||
83
scraper/scraper.py
Normal file
83
scraper/scraper.py
Normal file
@@ -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()
|
||||||
Reference in New Issue
Block a user