infra: HTTPS wildcard cert, subdomain routing, CI/CD pipeline, Grafana
- Wildcard LE cert for *.fxhnt.ai - Subdomain routing: git/grafana/prometheus.fxhnt.ai - CI/CD: Kaniko image builds, sccache, deploy stage - Grafana with Prometheus datasource - GitLab node upgraded to GP1-XS (16GB)
This commit is contained in:
@@ -17,7 +17,10 @@ variables:
|
||||
AWS_ACCESS_KEY_ID: $SCW_ACCESS_KEY
|
||||
AWS_SECRET_ACCESS_KEY: $SCW_SECRET_KEY
|
||||
RUSTC_WRAPPER: /usr/local/bin/sccache
|
||||
REGISTRY: ${CI_REGISTRY_IMAGE}
|
||||
# External: git.fxhnt.ai:5050/root/foxhunt (via Tailscale — not reachable from pods)
|
||||
# Internal: gitlab-registry.foxhunt.svc.cluster.local:5000 (HTTP, reachable from pods)
|
||||
INTERNAL_REGISTRY: gitlab-registry.foxhunt.svc.cluster.local:5000
|
||||
REGISTRY: ${INTERNAL_REGISTRY}/root/foxhunt
|
||||
|
||||
# Base template for Rust jobs
|
||||
.rust-base:
|
||||
@@ -63,11 +66,12 @@ test:
|
||||
entrypoint: [""]
|
||||
tags:
|
||||
- kapsule
|
||||
- docker
|
||||
rules:
|
||||
- if: $CI_COMMIT_BRANCH == "main" && $CI_PIPELINE_SOURCE == "push"
|
||||
before_script:
|
||||
- mkdir -p /kaniko/.docker
|
||||
- echo "{\"auths\":{\"${CI_REGISTRY}\":{\"auth\":\"$(printf '%s:%s' "${CI_REGISTRY_USER}" "${CI_REGISTRY_PASSWORD}" | base64 | tr -d '\n')\"}}}" > /kaniko/.docker/config.json
|
||||
- echo "{\"auths\":{\"${INTERNAL_REGISTRY}\":{\"auth\":\"$(printf '%s:%s' "${CI_REGISTRY_USER}" "${CI_REGISTRY_PASSWORD}" | base64 | tr -d '\n')\"}}}" > /kaniko/.docker/config.json
|
||||
|
||||
build-trading-service:
|
||||
extends: .kaniko-base
|
||||
@@ -75,6 +79,7 @@ build-trading-service:
|
||||
- /kaniko/executor
|
||||
--context "${CI_PROJECT_DIR}"
|
||||
--dockerfile "${CI_PROJECT_DIR}/infra/docker/Dockerfile.service"
|
||||
--insecure-registry "${INTERNAL_REGISTRY}"
|
||||
--build-arg SERVICE=trading_service
|
||||
--build-arg SCCACHE_BUCKET=${SCCACHE_BUCKET}
|
||||
--build-arg AWS_ACCESS_KEY_ID=${SCW_ACCESS_KEY}
|
||||
@@ -89,6 +94,7 @@ build-api-gateway:
|
||||
- /kaniko/executor
|
||||
--context "${CI_PROJECT_DIR}"
|
||||
--dockerfile "${CI_PROJECT_DIR}/infra/docker/Dockerfile.service"
|
||||
--insecure-registry "${INTERNAL_REGISTRY}"
|
||||
--build-arg SERVICE=api_gateway
|
||||
--build-arg SCCACHE_BUCKET=${SCCACHE_BUCKET}
|
||||
--build-arg AWS_ACCESS_KEY_ID=${SCW_ACCESS_KEY}
|
||||
@@ -103,6 +109,7 @@ build-broker-gateway:
|
||||
- /kaniko/executor
|
||||
--context "${CI_PROJECT_DIR}"
|
||||
--dockerfile "${CI_PROJECT_DIR}/infra/docker/Dockerfile.service"
|
||||
--insecure-registry "${INTERNAL_REGISTRY}"
|
||||
--build-arg SERVICE=broker_gateway_service
|
||||
--build-arg SCCACHE_BUCKET=${SCCACHE_BUCKET}
|
||||
--build-arg AWS_ACCESS_KEY_ID=${SCW_ACCESS_KEY}
|
||||
@@ -117,6 +124,7 @@ build-ml-training:
|
||||
- /kaniko/executor
|
||||
--context "${CI_PROJECT_DIR}"
|
||||
--dockerfile "${CI_PROJECT_DIR}/infra/docker/Dockerfile.service"
|
||||
--insecure-registry "${INTERNAL_REGISTRY}"
|
||||
--build-arg SERVICE=ml_training_service
|
||||
--build-arg SCCACHE_BUCKET=${SCCACHE_BUCKET}
|
||||
--build-arg AWS_ACCESS_KEY_ID=${SCW_ACCESS_KEY}
|
||||
@@ -131,6 +139,7 @@ build-backtesting:
|
||||
- /kaniko/executor
|
||||
--context "${CI_PROJECT_DIR}"
|
||||
--dockerfile "${CI_PROJECT_DIR}/infra/docker/Dockerfile.service"
|
||||
--insecure-registry "${INTERNAL_REGISTRY}"
|
||||
--build-arg SERVICE=backtesting_service
|
||||
--build-arg SCCACHE_BUCKET=${SCCACHE_BUCKET}
|
||||
--build-arg AWS_ACCESS_KEY_ID=${SCW_ACCESS_KEY}
|
||||
@@ -145,6 +154,7 @@ build-trading-agent:
|
||||
- /kaniko/executor
|
||||
--context "${CI_PROJECT_DIR}"
|
||||
--dockerfile "${CI_PROJECT_DIR}/infra/docker/Dockerfile.service"
|
||||
--insecure-registry "${INTERNAL_REGISTRY}"
|
||||
--build-arg SERVICE=trading_agent_service
|
||||
--build-arg SCCACHE_BUCKET=${SCCACHE_BUCKET}
|
||||
--build-arg AWS_ACCESS_KEY_ID=${SCW_ACCESS_KEY}
|
||||
@@ -153,12 +163,28 @@ build-trading-agent:
|
||||
--destination "${REGISTRY}/trading_agent_service:${CI_COMMIT_SHA}"
|
||||
--destination "${REGISTRY}/trading_agent_service:latest"
|
||||
|
||||
build-data-acquisition:
|
||||
extends: .kaniko-base
|
||||
script:
|
||||
- /kaniko/executor
|
||||
--context "${CI_PROJECT_DIR}"
|
||||
--dockerfile "${CI_PROJECT_DIR}/infra/docker/Dockerfile.service"
|
||||
--insecure-registry "${INTERNAL_REGISTRY}"
|
||||
--build-arg SERVICE=data_acquisition_service
|
||||
--build-arg SCCACHE_BUCKET=${SCCACHE_BUCKET}
|
||||
--build-arg AWS_ACCESS_KEY_ID=${SCW_ACCESS_KEY}
|
||||
--build-arg AWS_SECRET_ACCESS_KEY=${SCW_SECRET_KEY}
|
||||
--build-arg SCCACHE_ENDPOINT=${SCCACHE_ENDPOINT}
|
||||
--destination "${REGISTRY}/data_acquisition_service:${CI_COMMIT_SHA}"
|
||||
--destination "${REGISTRY}/data_acquisition_service:latest"
|
||||
|
||||
build-web-gateway:
|
||||
extends: .kaniko-base
|
||||
script:
|
||||
- /kaniko/executor
|
||||
--context "${CI_PROJECT_DIR}"
|
||||
--dockerfile "${CI_PROJECT_DIR}/infra/docker/Dockerfile.web-gateway"
|
||||
--insecure-registry "${INTERNAL_REGISTRY}"
|
||||
--destination "${REGISTRY}/web-gateway:${CI_COMMIT_SHA}"
|
||||
--destination "${REGISTRY}/web-gateway:latest"
|
||||
|
||||
@@ -168,6 +194,7 @@ build-training:
|
||||
- /kaniko/executor
|
||||
--context "${CI_PROJECT_DIR}"
|
||||
--dockerfile "${CI_PROJECT_DIR}/infra/docker/Dockerfile.training"
|
||||
--insecure-registry "${INTERNAL_REGISTRY}"
|
||||
--build-arg SCCACHE_BUCKET=${SCCACHE_BUCKET}
|
||||
--build-arg AWS_ACCESS_KEY_ID=${SCW_ACCESS_KEY}
|
||||
--build-arg AWS_SECRET_ACCESS_KEY=${SCW_SECRET_KEY}
|
||||
@@ -190,30 +217,23 @@ deploy:
|
||||
- build-ml-training
|
||||
- build-backtesting
|
||||
- build-trading-agent
|
||||
- build-data-acquisition
|
||||
- build-web-gateway
|
||||
- build-training
|
||||
rules:
|
||||
- if: $CI_COMMIT_BRANCH == "main" && $CI_PIPELINE_SOURCE == "push"
|
||||
before_script:
|
||||
- mkdir -p ~/.kube
|
||||
- echo "$KUBECONFIG_DATA" | base64 -d > ~/.kube/config
|
||||
- echo "$KUBECONFIG_B64" | base64 -d > ~/.kube/config
|
||||
- chmod 600 ~/.kube/config
|
||||
environment:
|
||||
name: production
|
||||
kubernetes:
|
||||
namespace: foxhunt
|
||||
script:
|
||||
# Apply manifests (picks up any config/resource changes)
|
||||
- kubectl apply -f infra/k8s/databases/
|
||||
- kubectl apply -f infra/k8s/services/
|
||||
# Update images to this commit's build
|
||||
- |
|
||||
for svc in trading-service api-gateway broker-gateway-service ml-training-service backtesting-service trading-agent-service; do
|
||||
for svc in trading_service api_gateway broker_gateway_service ml_training_service backtesting_service trading_agent_service data_acquisition_service; do
|
||||
kubectl -n foxhunt set image deployment/${svc} ${svc}=${REGISTRY}/${svc}:${CI_COMMIT_SHA} || true
|
||||
done
|
||||
kubectl -n foxhunt set image deployment/web-gateway web-gateway=${REGISTRY}/web-gateway:${CI_COMMIT_SHA} || true
|
||||
# Wait for rollouts
|
||||
- |
|
||||
for svc in trading-service api-gateway broker-gateway-service ml-training-service backtesting-service trading-agent-service web-gateway; do
|
||||
kubectl -n foxhunt rollout status deployment/${svc} --timeout=300s || true
|
||||
done
|
||||
|
||||
61
infra/k8s/gitlab/grafana-values.yaml
Normal file
61
infra/k8s/gitlab/grafana-values.yaml
Normal file
@@ -0,0 +1,61 @@
|
||||
# Grafana — Foxhunt monitoring dashboard
|
||||
# Accessed via Tailscale proxy on port 3000
|
||||
|
||||
replicas: 1
|
||||
|
||||
nodeSelector:
|
||||
k8s.scaleway.com/pool-name: gitlab
|
||||
tolerations:
|
||||
- key: gitlab
|
||||
operator: Equal
|
||||
value: "true"
|
||||
effect: NoSchedule
|
||||
|
||||
resources:
|
||||
requests:
|
||||
cpu: 50m
|
||||
memory: 128Mi
|
||||
limits:
|
||||
cpu: 200m
|
||||
memory: 256Mi
|
||||
|
||||
persistence:
|
||||
enabled: true
|
||||
size: 2Gi
|
||||
|
||||
adminUser: admin
|
||||
adminPassword: Welcome01
|
||||
|
||||
grafana.ini:
|
||||
server:
|
||||
root_url: https://grafana.fxhnt.ai
|
||||
|
||||
datasources:
|
||||
datasources.yaml:
|
||||
apiVersion: 1
|
||||
datasources:
|
||||
- name: Prometheus
|
||||
type: prometheus
|
||||
url: http://gitlab-prometheus-server.foxhunt.svc.cluster.local:80
|
||||
access: proxy
|
||||
isDefault: true
|
||||
|
||||
dashboardProviders:
|
||||
dashboardproviders.yaml:
|
||||
apiVersion: 1
|
||||
providers:
|
||||
- name: default
|
||||
orgId: 1
|
||||
folder: GitLab
|
||||
type: file
|
||||
disableDeletion: false
|
||||
editable: true
|
||||
options:
|
||||
path: /var/lib/grafana/dashboards/default
|
||||
|
||||
dashboards:
|
||||
default:
|
||||
gitlab-overview:
|
||||
gnetId: 1860
|
||||
revision: 37
|
||||
datasource: Prometheus
|
||||
@@ -67,6 +67,9 @@ spec:
|
||||
volumeMounts:
|
||||
- name: nginx-conf
|
||||
mountPath: /etc/nginx/conf.d
|
||||
- name: tls-certs
|
||||
mountPath: /etc/nginx/certs
|
||||
readOnly: true
|
||||
resources:
|
||||
requests:
|
||||
cpu: 25m
|
||||
@@ -122,6 +125,9 @@ spec:
|
||||
- name: nginx-conf
|
||||
configMap:
|
||||
name: tailscale-gitlab-nginx
|
||||
- name: tls-certs
|
||||
secret:
|
||||
secretName: gitlab-tls-cert
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
@@ -130,10 +136,22 @@ metadata:
|
||||
namespace: foxhunt
|
||||
data:
|
||||
default.conf: |
|
||||
# HTTP → HTTPS redirect for all subdomains
|
||||
server {
|
||||
listen 80;
|
||||
server_name *.fxhnt.ai;
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
|
||||
# GitLab — git.fxhnt.ai
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name git.fxhnt.ai;
|
||||
|
||||
ssl_certificate /etc/nginx/certs/tls.crt;
|
||||
ssl_certificate_key /etc/nginx/certs/tls.key;
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
|
||||
client_max_body_size 0;
|
||||
|
||||
location / {
|
||||
@@ -141,7 +159,7 @@ data:
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-Proto https;
|
||||
|
||||
proxy_buffering off;
|
||||
proxy_request_buffering off;
|
||||
@@ -152,10 +170,15 @@ data:
|
||||
}
|
||||
}
|
||||
|
||||
# Container Registry — git.fxhnt.ai:5050
|
||||
server {
|
||||
listen 5050;
|
||||
listen 5050 ssl;
|
||||
server_name git.fxhnt.ai;
|
||||
|
||||
ssl_certificate /etc/nginx/certs/tls.crt;
|
||||
ssl_certificate_key /etc/nginx/certs/tls.key;
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
|
||||
client_max_body_size 0;
|
||||
|
||||
location / {
|
||||
@@ -163,7 +186,7 @@ data:
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-Proto https;
|
||||
|
||||
proxy_buffering off;
|
||||
proxy_request_buffering off;
|
||||
@@ -172,3 +195,43 @@ data:
|
||||
proxy_send_timeout 3600s;
|
||||
}
|
||||
}
|
||||
|
||||
# Grafana — grafana.fxhnt.ai
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name grafana.fxhnt.ai;
|
||||
|
||||
ssl_certificate /etc/nginx/certs/tls.crt;
|
||||
ssl_certificate_key /etc/nginx/certs/tls.key;
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
|
||||
location / {
|
||||
proxy_pass http://grafana.foxhunt.svc.cluster.local:80;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto https;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
}
|
||||
}
|
||||
|
||||
# Prometheus — prometheus.fxhnt.ai
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name prometheus.fxhnt.ai;
|
||||
|
||||
ssl_certificate /etc/nginx/certs/tls.crt;
|
||||
ssl_certificate_key /etc/nginx/certs/tls.key;
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
|
||||
location / {
|
||||
proxy_pass http://gitlab-prometheus-server.foxhunt.svc.cluster.local:80;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto https;
|
||||
proxy_http_version 1.1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,8 +8,10 @@ global:
|
||||
domain: fxhnt.ai
|
||||
gitlab:
|
||||
name: git.fxhnt.ai
|
||||
https: true
|
||||
registry:
|
||||
name: git.fxhnt.ai
|
||||
https: true
|
||||
ingress:
|
||||
enabled: false
|
||||
configureCertmanager: false
|
||||
|
||||
@@ -21,9 +21,9 @@ inputs = {
|
||||
gpu_inference_type = "L4-1-24G"
|
||||
gpu_inference_max_size = 1
|
||||
|
||||
# GitLab CE pool (dedicated for GitLab + Runner manager)
|
||||
# GitLab CE pool (dedicated for GitLab + Prometheus + Runner manager)
|
||||
enable_gitlab_pool = true
|
||||
gitlab_type = "DEV1-L"
|
||||
gitlab_type = "GP1-XS"
|
||||
|
||||
# CI build pool (ephemeral runner pods, scale-to-zero)
|
||||
enable_ci_build_pool = true
|
||||
|
||||
Reference in New Issue
Block a user