StackOps Infrastructure
Architecture
┌─────────────────────────────────────┐
│ Cloudflare DNS │
│ nodeup.ru → 82.114.226.118 │
│ *.app.nodeup.ru (wildcard) │
└──────────────┬──────────────────────┘
│
▼
┌───────────────────────────────────────────┐
│ VPS 82.114.226.118 │
│ Debian 13, 6 CPU, 6GB RAM │
│ │
│ ┌─────────────────────────────────────┐ │
│ │ k3s v1.34.6 │ │
│ │ (traefik disabled) │ │
│ │ │ │
│ │ ┌────────────────────────────────┐ │ │
│ │ │ ingress-nginx (DaemonSet) │ │ │
│ │ │ ports 80/443 via ServiceLB│ │ │
│ │ └──────────┬─────────────────────┘ │ │
│ │ │ │ │
│ │ ┌──────────▼─────────────────────┐ │ │
│ │ │ cert-manager (HTTP-01) │ │ │
│ │ │ ClusterIssuer: letsencrypt │ │ │
│ │ └────────────────────────────────┘ │ │
│ │ │ │
│ │ ┌─── Namespaces ──────────────────┐ │ │
│ │ │ │ │ │
│ │ │ stackops/ │ │ │
│ │ │ stackops-api (Go + React UI) │ │ │
│ │ │ SQLite PVC, ClusterRole RBAC │ │ │
│ │ │ → app.nodeup.ru │ │ │
│ │ │ │ │ │
│ │ │ gitea/ │ │ │
│ │ │ Gitea (SQLite + Valkey) │ │ │
│ │ │ → git.nodeup.ru │ │ │
│ │ │ │ │ │
│ │ │ monitoring/ │ │ │
│ │ │ Prometheus (20Gi PV) │ │ │
│ │ │ Grafana → grafana.nodeup.ru │ │ │
│ │ │ Loki + Promtail (10Gi PV) │ │ │
│ │ │ │ │ │
│ │ │ vela-system/ │ │ │
│ │ │ KubeVela (OAM engine) │ │ │
│ │ │ │ │ │
│ │ │ cnpg-system/ │ │ │
│ │ │ CloudNativePG operator │ │ │
│ │ │ │ │ │
│ │ │ redis-operator/ │ │ │
│ │ │ OT Systems Redis operator │ │ │
│ │ │ │ │ │
│ │ │ whoami/ (test app) │ │ │
│ │ │ whoami + PostgreSQL (PV) │ │ │
│ │ │ → whoami.app.nodeup.ru │ │ │
│ │ │ │ │ │
│ │ └──────────────────────────────────┘ │ │
│ └─────────────────────────────────────┘ │
└───────────────────────────────────────────┘
Domains
| Domain | Service | TLS |
|---|---|---|
app.nodeup.ru |
StackOps API + UI | Let's Encrypt |
git.nodeup.ru |
Gitea | Let's Encrypt |
grafana.nodeup.ru |
Grafana | Let's Encrypt |
prom.nodeup.ru |
Prometheus (reserved) | — |
*.app.nodeup.ru |
User apps (wildcard) | Let's Encrypt per-app |
Deploy Flow
Developer writes stackfile.toml
│
▼
StackOps API (app.nodeup.ru)
│
├── git clone → reads stackfile.toml + commit SHA
│
├── toml-converter → KubeVela Application YAML
│
├── kubectl apply -n <namespace>
│
└── KubeVela orchestrates:
1. CloudNativePG → PostgreSQL cluster + secrets
2. Redis operator → Redis instance
3. webservice → Deployment + Service
4. gateway trait → Ingress (nginx + cert-manager TLS)
Components
| Component | Version | Namespace | Purpose |
|---|---|---|---|
| k3s | v1.34.6 | — | Kubernetes distribution |
| nginx-ingress | 4.15.1 | ingress-nginx | Ingress controller |
| cert-manager | v1.20.1 | cert-manager | TLS certificates (HTTP-01) |
| KubeVela | 1.10.8 | vela-system | OAM application engine |
| CloudNativePG | 1.23.0 | cnpg-system | PostgreSQL operator |
| Redis operator | 0.24.0 | redis-operator | Redis operator |
| Gitea | 1.25.4 | gitea | Git hosting |
| Prometheus | v0.90.1 | monitoring | Metrics |
| Grafana | (bundled) | monitoring | Dashboards |
| Loki | v2.9.3 | monitoring | Log aggregation |
| Promtail | (bundled) | monitoring | Log shipping |
Credentials
| Service | Login | Password |
|---|---|---|
| Gitea | stackops |
stackops-admin-2026 |
| Grafana | admin |
stackops-grafana-2026 |
| StackOps API | token | dev-secret-token |
Kubeconfig
export KUBECONFIG=~/.kube/config-nodeup
# or
export KUBECONFIG=infra/kubeconfig.yaml
Note: kubeconfig.yaml is in .gitignore — it contains the cluster admin token. Copy it manually from ~/.kube/config-nodeup.
Gitea Repositories
| Repo | URL | Content |
|---|---|---|
stackops/infra |
https://git.nodeup.ru/stackops/infra | This repo — IaC manifests |
stackops/stackops |
https://git.nodeup.ru/stackops/stackops | Application source code |
Reproduce from Scratch
# 0. DNS
bash 00-dns/cloudflare-records.sh
# 1. k3s
bash 01-k3s/install.sh
# 2. Core (nginx-ingress + cert-manager + ClusterIssuer)
make core
# 3. KubeVela + operators + ComponentDefinitions
make kubevela
# 4. Gitea
make gitea
# 5. Monitoring (Prometheus + Grafana + Loki)
make monitoring
# 6. StackOps app
make stackops
# 7. Test app
make test-app
Or all at once: make all (sequential).
Directory Structure
infra/
├── README.md
├── Makefile # Top-level automation
├── 00-dns/
│ └── cloudflare-records.sh # DNS A records via CF API
├── 01-k3s/
│ └── install.sh # k3s install + kubeconfig
├── 02-core/
│ └── clusterissuer.yaml # cert-manager ClusterIssuer (HTTP-01)
├── 03-kubevela/ # (manifests in ../kubevela/components/)
├── 04-gitea/
│ └── values.yaml # Gitea helm values
├── 05-monitoring/
│ ├── values-prometheus.yaml # kube-prometheus-stack values
│ └── values-loki.yaml # loki-stack values
├── 06-stackops/
│ ├── rbac.yaml # Namespace, SA, ClusterRole, PVC
│ └── deployment.yaml # Deployment, Service, Ingress
└── 07-test-app/
└── stackfile.toml # whoami test app stackfile
Description
Languages
Makefile
70.8%
Shell
29.2%