This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
# 💻 Local Development Infrastructure: Jambotron PaaS
|
||||
|
||||
Этот файл описывает конфигурацию локальной среды разработки, которая зеркально отражает серверную инфраструктуру в Хельсинки. Локальный кластер настроен для обеспечения бесшовного процесса созидания и мониторинга контейнеров.
|
||||
|
||||
## 🏗️ Архитектура системы
|
||||
|
||||
Локальная среда построена на базе Docker и управляется через единую сеть для обеспечения связи между системными базами и динамическими проектами.
|
||||
|
||||
* **Runtime**: Docker Engine / Docker Desktop.
|
||||
* **Network**: `jambotron-net` (Тип: bridge, внешняя).
|
||||
* **Оркестрация**: Docker Compose.
|
||||
* **JDK**: Version 21 (LTS).
|
||||
* **Build Tool**: Gradle.
|
||||
|
||||
## 📦 Реестр локальных сервисов
|
||||
|
||||
| Сервис | Образ | URL / Порт | Назначение |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| **caddy-dev** | `lucaslorentz/caddy-docker-proxy` | `*.localhost` | Обратный прокси с авто-обнаружением через Docker Socket. |
|
||||
| **jambo-postgres** | `postgres:15-alpine` | `localhost:5432` | Системная БД (Пользователи, настройки, биллинг). |
|
||||
| **jambotron-mongo** | `mongo:6.0` | `localhost:27017` | Хранилище метаданных проектов и контейнеров (SaaS 2.0). |
|
||||
| **jambo-pgadmin** | `dpage/pgadmin4` | `pgadmin.localhost` | Веб-интерфейс для управления PostgreSQL. |
|
||||
| **portainer-dev** | `portainer/portainer-ce` | `localhost:9443` | Визуальный мониторинг и управление Docker-ресурсами. |
|
||||
|
||||
## 🛠️ Стек разработки (Dev Mode)
|
||||
|
||||
* **Backend**: Spring Boot 3.5.0 (профиль `dev`).
|
||||
* **Frontend**: Angular 17+ (интегрирован в Gradle-таски).
|
||||
* **БД Миграции**: Flyway.
|
||||
* **API управления**: Docker Java Client (через `/var/run/docker.sock`).
|
||||
|
||||
## 🚀 Быстрый старт
|
||||
|
||||
### 1. Подготовка сети
|
||||
Перед первым запуском необходимо создать общую сеть, если она еще не создана:
|
||||
```bash
|
||||
docker network create jambotron-net
|
||||
```
|
||||
2. Запуск инфраструктуры
|
||||
Запуск всех баз данных и системных сервисов:
|
||||
|
||||
Bash
|
||||
docker-compose -f docker-compose.dev.yml up -d
|
||||
3. Запуск приложения (Spring + Angular)
|
||||
Используй кастомный Gradle-таск для запуска приложения с профилем разработчика:
|
||||
|
||||
Bash
|
||||
./gradlew bootRun_Dev
|
||||
Команда автоматически соберет фронтенд, скопирует статику в src/main/resources/static и запустит сервер.
|
||||
|
||||
🔗 Особенности созидания проектов
|
||||
Для реализации динамического деплоя внутри PaaS, приложение использует проброс Docker Socket.
|
||||
|
||||
Docker Labels: При создании нового контейнера через API, необходимо вешать лейблы caddy и caddy.reverse_proxy, чтобы локальный Caddy автоматически создал маршрут на project-name.localhost.
|
||||
|
||||
Volumes: Данные PostgreSQL и MongoDB сохраняются в именованных томах jambo_db_dev_data и mongo_dev_data соответственно.
|
||||
|
||||
Lombok: Для корректной сборки на JDK 21 используется версия 1.18.34.
|
||||
+95
-103
@@ -1,149 +1,141 @@
|
||||
plugins {
|
||||
id 'java'
|
||||
id 'org.springframework.boot' version '3.5.0'
|
||||
id 'io.spring.dependency-management' version '1.1.7'
|
||||
id 'org.flywaydb.flyway' version '10.4.1'
|
||||
id 'java'
|
||||
id 'org.springframework.boot' version '3.5.0'
|
||||
id 'io.spring.dependency-management' version '1.1.7'
|
||||
id 'org.flywaydb.flyway' version '10.4.1'
|
||||
}
|
||||
|
||||
group = 'com.jambotronGroup'
|
||||
version = '0.0.1-SNAPSHOT'
|
||||
|
||||
java {
|
||||
toolchain {
|
||||
languageVersion = JavaLanguageVersion.of(17)
|
||||
}
|
||||
toolchain {
|
||||
// Устанавливаем актуальную LTS версию 21 для Spring Boot 3.5
|
||||
languageVersion = JavaLanguageVersion.of(21)
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
|
||||
mavenCentral()
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'org.springframework.boot:spring-boot-starter-web'
|
||||
implementation 'org.springframework.boot:spring-boot-starter'
|
||||
implementation 'org.projectlombok:lombok:1.18.26'
|
||||
testImplementation 'org.springframework.boot:spring-boot-starter-test'
|
||||
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
|
||||
implementation 'jakarta.persistence:jakarta.persistence-api:3.1.0'
|
||||
implementation 'jakarta.validation:jakarta.validation-api:3.0.2'
|
||||
implementation 'org.springframework.boot:spring-boot-starter-security'
|
||||
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
|
||||
implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
|
||||
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5'
|
||||
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5' // For JSON serialization/deserialization
|
||||
implementation 'org.postgresql:postgresql:42.6.0'
|
||||
implementation 'org.flywaydb:flyway-core'
|
||||
implementation("org.flywaydb:flyway-database-postgresql:10.4.1")
|
||||
// Ядро Spring Boot
|
||||
implementation 'org.springframework.boot:spring-boot-starter'
|
||||
implementation 'org.springframework.boot:spring-boot-starter-web'
|
||||
implementation 'org.springframework.boot:spring-boot-starter-security'
|
||||
implementation 'org.springframework.boot:spring-boot-starter-actuator'
|
||||
implementation 'jakarta.validation:jakarta.validation-api:3.0.2'
|
||||
|
||||
implementation 'org.springframework.ai:spring-ai-zhipuai-spring-boot-starter:1.0.0-M6'
|
||||
implementation 'org.springframework:spring-mock:2.0.8'
|
||||
// --- НОВОЕ: Реактивная MongoDB 6.0 для метаданных PaaS ---
|
||||
implementation 'org.springframework.boot:spring-boot-starter-data-mongodb-reactive'
|
||||
|
||||
// Apache Commons Exec for process execution
|
||||
implementation 'org.apache.commons:commons-exec:1.3'
|
||||
// --- НОВОЕ: Docker API для управления контейнерами (Созидание) ---
|
||||
implementation 'com.github.docker-java:docker-java-core:3.3.6'
|
||||
implementation 'com.github.docker-java:docker-java-transport-httpclient5:3.3.6'
|
||||
|
||||
implementation 'com.google.guava:guava:33.4.8-jre'
|
||||
implementation 'io.micrometer:micrometer-core:1.12.0'
|
||||
implementation 'org.springframework.boot:spring-boot-starter-actuator'
|
||||
// Работа с SQL и PostgreSQL[cite: 3]
|
||||
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
|
||||
implementation 'org.postgresql:postgresql:42.6.0'
|
||||
implementation 'org.flywaydb:flyway-core'
|
||||
implementation "org.flywaydb:flyway-database-postgresql:10.4.1"
|
||||
implementation 'jakarta.persistence:jakarta.persistence-api:3.1.0'
|
||||
|
||||
// Безопасность и JWT
|
||||
implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
|
||||
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5'
|
||||
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5'
|
||||
|
||||
// Lombok с поддержкой JDK 21
|
||||
compileOnly 'org.projectlombok:lombok:1.18.34'
|
||||
annotationProcessor 'org.projectlombok:lombok:1.18.34'
|
||||
testCompileOnly 'org.projectlombok:lombok:1.18.34'
|
||||
testAnnotationProcessor 'org.projectlombok:lombok:1.18.34'
|
||||
|
||||
// Spring AI и дополнительные утилиты
|
||||
implementation 'org.springframework.ai:spring-ai-zhipuai-spring-boot-starter:1.0.0-M6'
|
||||
implementation 'com.google.guava:guava:33.4.8-jre'
|
||||
implementation 'org.apache.commons:commons-exec:1.3'
|
||||
implementation 'io.micrometer:micrometer-core:1.12.0'
|
||||
|
||||
// Тестирование
|
||||
testImplementation 'org.springframework.boot:spring-boot-starter-test'
|
||||
testImplementation 'io.projectreactor:reactor-test'
|
||||
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
|
||||
|
||||
// Временный фикс для обратной совместимости (если требуется)
|
||||
implementation 'org.springframework:spring-mock:2.0.8'
|
||||
}
|
||||
|
||||
apply plugin: 'io.spring.dependency-management'
|
||||
dependencyManagement {
|
||||
imports {
|
||||
mavenBom ("org.springframework.ai:spring-ai-retry:1.0.0")
|
||||
}
|
||||
}
|
||||
dependencyManagement {
|
||||
imports {
|
||||
mavenBom ("org.springframework.ai:spring-ai-retry:1.0.0")
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'java'
|
||||
// --- Задачи сборки Angular (Твой монолитный код существования) ---
|
||||
|
||||
import org.apache.tools.ant.taskdefs.condition.Os
|
||||
|
||||
tasks.register("bootRun_Dev") {
|
||||
group = "_jambotron_build"
|
||||
description = "Runs the Spring Boot application with the dev profile"
|
||||
doFirst {
|
||||
tasks.bootRun.configure {
|
||||
systemProperty("spring.profiles.active", "dev")
|
||||
}
|
||||
}
|
||||
finalizedBy("bootRun")
|
||||
group = "_jambotron_build"
|
||||
description = "Runs the Spring Boot application with the dev profile"
|
||||
doFirst {
|
||||
tasks.bootRun.configure {
|
||||
systemProperty("spring.profiles.active", "dev")
|
||||
}
|
||||
}
|
||||
finalizedBy("bootRun")
|
||||
}
|
||||
|
||||
|
||||
|
||||
tasks.register('buildAngular_dev', Exec) {
|
||||
group = "_jambotron_build"
|
||||
description = "Builds the Angular application in development mode"
|
||||
|
||||
workingDir './jambotron-ui' // Path to your Angular project (e.g., './angular-app')
|
||||
executable 'npm.cmd' // Use 'npm' for Unix-like systems or 'npm.cmd' for Windows
|
||||
|
||||
// Your Angular build command
|
||||
//do not forget build_dev used port 8082 with proxy for connect to backend rest api
|
||||
args = ['run', 'build_dev']
|
||||
|
||||
}
|
||||
|
||||
import org.apache.tools.ant.taskdefs.condition.Os // Обязательно добавь этот импорт в самое начало файла
|
||||
tasks.register('buildAngular_prod', Exec) {
|
||||
group = "_jambotron_build"
|
||||
|
||||
workingDir './jambotron-ui' // Path to your Angular project (e.g., './angular-app')
|
||||
// Use 'npm' for Unix-like systems or 'npm.cmd' for Windows
|
||||
group = "_jambotron_build"
|
||||
workingDir './jambotron-ui'
|
||||
executable = Os.isFamily(Os.FAMILY_WINDOWS) ? 'npm.cmd' : 'npm'
|
||||
|
||||
// Your Angular build command
|
||||
args = ['run', 'build']
|
||||
|
||||
args = ['run', 'build_dev']
|
||||
}
|
||||
|
||||
tasks.register('buildAngular_prod', Exec) {
|
||||
group = "_jambotron_build"
|
||||
workingDir './jambotron-ui'
|
||||
executable = Os.isFamily(Os.FAMILY_WINDOWS) ? 'npm.cmd' : 'npm'
|
||||
args = ['run', 'build']
|
||||
}
|
||||
|
||||
tasks.register('deleteStaticFolder_prod', Delete) {
|
||||
group = "_jambotron_build"
|
||||
|
||||
dependsOn buildAngular_prod
|
||||
def dirName = "src/main/resources/static"
|
||||
file(dirName).list().each {
|
||||
f ->
|
||||
delete "${dirName}/${f}"
|
||||
}
|
||||
group = "_jambotron_build"
|
||||
dependsOn buildAngular_prod
|
||||
delete "src/main/resources/static"
|
||||
}
|
||||
|
||||
tasks.register('deleteStaticFolder_dev', Delete) {
|
||||
group = "_jambotron_build"
|
||||
|
||||
dependsOn buildAngular_dev
|
||||
def dirName = "src/main/resources/static"
|
||||
file(dirName).list().each {
|
||||
f ->
|
||||
delete "${dirName}/${f}"
|
||||
}
|
||||
group = "_jambotron_build"
|
||||
dependsOn buildAngular_dev
|
||||
delete "src/main/resources/static"
|
||||
}
|
||||
|
||||
tasks.register('copyAngularBuild_prod', Copy) {
|
||||
group = "_jambotron_build"
|
||||
group = "_jambotron_build"
|
||||
dependsOn deleteStaticFolder_prod
|
||||
from 'jambotron-ui/dist/jambotron-ui/browser'
|
||||
into "src/main/resources/static"
|
||||
}
|
||||
|
||||
dependsOn deleteStaticFolder_prod
|
||||
|
||||
from 'jambotron-ui/dist/jambotron-ui/browser' // Path to your Angular dist folder
|
||||
into "src/main/resources/static" // Path INSIDE the WAR
|
||||
tasks.register('copyAngularBuild_dev', Copy) {
|
||||
group = "_jambotron_build"
|
||||
dependsOn deleteStaticFolder_dev
|
||||
from 'jambotron-ui/dist/jambotron-ui'
|
||||
into "src/main/resources/static"
|
||||
}
|
||||
|
||||
// Говорим задаче обработки ресурсов, что она НЕ ДОЛЖНА трогать статику фронтенда,
|
||||
// пока фронтенд-задача не закончит свою работу.
|
||||
processResources {
|
||||
if (!gradle.startParameter.taskNames.any { it.toLowerCase().contains("dev") })
|
||||
{
|
||||
// В продакшн сборке всегда копируем фронтенд
|
||||
if (!gradle.startParameter.taskNames.any { it.toLowerCase().contains("dev") }) {
|
||||
dependsOn copyAngularBuild_prod
|
||||
}
|
||||
|
||||
}
|
||||
tasks.register('copyAngularBuild_dev', Copy) {
|
||||
group = "_jambotron_build"
|
||||
dependsOn deleteStaticFolder_dev
|
||||
from 'jambotron-ui/dist/jambotron-ui' // Path to your Angular dist folder
|
||||
into "src/main/resources/static" // Path INSIDE the WAR
|
||||
}
|
||||
|
||||
tasks.named('test') {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
useJUnitPlatform()
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
# Основная БД для системных данных (JPA/Hibernate)
|
||||
jambo-postgres:
|
||||
image: postgres:15-alpine
|
||||
container_name: jambo-postgres
|
||||
environment:
|
||||
- POSTGRES_USER=jambotron_admin
|
||||
- POSTGRES_PASSWORD=jambo_secret_pass
|
||||
- POSTGRES_DB=jambotron_dev
|
||||
ports:
|
||||
- "5432:5432"
|
||||
volumes:
|
||||
- jambo_db_dev_data:/var/lib/postgresql/data
|
||||
networks:
|
||||
- jambotron-net
|
||||
|
||||
# Гибкое хранилище для SaaS 2.0 (Метаданные контейнеров)
|
||||
jambotron-mongo:
|
||||
image: mongo:6.0
|
||||
container_name: jambotron-mongo
|
||||
ports:
|
||||
- "27017:27017"
|
||||
volumes:
|
||||
- mongo_dev_data:/data/db
|
||||
networks:
|
||||
- jambotron-net
|
||||
|
||||
# UI для управления БД (Postgres)[cite: 3]
|
||||
jambo-pgadmin:
|
||||
image: dpage/pgadmin4
|
||||
container_name: jambo-pgadmin
|
||||
environment:
|
||||
- PGADMIN_DEFAULT_EMAIL=admin@jambotron.com
|
||||
- PGADMIN_DEFAULT_PASSWORD=admin
|
||||
labels:
|
||||
- "caddy=pgadmin.localhost" # Локальный домен вместо порта 5050
|
||||
- "caddy.reverse_proxy={{upstreams 80}}"
|
||||
ports:
|
||||
- "5050:80"
|
||||
networks:
|
||||
- jambotron-net
|
||||
|
||||
# Контроль кластера (вместо ручного терминала)[cite: 1, 3]
|
||||
portainer:
|
||||
image: portainer/portainer-ce:latest
|
||||
container_name: portainer-dev
|
||||
command: -H unix:///var/run/docker.sock
|
||||
ports:
|
||||
- "9443:9443"
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- portainer_dev_data:/data
|
||||
networks:
|
||||
- jambotron-net
|
||||
# Обратный прокси (Caddy) — сердце маршрутизации
|
||||
caddy:
|
||||
image: lucaslorentz/caddy-docker-proxy:latest
|
||||
container_name: caddy-dev
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
environment:
|
||||
- CADDY_INGRESS_NETWORKS=jambotron-net
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock # Чтобы Caddy видел новые контейнеры[cite: 2, 3]
|
||||
- caddy_dev_data:/data
|
||||
networks:
|
||||
- jambotron-net
|
||||
restart: always
|
||||
|
||||
networks:
|
||||
jambotron-net:
|
||||
external: true
|
||||
|
||||
volumes:
|
||||
jambo_db_dev_data:
|
||||
mongo_dev_data:
|
||||
portainer_dev_data:
|
||||
caddy_dev_data:
|
||||
@@ -82,7 +82,16 @@ services:
|
||||
caddy: test-app1.jambotron.com
|
||||
caddy.reverse_proxy: "{{upstreams 80}}"
|
||||
restart: always
|
||||
|
||||
loki:
|
||||
image: grafana/loki:2.9.0
|
||||
container_name: jambo-loki
|
||||
ports:
|
||||
- "3100:3100"
|
||||
command: -config.file=/etc/loki/local-config.yaml
|
||||
networks:
|
||||
- jambotron-net
|
||||
restart: always
|
||||
|
||||
networks:
|
||||
jambotron-net:
|
||||
name: jambotron-net
|
||||
|
||||
@@ -8,4 +8,8 @@ scrape_configs:
|
||||
|
||||
- job_name: 'cadvisor'
|
||||
static_configs:
|
||||
- targets: ['cadvisor:8080']
|
||||
- targets: ['cadvisor:8080']
|
||||
|
||||
- job_name: 'mongodb'
|
||||
static_configs:
|
||||
- targets: ['mongodb-exporter:9216']
|
||||
@@ -0,0 +1,45 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
# База данных для стейджинга
|
||||
jambo-db-staging:
|
||||
image: postgres:15-alpine
|
||||
container_name: jambo-db-staging
|
||||
restart: always
|
||||
networks:
|
||||
- jambotron-staging-net
|
||||
environment:
|
||||
POSTGRES_USER: ${STAGING_DB_USER}
|
||||
POSTGRES_PASSWORD: ${STAGING_DB_PASSWORD}
|
||||
POSTGRES_DB: ${STAGING_DB_NAME}
|
||||
volumes:
|
||||
- jambo_db_staging_data:/var/lib/postgresql/data
|
||||
|
||||
# Backend-приложение (Staging версия)
|
||||
jambotron-app-stg:
|
||||
image: jambotron-app:stg-latest
|
||||
container_name: jambotron-app-stg
|
||||
restart: always
|
||||
depends_on:
|
||||
- jambo-db-staging
|
||||
networks:
|
||||
- jambotron-staging-net
|
||||
- jambotron-net # Для связи с Caddy
|
||||
environment:
|
||||
SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES_ACTIVE}
|
||||
SPRING_DATASOURCE_URL: jdbc:postgresql://jambo-db-staging:5432/${STAGING_DB_NAME}
|
||||
SPRING_DATASOURCE_USERNAME: ${STAGING_DB_USER}
|
||||
SPRING_DATASOURCE_PASSWORD: ${STAGING_DB_PASSWORD}
|
||||
labels:
|
||||
# Настройки для caddy-docker-proxy
|
||||
caddy: ${STAGING_DOMAIN}
|
||||
caddy.reverse_proxy: "{{upstreams 8080}}"
|
||||
|
||||
networks:
|
||||
jambotron-staging-net:
|
||||
driver: bridge
|
||||
jambotron-net:
|
||||
external: true # Используем существующую сеть
|
||||
|
||||
volumes:
|
||||
jambo_db_staging_data:
|
||||
Reference in New Issue
Block a user