|
1 | | -# unbindapp/unbind-api |
| 1 | +# Unbind (APIs + Builder) |
| 2 | + |
| 3 | +<div align="center"> |
| 4 | + |
| 5 | + |
| 6 | + |
| 7 | + |
| 8 | + |
| 9 | + |
| 10 | + |
| 11 | + |
| 12 | +**Kubernetes-Based Platform as a Service** |
| 13 | + |
| 14 | +_Effortlessly deploy, scale, and manage applications on Kubernetes_ |
| 15 | + |
| 16 | +[🚀 **Quick Start**](#-quick-start) • [📖 **Documentation**](#-api-documentation) • [🏗️ **Architecture**](#-architecture) • [🤝 **Contributing**](#-contributing) |
| 17 | + |
| 18 | +</div> |
| 19 | + |
| 20 | +--- |
| 21 | + |
| 22 | +## 🌟 **What is Unbind?** |
| 23 | + |
| 24 | +Unbind is a **Platform as a Service (PaaS)** for managing all kinds of applications, it provides: |
| 25 | + |
| 26 | +- 🎯 **Zero-configuration deployments** from Git repositories and Docker images |
| 27 | +- ⚡ **Intelligent build system** powered by [BuildKit](https://github.com/moby/buildkit) and [Railpack](https://github.com/railwayapp/railpack) |
| 28 | +- 🔒 **Security** integrating OAuth2/OIDC with native [Kubernetes RBAC](https://kubernetes.io/docs/reference/access-authn-authz/rbac/) |
| 29 | +- 📊 **Metrics** with [Prometheus kube stack](https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack) |
| 30 | +- 📖 **Templates** an extensible template system that supports zero-configuration deployments of many popular open-source products (plausible, supabase, wordpress, minio, and more.) |
| 31 | +- 💾 **Production-grade Databases with Backups** with support for many popular databases through [operators](https://kubernetes.io/docs/concepts/extend-kubernetes/operator/) and helm charts - with backups to any S3-compatible storage. |
| 32 | + |
| 33 | +--- |
| 34 | + |
| 35 | +## 🏗️ **Architecture** |
| 36 | + |
| 37 | +```mermaid |
| 38 | +graph TB |
| 39 | + subgraph "🌐 Frontend & API" |
| 40 | + UI[🌐 Unbind UI] |
| 41 | + API[🚀 Unbind API] |
| 42 | + Auth[🔐 OAuth2 Server] |
| 43 | + UI --> API |
| 44 | + API --> Auth |
| 45 | + end |
| 46 | +
|
| 47 | + subgraph "💾 Data Layer" |
| 48 | + DB[(🗄️ PostgreSQL)] |
| 49 | + Cache[(📦 Redis)] |
| 50 | + end |
| 51 | +
|
| 52 | + subgraph "🏗️ Build Pipeline" |
| 53 | + Job[📦 Build Job] |
| 54 | + Builder[🏗️ Unbind Builder] |
| 55 | + BuildKit[⚡ BuildKit] |
| 56 | + Registry[📦 Container Registry] |
| 57 | + Git[🐙 Git Integration] |
| 58 | +
|
| 59 | + Job --> Builder |
| 60 | + Builder --> BuildKit |
| 61 | + Builder --> Registry |
| 62 | + Builder --> Git |
| 63 | + end |
| 64 | +
|
| 65 | + subgraph "☸️ Infrastructure" |
| 66 | + K8s[☸️ Kubernetes] |
| 67 | + Operator[🔧 Unbind Operator] |
| 68 | + Operator --> K8s |
| 69 | + end |
| 70 | +
|
| 71 | + subgraph "📊 Monitoring and Logs" |
| 72 | + Prometheus[📊 Prometheus] |
| 73 | + Alloy[📡 Alloy] |
| 74 | + Loki[📋 Loki] |
| 75 | +
|
| 76 | + Alloy --> Loki |
| 77 | + end |
| 78 | +
|
| 79 | + %% Main connections |
| 80 | + API --> DB |
| 81 | + API --> Cache |
| 82 | + API --> Job |
| 83 | + API --> K8s |
| 84 | + Builder --> K8s |
| 85 | + K8s --> Prometheus |
| 86 | + K8s --> Alloy |
| 87 | + API --> Prometheus |
| 88 | + API --> Loki |
| 89 | +``` |
| 90 | + |
| 91 | +### 🧩 **Core Components** |
| 92 | + |
| 93 | +| Component | Purpose | Technology | |
| 94 | +| ------------------- | ------------------------------- | ------------------- | |
| 95 | +| **API Server** | Core platform logic & REST APIs | Go + Huma Framework | |
| 96 | +| **OAuth2 Server** | Authentication & authorization | Dex + OIDC | |
| 97 | +| **Builder Service** | Container image building | BuildKit + Railpack | |
| 98 | + |
| 99 | +--- |
| 100 | + |
| 101 | +## 🚀 **Quick Start** |
2 | 102 |
|
3 | | -  |
| 103 | +### 📋 **Prerequisites** |
4 | 104 |
|
5 | | -The APIs for the Unbind platform. |
| 105 | +- **Go 1.24+** 🐹 |
| 106 | +- **Docker & Docker Compose** 🐳 |
| 107 | +- **Kubernetes cluster** (local or cloud) ☸️ |
| 108 | +- **Dex IDP binary** in `$PATH` 🔐 |
6 | 109 |
|
7 | | -## Prerequisites (to run locally) |
| 110 | +### ⚡ **Local Development Setup** |
8 | 111 |
|
9 | | -- Go 1.24 or higher |
10 | | -- Docker Compose |
11 | | -- [Dex IDP](https://dexidp.io) binary installed in $PATH |
| 112 | +```bash |
| 113 | +# 1) Clone the repository |
| 114 | +git clone https://github.com/unbindapp/unbind-api.git |
| 115 | +cd unbind-api |
12 | 116 |
|
13 | | -1. Clone the repository |
14 | | -2. Run `docker-compose up -d` to start dependencies (postgres, redis, etc.) |
15 | | -3. Run `./startdex.sh` to start dex IDP |
16 | | -4. Reference [config/config.go](config/config.go) for environment variables, place them in a `.env` file |
| 117 | +# 2) Start infrastructure dependencies |
| 118 | +docker-compose up -d |
17 | 119 |
|
18 | | -## Running services |
| 120 | +# 3) Start Dex Identity Provider |
| 121 | +./startdex.sh |
| 122 | + |
| 123 | +# 4) Configure environment variables |
| 124 | +cp .env.example .env |
| 125 | +# Edit .env with your settings (see config/config.go for reference) |
| 126 | + |
| 127 | +# 5) Run database migrations |
| 128 | +go run cmd/cli migrate |
| 129 | + |
| 130 | +# 6) Start the services |
| 131 | +go run cmd/api # 🚀 API Server (port 8089) |
| 132 | +go run cmd/oauth2server # 🔐 OAuth2 Server (port 8090) |
| 133 | +``` |
19 | 134 |
|
20 | | -- `go run cmd/api` to start the API |
21 | | - - Visit `http://localhost:8089/docs` for API documentation |
22 | | -- `go run cmd/oauth2server` to start the OAuth2 server |
23 | | -- `go run cmd/cli` to execute CLI commands |
| 135 | +### 📖 **API Documentation** |
24 | 136 |
|
25 | | -## Generated code |
| 137 | +Visit **`http://localhost:8089/docs`** for interactive API documentation (OpenAPI 3.1) 📚 |
26 | 138 |
|
27 | | -Unbind relies on code generation for some components: |
| 139 | +--- |
28 | 140 |
|
29 | | -- `./ent` - Generated by ent framework |
30 | | -- Various interfaces, generated with [ifacemaker](https://github.com/vburenin/ifacemaker) |
31 | | -- `./mocks` - Generated with [mockery](https://github.com/vektra/mockery) |
| 141 | +## 🔧 **Technology Stack** |
32 | 142 |
|
33 | | -Run `go generate ./...` to re-generate ent code and interfaces. |
| 143 | +### 🏗️ **Backend Technologies** |
34 | 144 |
|
35 | | -Install mockery and run `mockery` to re-generate mocks. |
| 145 | +| Technology | Purpose | Why We Use It | |
| 146 | +| ------------------------------------------------------ | ------------------- | ------------------------------------------------ | |
| 147 | +| **[Huma v2](https://huma.rocks/)** | REST API Framework | Type-safe APIs with automatic OpenAPI generation | |
| 148 | +| **[Ent](https://entgo.io/)** | Entity Framework | ORM that models database entities as GO objects | |
| 149 | +| **[go-redis](https://github.com/redis/go-redis)** | Redis Client | Build queues and caching | |
| 150 | +| **[BuildKit](https://github.com/moby/buildkit)** | Container Builder | Advanced build features and distributed caching | |
| 151 | +| **[Railpack](https://github.com/railwayapp/railpack)** | Application Builder | Automatically turns code into images | |
36 | 152 |
|
37 | | -## Core GO Dependencies |
| 153 | +### ☸️ **Kubernetes & Cloud** |
38 | 154 |
|
39 | | -- [Huma](https://huma.rocks/) - REST API Framework |
40 | | -- [ent](https://entgo.io/) - Entity framework for GO |
41 | | -- [go-redis](https://github.com/redis/go-redis) - Redis client |
42 | | -- [ifacemaker](https://github.com/vburenin/ifacemaker) - Automatically generates interfaces from structs |
43 | | -- [mockery](https://github.com/vektra/mockery) - Automatically creates mocks based on `.mockery.yaml` |
| 155 | +- **Cert-Manager** for TLS certificate automation with Let's Encrypt |
| 156 | +- **Ingress NGINX Controller** for reverse proxy and load balancer |
| 157 | +- **Prometheus** for metrics collection |
| 158 | +- **Loki** for centralized logging |
| 159 | +- **Alloy** for ingesting pod logs into Loki |
44 | 160 |
|
45 | | -## Bootstrapping |
| 161 | +--- |
46 | 162 |
|
47 | | -Bootsrap superuser: |
| 163 | +## 🛠️ **Development Workflow** |
48 | 164 |
|
| 165 | +### 🔄 **Code Generation** |
| 166 | + |
| 167 | +Unbind uses extensive code generation for maintainable, type-safe code: |
| 168 | + |
| 169 | +```bash |
| 170 | +# Regenerate Ent entities and edges |
| 171 | +go generate ./ent/... |
| 172 | + |
| 173 | +# Regenerate service interfaces |
| 174 | +go generate ./... |
| 175 | + |
| 176 | +# Regenerate mocks for testing |
| 177 | +mockery |
49 | 178 | ``` |
50 | | -/app/cli user:create --email=EMAIL --password=PASSWORD |
51 | | -/app/cli group:create --name=superuser --description="Superuser Group" |
52 | | -/app/cli group:add-user --email=EMAIL --group-name=superuser |
53 | | -/app/cli group:grant-permission --group-name=superuser --resource-type=system --resource-id="*" --action=admin |
54 | | -/app/cli group:grant-permission --group-name=superuser --resource-type=team --resource-id="*" --action=admin |
55 | | -/app/cli sync:group-to-k8s |
| 179 | + |
| 180 | +### 🗄️ **Database Migrations** |
| 181 | + |
| 182 | +Update entities in `./ent/schema`, then create a new versioned migration. |
| 183 | + |
| 184 | +```bash |
| 185 | +# Create a new migration |
| 186 | +make migrate NAME=add_awesome_feature |
| 187 | + |
| 188 | +# If editing the migration manually, then re-generate checksum |
| 189 | +make migrate-checksum |
56 | 190 | ``` |
57 | 191 |
|
58 | | -## Migrations |
| 192 | +Migrations are applied automatically on API startup. |
| 193 | + |
| 194 | +--- |
| 195 | + |
| 196 | +## 👥 **Bootstrapping Admin User** |
| 197 | + |
| 198 | +```bash |
| 199 | +# Create superuser account |
| 200 | +go run cmd/cli user:create \ |
| 201 | + --email=admin@unbind.app \ |
| 202 | + --password=secure_password |
| 203 | + |
| 204 | +# Create superuser group |
| 205 | +go run cmd/cli group:create \ |
| 206 | + --name=superuser \ |
| 207 | + --description="Platform Administrators" |
| 208 | + |
| 209 | +# Add user to superuser group |
| 210 | +go run cmd/cli group:add-user \ |
| 211 | + --email=admin@unbind.app \ |
| 212 | + --group-name=superuser |
| 213 | + |
| 214 | +# Grant system-wide admin permissions |
| 215 | +go run cmd/cli group:grant-permission \ |
| 216 | + --group-name=superuser \ |
| 217 | + --resource-type=system \ |
| 218 | + --resource-id="*" \ |
| 219 | + --action=admin |
| 220 | + |
| 221 | +# Sync permissions to Kubernetes |
| 222 | +go run cmd/cli sync:group-to-k8s |
| 223 | +``` |
| 224 | + |
| 225 | +--- |
| 226 | + |
| 227 | +## 🤝 **Contributing** |
| 228 | + |
| 229 | +We welcome contributions! Here's how to get started: |
| 230 | + |
| 231 | +1. **🍴 Fork** the repository |
| 232 | +2. **🌿 Create** a feature branch: `git checkout -b amazing-feature` |
| 233 | +3. **✨ Make** your changes and add tests |
| 234 | +4. **🧪 Run** tests: `go test ./...` |
| 235 | +5. **📝 Commit** changes: `git commit -m 'Add amazing feature'` |
| 236 | +6. **🚀 Push** to branch: `git push origin amazing-feature` |
| 237 | +7. **🔄 Create** a Pull Request |
| 238 | + |
| 239 | +--- |
| 240 | + |
| 241 | +## 📄 **License** |
| 242 | + |
| 243 | +This project is licensed under the **MIT License** - see the [LICENSE](LICENSE) file for details. |
| 244 | + |
| 245 | +<div align="center"> |
59 | 246 |
|
60 | | -1. Make schema change in `./ent/schema` |
61 | | -2. Re-generate `go generate ./ent/...` |
62 | | -3. Make a versioned migration `make migrate NAME=your_migration_name` |
| 247 | +[Report Bug](https://github.com/unbindapp/unbind-api/issues) • [Request Feature](https://github.com/unbindapp/unbind-api/issues) • [Join Discord](https://discord.gg/r8Q3zNTgbp) |
63 | 248 |
|
64 | | -If you edit a migration sql file manually, be sure to re-generate the checksum `make migrate-checksum` |
| 249 | +</div> |
0 commit comments