migrate from github
This commit is contained in:
@@ -0,0 +1,68 @@
|
|||||||
|
# host exposed ports
|
||||||
|
NGINX_HTTP_PORT=8080
|
||||||
|
NGINX_HTTPS_PORT=8443
|
||||||
|
BACKEND_GRPC_HOST_PORT=9090
|
||||||
|
BACKEND_DEBUG_HOST_PORT=2345
|
||||||
|
POSTGRES_HOST_PORT=5432
|
||||||
|
REDIS_HOST_PORT=6379
|
||||||
|
RABBITMQ_AMQP_HOST_PORT=5672
|
||||||
|
CONSUL_HOST_PORT=8500
|
||||||
|
ELASTICSEARCH_HOST_PORT=9200
|
||||||
|
|
||||||
|
# internal service ports
|
||||||
|
BACKEND_GRPC_PORT=9090
|
||||||
|
BACKEND_GRPC_WEB_PORT=8080
|
||||||
|
POSTGRES_PORT=5432
|
||||||
|
REDIS_PORT=6379
|
||||||
|
RABBITMQ_AMQP_PORT=5672
|
||||||
|
RABBITMQ_MANAGEMENT_PORT=15672
|
||||||
|
CONSUL_PORT=8500
|
||||||
|
COLLAB_CORE_PORT=1234
|
||||||
|
COLLAB_GATEWAY_PORT=1234
|
||||||
|
MINIO_API_PORT=9000
|
||||||
|
MINIO_CONSOLE_PORT=9001
|
||||||
|
ELASTICSEARCH_PORT=9200
|
||||||
|
REDIS_DB=0
|
||||||
|
|
||||||
|
# internal service hosts
|
||||||
|
POSTGRES_HOST=postgres
|
||||||
|
REDIS_HOST=redis
|
||||||
|
CONSUL_HOST=consul
|
||||||
|
RABBITMQ_HOST=rabbitmq
|
||||||
|
BACKEND_HOST=backend
|
||||||
|
FRONTEND_HOST=frontend
|
||||||
|
COLLAB_HOST=collab
|
||||||
|
COLLAB_CORE_HOST=collab-core
|
||||||
|
MINIO_HOST=minio
|
||||||
|
ELASTICSEARCH_HOST=elasticsearch
|
||||||
|
|
||||||
|
# credentials & secrets
|
||||||
|
POSTGRES_USER=root
|
||||||
|
POSTGRES_PASSWORD=your_password
|
||||||
|
POSTGRES_DB=yoresee_doc_db
|
||||||
|
REDIS_PASSWORD=your_redis_password
|
||||||
|
RABBITMQ_DEFAULT_USER=guest
|
||||||
|
RABBITMQ_DEFAULT_PASS=guest
|
||||||
|
CONSUL_ROOT_TOKEN=yoresee_doc_root_token
|
||||||
|
BACKEND_INTERNAL_RPC_KEY=yoresee_doc_internal_key
|
||||||
|
JWT_SECRET=yoresee_doc_jwt_secret_key
|
||||||
|
MINIO_ROOT_USER=minioadmin
|
||||||
|
MINIO_ROOT_PASSWORD=minioadmin
|
||||||
|
|
||||||
|
# application config
|
||||||
|
VITE_API_BASE_URL=http://localhost:8080
|
||||||
|
VITE_GRPC_WEB_ENDPOINT=/grpc
|
||||||
|
MINIO_BUCKET=yoresee-doc
|
||||||
|
# Keep this aligned with VITE_API_BASE_URL. configure.sh will derive it as ${VITE_API_BASE_URL}/minio.
|
||||||
|
MINIO_BROWSER_REDIRECT_URL=http://localhost:8080/minio
|
||||||
|
DIRTY_DOC_TOPIC=collab.dirty_docs
|
||||||
|
DIRTY_DOC_MQ=rabbitmq
|
||||||
|
NOTIFICATION_MQ=rabbitmq
|
||||||
|
SEARCH_SYNC_MQ=rabbitmq
|
||||||
|
DIRTY_DOC_NOTIFY_THRESHOLD=5
|
||||||
|
|
||||||
|
# elasticsearch
|
||||||
|
ELASTICSEARCH_ENABLED=true
|
||||||
|
ELASTICSEARCH_USERNAME=
|
||||||
|
ELASTICSEARCH_PASSWORD=
|
||||||
|
ELASTICSEARCH_INDEX_PREFIX=yoresee_doc
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
# ignore config files
|
||||||
|
nginx/nginx.conf
|
||||||
|
nginx/conf.d/default.conf
|
||||||
|
|
||||||
|
redis/redis.conf
|
||||||
|
|
||||||
|
rabbitmq/rabbitmq.conf
|
||||||
|
.env
|
||||||
|
|
||||||
|
# ignore log files by suffix
|
||||||
|
*.logs
|
||||||
|
*.log
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
FROM bufbuild/buf:latest
|
||||||
|
|
||||||
|
WORKDIR /workspace/proto
|
||||||
|
|
||||||
|
ENTRYPOINT ["sh", "-c", "\
|
||||||
|
buf generate --template buf.gen.backend.yaml && \
|
||||||
|
buf generate --template buf.gen.collab-go.yaml && \
|
||||||
|
buf generate --template buf.gen.frontend.yaml && \
|
||||||
|
buf generate --template buf.gen.node.yaml && \
|
||||||
|
echo 'Proto generation complete.' \
|
||||||
|
"]
|
||||||
@@ -0,0 +1,324 @@
|
|||||||
|
services:
|
||||||
|
proto-gen:
|
||||||
|
build:
|
||||||
|
context: ../proto
|
||||||
|
dockerfile: ../deploy/Dockerfile.proto-gen
|
||||||
|
image: yoresee_doc_proto_gen:latest
|
||||||
|
container_name: yoresee_doc_proto_gen
|
||||||
|
volumes:
|
||||||
|
- ../proto:/workspace/proto
|
||||||
|
- ../backend/pkg/gen:/workspace/backend/pkg/gen
|
||||||
|
- ../collab-go/pkg/gen:/workspace/collab-go/pkg/gen
|
||||||
|
- ../frontend/src/gen:/workspace/frontend/src/gen
|
||||||
|
- ../collab/src/gen:/workspace/collab/src/gen
|
||||||
|
|
||||||
|
nginx:
|
||||||
|
image: nginx:alpine
|
||||||
|
container_name: yoresee_doc_nginx
|
||||||
|
ports:
|
||||||
|
- "${NGINX_HTTP_PORT:-8080}:80"
|
||||||
|
- "${NGINX_HTTPS_PORT:-8443}:443"
|
||||||
|
volumes:
|
||||||
|
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
|
||||||
|
- ./nginx/conf.d/default.conf:/etc/nginx/conf.d/default.conf
|
||||||
|
- ./logs/nginx:/var/log/nginx
|
||||||
|
depends_on:
|
||||||
|
- frontend
|
||||||
|
- backend
|
||||||
|
- collab
|
||||||
|
- minio
|
||||||
|
networks:
|
||||||
|
- yoresee_doc_network
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
frontend:
|
||||||
|
build:
|
||||||
|
context: ../frontend
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
target: dev
|
||||||
|
image: yoresee_doc_frontend_dev:latest
|
||||||
|
container_name: yoresee_doc_frontend
|
||||||
|
volumes:
|
||||||
|
- ../frontend:/app
|
||||||
|
- /app/node_modules
|
||||||
|
environment:
|
||||||
|
- NODE_ENV=development
|
||||||
|
- VITE_API_BASE_URL=${VITE_API_BASE_URL:-http://localhost:8080}
|
||||||
|
- VITE_GRPC_WEB_ENDPOINT=${VITE_GRPC_WEB_ENDPOINT:-/grpc}
|
||||||
|
networks:
|
||||||
|
- yoresee_doc_network
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
postgres:
|
||||||
|
image: postgres:15-alpine
|
||||||
|
container_name: yoresee_doc_postgres
|
||||||
|
environment:
|
||||||
|
POSTGRES_USER: ${POSTGRES_USER:-root}
|
||||||
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-your_password}
|
||||||
|
POSTGRES_DB: ${POSTGRES_DB:-yoresee_doc_db}
|
||||||
|
ports:
|
||||||
|
- "${POSTGRES_HOST_PORT:-5432}:${POSTGRES_PORT:-5432}"
|
||||||
|
volumes:
|
||||||
|
- yoresee_doc_postgres_data:/var/lib/postgresql/data
|
||||||
|
networks:
|
||||||
|
- yoresee_doc_network
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-root} -d ${POSTGRES_DB:-yoresee_doc_db}"]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 3s
|
||||||
|
retries: 5
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
redis:
|
||||||
|
image: redis:7-alpine
|
||||||
|
container_name: yoresee_doc_redis
|
||||||
|
environment:
|
||||||
|
REDIS_PASSWORD: ${REDIS_PASSWORD:-your_redis_password}
|
||||||
|
ports:
|
||||||
|
- "${REDIS_HOST_PORT:-6379}:${REDIS_PORT:-6379}"
|
||||||
|
volumes:
|
||||||
|
- yoresee_doc_redis_data:/data
|
||||||
|
- ./redis/redis.conf:/usr/local/etc/redis/redis.conf
|
||||||
|
command: redis-server /usr/local/etc/redis/redis.conf
|
||||||
|
networks:
|
||||||
|
- yoresee_doc_network
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "redis-cli", "--raw", "incr", "ping"]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 3s
|
||||||
|
retries: 5
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
consul:
|
||||||
|
image: hashicorp/consul:1.16
|
||||||
|
container_name: yoresee_doc_consul
|
||||||
|
command: "agent -dev -client=0.0.0.0 -ui"
|
||||||
|
environment:
|
||||||
|
CONSUL_LOCAL_CONFIG: >-
|
||||||
|
{"acl":{"enabled":true,"default_policy":"deny","down_policy":"extend-cache","enable_token_persistence":true,"tokens":{"initial_management":"${CONSUL_ROOT_TOKEN:-yoresee_doc_root_token}"}}}
|
||||||
|
ports:
|
||||||
|
- "${CONSUL_HOST_PORT:-8500}:${CONSUL_PORT:-8500}"
|
||||||
|
volumes:
|
||||||
|
- yoresee_doc_consul_data:/consul/data
|
||||||
|
networks:
|
||||||
|
- yoresee_doc_network
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
rabbitmq:
|
||||||
|
image: rabbitmq:3-management
|
||||||
|
container_name: yoresee_doc_rabbitmq
|
||||||
|
environment:
|
||||||
|
RABBITMQ_DEFAULT_USER: ${RABBITMQ_DEFAULT_USER:-guest}
|
||||||
|
RABBITMQ_DEFAULT_PASS: ${RABBITMQ_DEFAULT_PASS:-guest}
|
||||||
|
ports:
|
||||||
|
- "${RABBITMQ_AMQP_HOST_PORT:-5672}:${RABBITMQ_AMQP_PORT:-5672}"
|
||||||
|
volumes:
|
||||||
|
- yoresee_doc_rabbitmq_data:/var/lib/rabbitmq
|
||||||
|
- ./rabbitmq/rabbitmq.conf:/etc/rabbitmq/rabbitmq.conf:ro
|
||||||
|
- ./logs/rabbitmq:/var/log/rabbitmq
|
||||||
|
networks:
|
||||||
|
- yoresee_doc_network
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "rabbitmq-diagnostics", "-q", "ping"]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 3s
|
||||||
|
retries: 5
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
minio:
|
||||||
|
image: minio/minio:latest
|
||||||
|
container_name: yoresee_doc_minio
|
||||||
|
command: server /data --console-address ":${MINIO_CONSOLE_PORT:-9001}"
|
||||||
|
environment:
|
||||||
|
MINIO_ROOT_USER: ${MINIO_ROOT_USER:-minioadmin}
|
||||||
|
MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD:-minioadmin}
|
||||||
|
MINIO_BROWSER_REDIRECT_URL: ${MINIO_BROWSER_REDIRECT_URL:-http://localhost:8080/minio}
|
||||||
|
volumes:
|
||||||
|
- yoresee_doc_minio_data:/data
|
||||||
|
networks:
|
||||||
|
- yoresee_doc_network
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
elasticsearch:
|
||||||
|
image: docker.elastic.co/elasticsearch/elasticsearch:8.15.3
|
||||||
|
container_name: yoresee_doc_elasticsearch
|
||||||
|
environment:
|
||||||
|
- discovery.type=single-node
|
||||||
|
- xpack.security.enabled=false
|
||||||
|
- xpack.security.enrollment.enabled=false
|
||||||
|
- ES_JAVA_OPTS=-Xms512m -Xmx512m
|
||||||
|
ports:
|
||||||
|
- "${ELASTICSEARCH_HOST_PORT:-9200}:${ELASTICSEARCH_PORT:-9200}"
|
||||||
|
volumes:
|
||||||
|
- yoresee_doc_elasticsearch_data:/usr/share/elasticsearch/data
|
||||||
|
networks:
|
||||||
|
- yoresee_doc_network
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
backend:
|
||||||
|
build:
|
||||||
|
context: ../backend
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
target: dev
|
||||||
|
image: yoresee_doc_backend_dev:latest
|
||||||
|
container_name: yoresee_doc_backend
|
||||||
|
volumes:
|
||||||
|
- ../backend:/app
|
||||||
|
ports:
|
||||||
|
- "${BACKEND_DEBUG_HOST_PORT:-2345}:2345"
|
||||||
|
- "${BACKEND_GRPC_HOST_PORT:-9090}:${BACKEND_GRPC_PORT:-9090}"
|
||||||
|
environment:
|
||||||
|
- BACKEND_INTERNAL_RPC_KEY=${BACKEND_INTERNAL_RPC_KEY:-yoresee_doc_internal_key}
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
redis:
|
||||||
|
condition: service_healthy
|
||||||
|
rabbitmq:
|
||||||
|
condition: service_healthy
|
||||||
|
minio:
|
||||||
|
condition: service_started
|
||||||
|
elasticsearch:
|
||||||
|
condition: service_started
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "wget", "--spider", "-q", "http://${BACKEND_HOST:-backend}:${BACKEND_GRPC_PORT:-9090}/health"]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 3s
|
||||||
|
retries: 20
|
||||||
|
start_period: 30s
|
||||||
|
networks:
|
||||||
|
- yoresee_doc_network
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
collab-core:
|
||||||
|
build:
|
||||||
|
context: ..
|
||||||
|
dockerfile: collab/Dockerfile
|
||||||
|
image: yoresee_doc_collab_core:latest
|
||||||
|
container_name: yoresee_doc_collab_core
|
||||||
|
environment:
|
||||||
|
- REDIS_HOST=${REDIS_HOST:-redis}
|
||||||
|
- REDIS_PORT=${REDIS_PORT:-6379}
|
||||||
|
- REDIS_PASSWORD=${REDIS_PASSWORD:-your_redis_password}
|
||||||
|
- REDIS_DB=${REDIS_DB:-0}
|
||||||
|
- BACKEND_ADDR=${BACKEND_HOST:-backend}:${BACKEND_GRPC_PORT:-9090}
|
||||||
|
- DIRTY_DOC_MQ=${DIRTY_DOC_MQ:-rabbitmq}
|
||||||
|
- DIRTY_DOC_TOPIC=${DIRTY_DOC_TOPIC:-collab.dirty_docs}
|
||||||
|
- RABBITMQ_URL=amqp://${RABBITMQ_DEFAULT_USER:-guest}:${RABBITMQ_DEFAULT_PASS:-guest}@${RABBITMQ_HOST:-rabbitmq}:${RABBITMQ_AMQP_PORT:-5672}/
|
||||||
|
- INTERNAL_RPC_KEY=${BACKEND_INTERNAL_RPC_KEY:-yoresee_doc_internal_key}
|
||||||
|
- DIRTY_DOC_NOTIFY_THRESHOLD=${DIRTY_DOC_NOTIFY_THRESHOLD:-5}
|
||||||
|
depends_on:
|
||||||
|
redis:
|
||||||
|
condition: service_healthy
|
||||||
|
backend:
|
||||||
|
condition: service_healthy
|
||||||
|
rabbitmq:
|
||||||
|
condition: service_healthy
|
||||||
|
networks:
|
||||||
|
- yoresee_doc_network
|
||||||
|
volumes:
|
||||||
|
- ../collab:/app
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
collab:
|
||||||
|
build:
|
||||||
|
context: ../collab-go
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
image: yoresee_doc_collab_gateway:latest
|
||||||
|
container_name: yoresee_doc_collab
|
||||||
|
environment:
|
||||||
|
- ADDR=:${COLLAB_GATEWAY_PORT:-1234}
|
||||||
|
- JWT_SECRET=${JWT_SECRET:-yoresee_doc_jwt_secret_key}
|
||||||
|
- COLLAB_CORE_URL=ws://${COLLAB_CORE_HOST:-collab-core}:${COLLAB_CORE_PORT:-1234}
|
||||||
|
- BACKEND_GRPC_ADDR=${BACKEND_HOST:-backend}:${BACKEND_GRPC_PORT:-9090}
|
||||||
|
- INTERNAL_RPC_KEY=${BACKEND_INTERNAL_RPC_KEY:-yoresee_doc_internal_key}
|
||||||
|
volumes:
|
||||||
|
- ../collab-go:/app
|
||||||
|
depends_on:
|
||||||
|
- collab-core
|
||||||
|
networks:
|
||||||
|
- yoresee_doc_network
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
snapshot-worker:
|
||||||
|
build:
|
||||||
|
context: ../backend
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
target: dev
|
||||||
|
image: yoresee_doc_snapshot_worker_dev:latest
|
||||||
|
container_name: yoresee_doc_snapshot_worker
|
||||||
|
volumes:
|
||||||
|
- ../backend:/app
|
||||||
|
environment:
|
||||||
|
- COLLAB_CORE_HTTP=http://${COLLAB_CORE_HOST:-collab-core}:${COLLAB_CORE_PORT:-1234}
|
||||||
|
command: sh -c "go mod download && go run ./cmd/snapshot-worker"
|
||||||
|
depends_on:
|
||||||
|
rabbitmq:
|
||||||
|
condition: service_healthy
|
||||||
|
redis:
|
||||||
|
condition: service_healthy
|
||||||
|
elasticsearch:
|
||||||
|
condition: service_started
|
||||||
|
networks:
|
||||||
|
- yoresee_doc_network
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
notification-worker:
|
||||||
|
build:
|
||||||
|
context: ../backend
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
target: dev
|
||||||
|
image: yoresee_doc_notification_worker_dev:latest
|
||||||
|
container_name: yoresee_doc_notification_worker
|
||||||
|
volumes:
|
||||||
|
- ../backend:/app
|
||||||
|
environment:
|
||||||
|
- NOTIFICATION_MQ=${NOTIFICATION_MQ:-rabbitmq}
|
||||||
|
command: sh -c "go mod download && go run ./cmd/notification-worker"
|
||||||
|
depends_on:
|
||||||
|
rabbitmq:
|
||||||
|
condition: service_healthy
|
||||||
|
redis:
|
||||||
|
condition: service_healthy
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
networks:
|
||||||
|
- yoresee_doc_network
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
search-sync-worker:
|
||||||
|
build:
|
||||||
|
context: ../backend
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
target: dev
|
||||||
|
image: yoresee_doc_search_sync_worker_dev:latest
|
||||||
|
container_name: yoresee_doc_search_sync_worker
|
||||||
|
volumes:
|
||||||
|
- ../backend:/app
|
||||||
|
environment:
|
||||||
|
- SEARCH_SYNC_MQ=${SEARCH_SYNC_MQ:-rabbitmq}
|
||||||
|
command: sh -c "go mod download && go run ./cmd/search-sync-worker"
|
||||||
|
depends_on:
|
||||||
|
rabbitmq:
|
||||||
|
condition: service_healthy
|
||||||
|
redis:
|
||||||
|
condition: service_healthy
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
elasticsearch:
|
||||||
|
condition: service_started
|
||||||
|
networks:
|
||||||
|
- yoresee_doc_network
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
yoresee_doc_postgres_data:
|
||||||
|
yoresee_doc_redis_data:
|
||||||
|
yoresee_doc_consul_data:
|
||||||
|
yoresee_doc_rabbitmq_data:
|
||||||
|
yoresee_doc_minio_data:
|
||||||
|
yoresee_doc_elasticsearch_data:
|
||||||
|
|
||||||
|
networks:
|
||||||
|
yoresee_doc_network:
|
||||||
|
driver: bridge
|
||||||
@@ -0,0 +1,251 @@
|
|||||||
|
services:
|
||||||
|
nginx:
|
||||||
|
image: nginx:alpine
|
||||||
|
container_name: yoresee_doc_nginx
|
||||||
|
ports:
|
||||||
|
- "${NGINX_HTTP_PORT:-8080}:80"
|
||||||
|
- "${NGINX_HTTPS_PORT:-8443}:443"
|
||||||
|
volumes:
|
||||||
|
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
|
||||||
|
- ./nginx/conf.d/default.conf:/etc/nginx/conf.d/default.conf
|
||||||
|
- ./logs/nginx:/var/log/nginx
|
||||||
|
depends_on:
|
||||||
|
- frontend
|
||||||
|
- backend
|
||||||
|
- collab
|
||||||
|
- minio
|
||||||
|
networks:
|
||||||
|
- yoresee_doc_network
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
frontend:
|
||||||
|
build:
|
||||||
|
context: ..
|
||||||
|
dockerfile: frontend/Dockerfile.prod
|
||||||
|
target: runner
|
||||||
|
image: yoresee_doc_frontend_runner:latest
|
||||||
|
container_name: yoresee_doc_frontend
|
||||||
|
environment:
|
||||||
|
- NODE_ENV=production
|
||||||
|
- VITE_API_BASE_URL=${VITE_API_BASE_URL:-http://localhost:8080}
|
||||||
|
- VITE_GRPC_WEB_ENDPOINT=${VITE_GRPC_WEB_ENDPOINT:-/grpc}
|
||||||
|
networks:
|
||||||
|
- yoresee_doc_network
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
postgres:
|
||||||
|
image: postgres:15-alpine
|
||||||
|
container_name: yoresee_doc_postgres
|
||||||
|
environment:
|
||||||
|
POSTGRES_USER: ${POSTGRES_USER:-root}
|
||||||
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-your_password}
|
||||||
|
POSTGRES_DB: ${POSTGRES_DB:-yoresee_doc_db}
|
||||||
|
volumes:
|
||||||
|
- yoresee_doc_postgres_data:/var/lib/postgresql/data
|
||||||
|
networks:
|
||||||
|
- yoresee_doc_network
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
redis:
|
||||||
|
image: redis:7-alpine
|
||||||
|
container_name: yoresee_doc_redis
|
||||||
|
environment:
|
||||||
|
REDIS_PASSWORD: ${REDIS_PASSWORD:-your_redis_password}
|
||||||
|
volumes:
|
||||||
|
- yoresee_doc_redis_data:/data
|
||||||
|
- ./redis/redis.conf:/usr/local/etc/redis/redis.conf
|
||||||
|
command: redis-server /usr/local/etc/redis/redis.conf
|
||||||
|
networks:
|
||||||
|
- yoresee_doc_network
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
consul:
|
||||||
|
image: hashicorp/consul:1.16
|
||||||
|
container_name: yoresee_doc_consul
|
||||||
|
command: "agent -dev -client=0.0.0.0 -ui"
|
||||||
|
environment:
|
||||||
|
CONSUL_LOCAL_CONFIG: >-
|
||||||
|
{"acl":{"enabled":true,"default_policy":"deny","down_policy":"extend-cache","enable_token_persistence":true,"tokens":{"initial_management":"${CONSUL_ROOT_TOKEN:-yoresee_doc_root_token}"}}}
|
||||||
|
ports:
|
||||||
|
- "${CONSUL_HOST_PORT:-8500}:${CONSUL_PORT:-8500}"
|
||||||
|
volumes:
|
||||||
|
- yoresee_doc_consul_data:/consul/data
|
||||||
|
networks:
|
||||||
|
- yoresee_doc_network
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
rabbitmq:
|
||||||
|
image: rabbitmq:3-management
|
||||||
|
container_name: yoresee_doc_rabbitmq
|
||||||
|
environment:
|
||||||
|
RABBITMQ_DEFAULT_USER: ${RABBITMQ_DEFAULT_USER:-guest}
|
||||||
|
RABBITMQ_DEFAULT_PASS: ${RABBITMQ_DEFAULT_PASS:-guest}
|
||||||
|
volumes:
|
||||||
|
- yoresee_doc_rabbitmq_data:/var/lib/rabbitmq
|
||||||
|
- ./rabbitmq/rabbitmq.conf:/etc/rabbitmq/rabbitmq.conf:ro
|
||||||
|
- ./logs/rabbitmq:/var/log/rabbitmq
|
||||||
|
networks:
|
||||||
|
- yoresee_doc_network
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
minio:
|
||||||
|
image: minio/minio:latest
|
||||||
|
container_name: yoresee_doc_minio
|
||||||
|
command: server /data --console-address ":${MINIO_CONSOLE_PORT:-9001}"
|
||||||
|
environment:
|
||||||
|
MINIO_ROOT_USER: ${MINIO_ROOT_USER:-minioadmin}
|
||||||
|
MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD:-minioadmin}
|
||||||
|
MINIO_BROWSER_REDIRECT_URL: ${MINIO_BROWSER_REDIRECT_URL:-http://localhost:8080/minio}
|
||||||
|
volumes:
|
||||||
|
- yoresee_doc_minio_data:/data
|
||||||
|
networks:
|
||||||
|
- yoresee_doc_network
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
elasticsearch:
|
||||||
|
image: docker.elastic.co/elasticsearch/elasticsearch:8.15.3
|
||||||
|
container_name: yoresee_doc_elasticsearch
|
||||||
|
environment:
|
||||||
|
- discovery.type=single-node
|
||||||
|
- xpack.security.enabled=false
|
||||||
|
- xpack.security.enrollment.enabled=false
|
||||||
|
- ES_JAVA_OPTS=-Xms512m -Xmx512m
|
||||||
|
volumes:
|
||||||
|
- yoresee_doc_elasticsearch_data:/usr/share/elasticsearch/data
|
||||||
|
networks:
|
||||||
|
- yoresee_doc_network
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
backend:
|
||||||
|
build:
|
||||||
|
context: ..
|
||||||
|
dockerfile: backend/Dockerfile.prod
|
||||||
|
target: runner
|
||||||
|
image: yoresee_doc_backend_runner:latest
|
||||||
|
container_name: yoresee_doc_backend
|
||||||
|
volumes:
|
||||||
|
- ../backend/config.toml:/app/config.toml
|
||||||
|
environment:
|
||||||
|
- BACKEND_INTERNAL_RPC_KEY=${BACKEND_INTERNAL_RPC_KEY:-yoresee_doc_internal_key}
|
||||||
|
ports:
|
||||||
|
- "${BACKEND_GRPC_HOST_PORT:-9090}:${BACKEND_GRPC_PORT:-9090}"
|
||||||
|
depends_on:
|
||||||
|
- postgres
|
||||||
|
- redis
|
||||||
|
- consul
|
||||||
|
- rabbitmq
|
||||||
|
- minio
|
||||||
|
- elasticsearch
|
||||||
|
networks:
|
||||||
|
- yoresee_doc_network
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
collab-core:
|
||||||
|
build:
|
||||||
|
context: ..
|
||||||
|
dockerfile: collab/Dockerfile.prod
|
||||||
|
image: yoresee_doc_collab_core:latest
|
||||||
|
container_name: yoresee_doc_collab_core
|
||||||
|
environment:
|
||||||
|
- REDIS_HOST=${REDIS_HOST:-redis}
|
||||||
|
- REDIS_PORT=${REDIS_PORT:-6379}
|
||||||
|
- REDIS_PASSWORD=${REDIS_PASSWORD:-your_redis_password}
|
||||||
|
- REDIS_DB=${REDIS_DB:-0}
|
||||||
|
- BACKEND_ADDR=${BACKEND_HOST:-backend}:${BACKEND_GRPC_PORT:-9090}
|
||||||
|
- DIRTY_DOC_MQ=${DIRTY_DOC_MQ:-rabbitmq}
|
||||||
|
- DIRTY_DOC_TOPIC=${DIRTY_DOC_TOPIC:-collab.dirty_docs}
|
||||||
|
- RABBITMQ_URL=amqp://${RABBITMQ_DEFAULT_USER:-guest}:${RABBITMQ_DEFAULT_PASS:-guest}@${RABBITMQ_HOST:-rabbitmq}:${RABBITMQ_AMQP_PORT:-5672}/
|
||||||
|
- INTERNAL_RPC_KEY=${BACKEND_INTERNAL_RPC_KEY:-yoresee_doc_internal_key}
|
||||||
|
- DIRTY_DOC_NOTIFY_THRESHOLD=${DIRTY_DOC_NOTIFY_THRESHOLD:-200}
|
||||||
|
depends_on:
|
||||||
|
- redis
|
||||||
|
- backend
|
||||||
|
- rabbitmq
|
||||||
|
networks:
|
||||||
|
- yoresee_doc_network
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
collab:
|
||||||
|
build:
|
||||||
|
context: ..
|
||||||
|
dockerfile: collab-go/Dockerfile.prod
|
||||||
|
image: yoresee_doc_collab_gateway:latest
|
||||||
|
container_name: yoresee_doc_collab
|
||||||
|
environment:
|
||||||
|
- ADDR=:${COLLAB_GATEWAY_PORT:-1234}
|
||||||
|
- JWT_SECRET=${JWT_SECRET:-yoresee_doc_jwt_secret_key}
|
||||||
|
- COLLAB_CORE_URL=ws://${COLLAB_CORE_HOST:-collab-core}:${COLLAB_CORE_PORT:-1234}
|
||||||
|
- BACKEND_GRPC_ADDR=${BACKEND_HOST:-backend}:${BACKEND_GRPC_PORT:-9090}
|
||||||
|
- INTERNAL_RPC_KEY=${BACKEND_INTERNAL_RPC_KEY:-yoresee_doc_internal_key}
|
||||||
|
depends_on:
|
||||||
|
- collab-core
|
||||||
|
networks:
|
||||||
|
- yoresee_doc_network
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
snapshot-worker:
|
||||||
|
build:
|
||||||
|
context: ..
|
||||||
|
dockerfile: backend/Dockerfile.snapshot.prod
|
||||||
|
image: yoresee_doc_snapshot_worker:latest
|
||||||
|
container_name: yoresee_doc_snapshot_worker
|
||||||
|
volumes:
|
||||||
|
- ../backend/config.toml:/app/config.toml
|
||||||
|
environment:
|
||||||
|
- COLLAB_CORE_HTTP=http://${COLLAB_CORE_HOST:-collab-core}:${COLLAB_CORE_PORT:-1234}
|
||||||
|
depends_on:
|
||||||
|
- rabbitmq
|
||||||
|
- redis
|
||||||
|
- elasticsearch
|
||||||
|
networks:
|
||||||
|
- yoresee_doc_network
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
notification-worker:
|
||||||
|
build:
|
||||||
|
context: ..
|
||||||
|
dockerfile: backend/Dockerfile.notification.prod
|
||||||
|
image: yoresee_doc_notification_worker:latest
|
||||||
|
container_name: yoresee_doc_notification_worker
|
||||||
|
volumes:
|
||||||
|
- ../backend/config.toml:/app/config.toml
|
||||||
|
environment:
|
||||||
|
- NOTIFICATION_MQ=${NOTIFICATION_MQ:-rabbitmq}
|
||||||
|
depends_on:
|
||||||
|
- rabbitmq
|
||||||
|
- redis
|
||||||
|
- postgres
|
||||||
|
networks:
|
||||||
|
- yoresee_doc_network
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
search-sync-worker:
|
||||||
|
build:
|
||||||
|
context: ..
|
||||||
|
dockerfile: backend/Dockerfile.search-sync.prod
|
||||||
|
image: yoresee_doc_search_sync_worker:latest
|
||||||
|
container_name: yoresee_doc_search_sync_worker
|
||||||
|
volumes:
|
||||||
|
- ../backend/config.toml:/app/config.toml
|
||||||
|
environment:
|
||||||
|
- SEARCH_SYNC_MQ=${SEARCH_SYNC_MQ:-rabbitmq}
|
||||||
|
depends_on:
|
||||||
|
- rabbitmq
|
||||||
|
- redis
|
||||||
|
- postgres
|
||||||
|
- elasticsearch
|
||||||
|
networks:
|
||||||
|
- yoresee_doc_network
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
yoresee_doc_postgres_data:
|
||||||
|
yoresee_doc_redis_data:
|
||||||
|
yoresee_doc_consul_data:
|
||||||
|
yoresee_doc_rabbitmq_data:
|
||||||
|
yoresee_doc_minio_data:
|
||||||
|
yoresee_doc_elasticsearch_data:
|
||||||
|
|
||||||
|
networks:
|
||||||
|
yoresee_doc_network:
|
||||||
|
driver: bridge
|
||||||
@@ -0,0 +1,130 @@
|
|||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name localhost;
|
||||||
|
client_max_body_size 5m;
|
||||||
|
# Uncomment the following block (Line6 to Line24) to enable redirect HTTP to HTTPS
|
||||||
|
# Redirect HTTP to HTTPS
|
||||||
|
# Using 8443 port because that is what is exposed in docker-compose
|
||||||
|
# location / {
|
||||||
|
# return 301 https://$host:8443$request_uri;
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
|
||||||
|
# server {
|
||||||
|
# listen 443 ssl;
|
||||||
|
# server_name localhost;
|
||||||
|
|
||||||
|
# ssl_certificate /etc/nginx/ssl/server.crt;
|
||||||
|
# ssl_certificate_key /etc/nginx/ssl/server.key;
|
||||||
|
|
||||||
|
# ssl_session_cache shared:SSL:1m;
|
||||||
|
# ssl_session_timeout 5m;
|
||||||
|
|
||||||
|
# ssl_ciphers HIGH:!aNULL:!MD5;
|
||||||
|
# ssl_prefer_server_ciphers on;
|
||||||
|
|
||||||
|
# gRPC endpoint
|
||||||
|
location /grpc/ {
|
||||||
|
if ($request_method = OPTIONS) {
|
||||||
|
add_header 'Access-Control-Allow-Origin' "$http_origin" always;
|
||||||
|
add_header 'Access-Control-Allow-Credentials' 'true' always;
|
||||||
|
add_header 'Access-Control-Allow-Methods' 'POST,GET,OPTIONS' always;
|
||||||
|
add_header 'Access-Control-Allow-Headers' 'Accept,Accept-Language,Content-Type,Content-Length,X-Grpc-Web,X-User-Agent,Grpc-Timeout,Authorization,Connect-Protocol-Version' always;
|
||||||
|
return 204;
|
||||||
|
}
|
||||||
|
proxy_pass http://${BACKEND_HOST}:${BACKEND_GRPC_WEB_PORT}/;
|
||||||
|
proxy_set_header Host $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-Grpc-Web $http_x_grpc_web;
|
||||||
|
proxy_set_header X-User-Agent $http_x_user_agent;
|
||||||
|
}
|
||||||
|
|
||||||
|
# MinIO Console
|
||||||
|
location = /minio {
|
||||||
|
return 301 /minio/;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /minio/ {
|
||||||
|
rewrite ^/minio/(.*)$ /$1 break;
|
||||||
|
proxy_pass http://${MINIO_HOST}:${MINIO_CONSOLE_PORT};
|
||||||
|
proxy_set_header Host $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-Prefix /minio;
|
||||||
|
proxy_redirect off;
|
||||||
|
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection $connection_upgrade;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Public storage path
|
||||||
|
location = /storage {
|
||||||
|
return 301 /storage/;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /storage/ {
|
||||||
|
rewrite ^/storage/(.*)$ /${MINIO_BUCKET}/$1 break;
|
||||||
|
proxy_pass http://${MINIO_HOST}:${MINIO_API_PORT};
|
||||||
|
proxy_set_header Host ${MINIO_HOST}:${MINIO_API_PORT};
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Frontend (dev/prod on same port)
|
||||||
|
location / {
|
||||||
|
proxy_pass http://${FRONTEND_HOST}:80;
|
||||||
|
proxy_set_header Host $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;
|
||||||
|
|
||||||
|
# Vite HMR WebSocket support
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection $connection_upgrade;
|
||||||
|
}
|
||||||
|
|
||||||
|
# New collab WebSocket path
|
||||||
|
location = /ws/doc {
|
||||||
|
return 301 /ws/doc/;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /ws/doc/ {
|
||||||
|
proxy_pass http://${COLLAB_HOST}:${COLLAB_GATEWAY_PORT};
|
||||||
|
proxy_set_header Host $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_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection $connection_upgrade;
|
||||||
|
}
|
||||||
|
|
||||||
|
# RabbitMQ Management Interface
|
||||||
|
location /rabbitmq/ {
|
||||||
|
proxy_pass http://${RABBITMQ_HOST}:${RABBITMQ_MANAGEMENT_PORT}/;
|
||||||
|
proxy_set_header Host $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_redirect off;
|
||||||
|
|
||||||
|
# Handle WebSocket connections for management UI
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
error_page 404 /404.html;
|
||||||
|
error_page 500 502 503 504 /50x.html;
|
||||||
|
location = /50x.html {
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
user nginx;
|
||||||
|
worker_processes auto;
|
||||||
|
|
||||||
|
error_log /var/log/nginx/error.log warn;
|
||||||
|
pid /var/run/nginx.pid;
|
||||||
|
|
||||||
|
events {
|
||||||
|
worker_connections 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
http {
|
||||||
|
include /etc/nginx/mime.types;
|
||||||
|
default_type application/octet-stream;
|
||||||
|
|
||||||
|
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||||
|
'$status $body_bytes_sent "$http_referer" '
|
||||||
|
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||||
|
|
||||||
|
access_log /var/log/nginx/access.log main;
|
||||||
|
|
||||||
|
sendfile on;
|
||||||
|
#tcp_nopush on;
|
||||||
|
|
||||||
|
keepalive_timeout 65;
|
||||||
|
|
||||||
|
#gzip on;
|
||||||
|
|
||||||
|
map $http_upgrade $connection_upgrade {
|
||||||
|
default upgrade;
|
||||||
|
'' close;
|
||||||
|
}
|
||||||
|
|
||||||
|
include /etc/nginx/conf.d/*.conf;
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
# RabbitMQ Configuration File - Template
|
||||||
|
|
||||||
|
# Default user and password
|
||||||
|
default_user = ${RABBITMQ_DEFAULT_USER}
|
||||||
|
default_pass = ${RABBITMQ_DEFAULT_PASS}
|
||||||
|
|
||||||
|
# Management plugin
|
||||||
|
management.tcp.port = ${RABBITMQ_MANAGEMENT_PORT}
|
||||||
|
|
||||||
|
# Networking
|
||||||
|
listeners.tcp.default = ${RABBITMQ_AMQP_PORT}
|
||||||
|
|
||||||
|
# Memory-based DB configuration
|
||||||
|
vm_memory_high_watermark.relative = 0.6
|
||||||
|
|
||||||
|
# Logging
|
||||||
|
log.file.level = info
|
||||||
|
|
||||||
|
# Keep RabbitMQ default auth mechanisms (PLAIN/AMQPLAIN) for broad client compatibility.
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
bind 0.0.0.0
|
||||||
|
protected-mode yes
|
||||||
|
requirepass ${REDIS_PASSWORD}
|
||||||
@@ -0,0 +1,111 @@
|
|||||||
|
#Requires -Version 5.1
|
||||||
|
Set-StrictMode -Version Latest
|
||||||
|
$ErrorActionPreference = 'Stop'
|
||||||
|
|
||||||
|
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Definition
|
||||||
|
$BasePath = (Resolve-Path "$ScriptDir\..\.." ).Path
|
||||||
|
$DeployDir = "$BasePath\deploy"
|
||||||
|
$EnvFile = "$DeployDir\.env"
|
||||||
|
$EnvExampleFile = "$DeployDir\.env.example"
|
||||||
|
|
||||||
|
if (-not (Test-Path $EnvExampleFile)) {
|
||||||
|
Write-Error "Missing required file: $EnvExampleFile"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-not (Test-Path $EnvFile)) {
|
||||||
|
Copy-Item $EnvExampleFile $EnvFile
|
||||||
|
}
|
||||||
|
|
||||||
|
# Load key=value pairs from a .env file into a hashtable (last value wins)
|
||||||
|
function Read-EnvFile([string]$Path) {
|
||||||
|
$map = @{}
|
||||||
|
foreach ($line in (Get-Content $Path)) {
|
||||||
|
if ($line -match '^\s*#' -or $line.Trim() -eq '') { continue }
|
||||||
|
$idx = $line.IndexOf('=')
|
||||||
|
if ($idx -lt 1) { continue }
|
||||||
|
$map[$line.Substring(0, $idx).Trim()] = $line.Substring($idx + 1)
|
||||||
|
}
|
||||||
|
return $map
|
||||||
|
}
|
||||||
|
|
||||||
|
# Write or update a single key in the .env file
|
||||||
|
function Update-EnvKey([string]$Key, [string]$Value) {
|
||||||
|
$lines = Get-Content $EnvFile
|
||||||
|
$updated = $false
|
||||||
|
$result = foreach ($line in $lines) {
|
||||||
|
if ($line -match "^$Key=") { "$Key=$Value"; $updated = $true }
|
||||||
|
else { $line }
|
||||||
|
}
|
||||||
|
if (-not $updated) { $result += "$Key=$Value" }
|
||||||
|
$result | Set-Content $EnvFile
|
||||||
|
}
|
||||||
|
|
||||||
|
# Prompt the user for a value, showing the current default in brackets
|
||||||
|
function Prompt-Value([string]$Key, [string]$Label, [string]$Fallback) {
|
||||||
|
$current = if ($script:cfg.ContainsKey($Key) -and $script:cfg[$Key] -ne '') {
|
||||||
|
$script:cfg[$Key]
|
||||||
|
} else { $Fallback }
|
||||||
|
|
||||||
|
$input = Read-Host "$Label [$current]"
|
||||||
|
if ([string]::IsNullOrEmpty($input)) { $input = $current }
|
||||||
|
|
||||||
|
$script:cfg[$Key] = $input
|
||||||
|
Update-EnvKey $Key $input
|
||||||
|
}
|
||||||
|
|
||||||
|
# Merge example defaults then overlay with actual .env values
|
||||||
|
$script:cfg = Read-EnvFile $EnvExampleFile
|
||||||
|
foreach ($kv in (Read-EnvFile $EnvFile).GetEnumerator()) {
|
||||||
|
$script:cfg[$kv.Key] = $kv.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "== Yoresee Deploy Config Init =="
|
||||||
|
Write-Host "Press Enter to keep the default value in brackets."
|
||||||
|
|
||||||
|
# Host exposed ports
|
||||||
|
Prompt-Value 'NGINX_HTTP_PORT' 'Host port for Nginx HTTP' '8080'
|
||||||
|
Prompt-Value 'NGINX_HTTPS_PORT' 'Host port for Nginx HTTPS' '8443'
|
||||||
|
Prompt-Value 'BACKEND_GRPC_HOST_PORT' 'Host port for backend gRPC' '9090'
|
||||||
|
Prompt-Value 'BACKEND_DEBUG_HOST_PORT' 'Host port for backend debug (dev only)' '2345'
|
||||||
|
Prompt-Value 'POSTGRES_HOST_PORT' 'Host port for Postgres (dev only)' '5432'
|
||||||
|
Prompt-Value 'REDIS_HOST_PORT' 'Host port for Redis (dev only)' '6379'
|
||||||
|
Prompt-Value 'RABBITMQ_AMQP_HOST_PORT' 'Host port for RabbitMQ AMQP (dev only)' '5672'
|
||||||
|
Prompt-Value 'CONSUL_HOST_PORT' 'Host port for Consul UI/API' '8500'
|
||||||
|
Prompt-Value 'ELASTICSEARCH_HOST_PORT' 'Host port for Elasticsearch (dev only)' '9200'
|
||||||
|
|
||||||
|
# Credentials and app secrets
|
||||||
|
Prompt-Value 'POSTGRES_USER' 'Postgres user' 'root'
|
||||||
|
Prompt-Value 'POSTGRES_PASSWORD' 'Postgres password' 'your_password'
|
||||||
|
Prompt-Value 'POSTGRES_DB' 'Postgres database' 'yoresee_doc_db'
|
||||||
|
Prompt-Value 'REDIS_PASSWORD' 'Redis password' 'your_redis_password'
|
||||||
|
Prompt-Value 'RABBITMQ_DEFAULT_USER' 'RabbitMQ user' 'guest'
|
||||||
|
Prompt-Value 'RABBITMQ_DEFAULT_PASS' 'RabbitMQ password' 'guest'
|
||||||
|
Prompt-Value 'MINIO_ROOT_USER' 'MinIO root user' 'minioadmin'
|
||||||
|
Prompt-Value 'MINIO_ROOT_PASSWORD' 'MinIO root password' 'minioadmin'
|
||||||
|
Prompt-Value 'CONSUL_ROOT_TOKEN' 'Consul root token' 'yoresee_doc_root_token'
|
||||||
|
Prompt-Value 'BACKEND_INTERNAL_RPC_KEY' 'Internal RPC key' 'yoresee_doc_internal_key'
|
||||||
|
Prompt-Value 'JWT_SECRET' 'JWT secret' 'yoresee_doc_jwt_secret_key'
|
||||||
|
|
||||||
|
# App behaviour
|
||||||
|
$defaultApiUrl = "http://localhost:$($script:cfg['NGINX_HTTP_PORT'])"
|
||||||
|
Prompt-Value 'VITE_API_BASE_URL' 'Frontend API base URL' $defaultApiUrl
|
||||||
|
Prompt-Value 'VITE_GRPC_WEB_ENDPOINT' 'Frontend gRPC-web endpoint' '/grpc'
|
||||||
|
Prompt-Value 'DIRTY_DOC_NOTIFY_THRESHOLD' 'Dirty doc notify threshold' '5'
|
||||||
|
|
||||||
|
# Derived value — keep MinIO redirect bound to API base URL
|
||||||
|
$minioRedirect = "$($script:cfg['VITE_API_BASE_URL'].TrimEnd('/'))/minio"
|
||||||
|
Update-EnvKey 'MINIO_BROWSER_REDIRECT_URL' $minioRedirect
|
||||||
|
Write-Host "MinIO browser redirect URL (derived): $minioRedirect"
|
||||||
|
|
||||||
|
Prompt-Value 'ELASTICSEARCH_ENABLED' 'Enable Elasticsearch' 'true'
|
||||||
|
Prompt-Value 'ELASTICSEARCH_INDEX_PREFIX' 'Elasticsearch index prefix' 'yoresee_doc'
|
||||||
|
Prompt-Value 'ELASTICSEARCH_USERNAME' 'Elasticsearch username (optional)' ''
|
||||||
|
Prompt-Value 'ELASTICSEARCH_PASSWORD' 'Elasticsearch password (optional)' ''
|
||||||
|
|
||||||
|
Write-Host "Written: $EnvFile"
|
||||||
|
|
||||||
|
& powershell -ExecutionPolicy Bypass -File "$ScriptDir\prepare.ps1"
|
||||||
|
|
||||||
|
Write-Host "Initialization completed."
|
||||||
|
Write-Host "You can start services with: powershell -ExecutionPolicy Bypass -File deploy/script/start.ps1 dev up"
|
||||||
Executable
+119
@@ -0,0 +1,119 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
BASE_PATH="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||||
|
DEPLOY_DIR="$BASE_PATH/deploy"
|
||||||
|
ENV_FILE="$DEPLOY_DIR/.env"
|
||||||
|
ENV_EXAMPLE_FILE="$DEPLOY_DIR/.env.example"
|
||||||
|
|
||||||
|
if [ ! -t 0 ]; then
|
||||||
|
echo "Interactive terminal is required."
|
||||||
|
echo "Fallback: copy deploy/.env.example to deploy/.env then run bash deploy/script/prepare.sh"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f "$ENV_EXAMPLE_FILE" ]; then
|
||||||
|
echo "Missing required file: $ENV_EXAMPLE_FILE"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f "$ENV_FILE" ]; then
|
||||||
|
cp "$ENV_EXAMPLE_FILE" "$ENV_FILE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
set -a
|
||||||
|
# shellcheck disable=SC1090
|
||||||
|
source "$ENV_EXAMPLE_FILE"
|
||||||
|
# shellcheck disable=SC1090
|
||||||
|
source "$ENV_FILE"
|
||||||
|
set +a
|
||||||
|
|
||||||
|
update_env_key() {
|
||||||
|
local key="$1"
|
||||||
|
local value="$2"
|
||||||
|
local tmp_file=""
|
||||||
|
|
||||||
|
tmp_file="$(mktemp)"
|
||||||
|
awk -v key="$key" -v val="$value" '
|
||||||
|
BEGIN { updated = 0 }
|
||||||
|
$0 ~ "^" key "=" {
|
||||||
|
print key "=" val
|
||||||
|
updated = 1
|
||||||
|
next
|
||||||
|
}
|
||||||
|
{ print }
|
||||||
|
END {
|
||||||
|
if (!updated) {
|
||||||
|
print key "=" val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
' "$ENV_FILE" > "$tmp_file"
|
||||||
|
mv "$tmp_file" "$ENV_FILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
prompt_value() {
|
||||||
|
local key="$1"
|
||||||
|
local label="$2"
|
||||||
|
local fallback="$3"
|
||||||
|
local current_value=""
|
||||||
|
local input=""
|
||||||
|
|
||||||
|
current_value="${!key:-$fallback}"
|
||||||
|
read -r -p "$label [$current_value]: " input
|
||||||
|
if [ -z "$input" ]; then
|
||||||
|
input="$current_value"
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf -v "$key" '%s' "$input"
|
||||||
|
update_env_key "$key" "$input"
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "== Yoresee Deploy Config Init =="
|
||||||
|
echo "Press Enter to keep the default value in brackets."
|
||||||
|
|
||||||
|
# Host exposed ports
|
||||||
|
prompt_value NGINX_HTTP_PORT "Host port for Nginx HTTP" "8080"
|
||||||
|
prompt_value NGINX_HTTPS_PORT "Host port for Nginx HTTPS" "8443"
|
||||||
|
prompt_value BACKEND_GRPC_HOST_PORT "Host port for backend gRPC" "9090"
|
||||||
|
prompt_value BACKEND_DEBUG_HOST_PORT "Host port for backend debug (dev only)" "2345"
|
||||||
|
prompt_value POSTGRES_HOST_PORT "Host port for Postgres (dev only)" "5432"
|
||||||
|
prompt_value REDIS_HOST_PORT "Host port for Redis (dev only)" "6379"
|
||||||
|
prompt_value RABBITMQ_AMQP_HOST_PORT "Host port for RabbitMQ AMQP (dev only)" "5672"
|
||||||
|
prompt_value CONSUL_HOST_PORT "Host port for Consul UI/API" "8500"
|
||||||
|
prompt_value ELASTICSEARCH_HOST_PORT "Host port for Elasticsearch (dev only)" "9200"
|
||||||
|
|
||||||
|
# Credentials and app secrets
|
||||||
|
prompt_value POSTGRES_USER "Postgres user" "root"
|
||||||
|
prompt_value POSTGRES_PASSWORD "Postgres password" "your_password"
|
||||||
|
prompt_value POSTGRES_DB "Postgres database" "yoresee_doc_db"
|
||||||
|
prompt_value REDIS_PASSWORD "Redis password" "your_redis_password"
|
||||||
|
prompt_value RABBITMQ_DEFAULT_USER "RabbitMQ user" "guest"
|
||||||
|
prompt_value RABBITMQ_DEFAULT_PASS "RabbitMQ password" "guest"
|
||||||
|
prompt_value MINIO_ROOT_USER "MinIO root user" "minioadmin"
|
||||||
|
prompt_value MINIO_ROOT_PASSWORD "MinIO root password" "minioadmin"
|
||||||
|
prompt_value CONSUL_ROOT_TOKEN "Consul root token" "yoresee_doc_root_token"
|
||||||
|
prompt_value BACKEND_INTERNAL_RPC_KEY "Internal RPC key" "yoresee_doc_internal_key"
|
||||||
|
prompt_value JWT_SECRET "JWT secret" "yoresee_doc_jwt_secret_key"
|
||||||
|
|
||||||
|
# App behavior
|
||||||
|
prompt_value VITE_API_BASE_URL "Frontend API base URL" "http://localhost:${NGINX_HTTP_PORT}"
|
||||||
|
prompt_value VITE_GRPC_WEB_ENDPOINT "Frontend gRPC-web endpoint" "/grpc"
|
||||||
|
prompt_value DIRTY_DOC_NOTIFY_THRESHOLD "Dirty doc notify threshold" "5"
|
||||||
|
|
||||||
|
# Keep MinIO browser redirect bound to API base URL to avoid host drift in deployments.
|
||||||
|
MINIO_BROWSER_REDIRECT_URL="${VITE_API_BASE_URL%/}/minio"
|
||||||
|
update_env_key MINIO_BROWSER_REDIRECT_URL "$MINIO_BROWSER_REDIRECT_URL"
|
||||||
|
echo "MinIO browser redirect URL (derived): $MINIO_BROWSER_REDIRECT_URL"
|
||||||
|
|
||||||
|
prompt_value ELASTICSEARCH_ENABLED "Enable Elasticsearch" "true"
|
||||||
|
prompt_value ELASTICSEARCH_INDEX_PREFIX "Elasticsearch index prefix" "yoresee_doc"
|
||||||
|
prompt_value ELASTICSEARCH_USERNAME "Elasticsearch username (optional)" ""
|
||||||
|
prompt_value ELASTICSEARCH_PASSWORD "Elasticsearch password (optional)" ""
|
||||||
|
|
||||||
|
echo "Written: $ENV_FILE"
|
||||||
|
|
||||||
|
bash "$SCRIPT_DIR/prepare.sh"
|
||||||
|
|
||||||
|
echo "Initialization completed."
|
||||||
|
echo "You can start services with: bash deploy/script/start.sh dev up"
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
#Requires -Version 5.1
|
||||||
|
Set-StrictMode -Version Latest
|
||||||
|
$ErrorActionPreference = 'Stop'
|
||||||
|
|
||||||
|
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Definition
|
||||||
|
$DeployDir = Resolve-Path "$ScriptDir\.."
|
||||||
|
|
||||||
|
if (Get-Command buf -ErrorAction SilentlyContinue) {
|
||||||
|
Write-Host "buf found locally, generating directly..."
|
||||||
|
Push-Location "$DeployDir\..\proto"
|
||||||
|
buf generate --template buf.gen.backend.yaml
|
||||||
|
buf generate --template buf.gen.collab-go.yaml
|
||||||
|
buf generate --template buf.gen.frontend.yaml
|
||||||
|
buf generate --template buf.gen.node.yaml
|
||||||
|
Pop-Location
|
||||||
|
Write-Host "Proto generation complete."
|
||||||
|
} else {
|
||||||
|
Write-Host "buf not found locally, using proto-gen container..."
|
||||||
|
docker compose -f "$DeployDir\docker-compose.dev.yml" run --rm proto-gen
|
||||||
|
}
|
||||||
Executable
+18
@@ -0,0 +1,18 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
DEPLOY_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||||
|
|
||||||
|
if command -v buf &>/dev/null; then
|
||||||
|
echo "buf found locally, generating directly..."
|
||||||
|
cd "$DEPLOY_DIR/../proto"
|
||||||
|
buf generate --template buf.gen.backend.yaml
|
||||||
|
buf generate --template buf.gen.collab-go.yaml
|
||||||
|
buf generate --template buf.gen.frontend.yaml
|
||||||
|
buf generate --template buf.gen.node.yaml
|
||||||
|
echo "Proto generation complete."
|
||||||
|
else
|
||||||
|
echo "buf not found locally, using proto-gen container..."
|
||||||
|
docker compose -f "$DEPLOY_DIR/docker-compose.dev.yml" run --rm proto-gen
|
||||||
|
fi
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
#Requires -Version 5.1
|
||||||
|
Set-StrictMode -Version Latest
|
||||||
|
$ErrorActionPreference = 'Stop'
|
||||||
|
|
||||||
|
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Definition
|
||||||
|
$BasePath = (Resolve-Path "$ScriptDir\..\.." ).Path
|
||||||
|
$DeployDir = "$BasePath\deploy"
|
||||||
|
$EnvExampleFile = "$DeployDir\.env.example"
|
||||||
|
$EnvFile = "$DeployDir\.env"
|
||||||
|
|
||||||
|
if (-not (Test-Path $EnvExampleFile)) {
|
||||||
|
Write-Error "Missing required file: $EnvExampleFile"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-not (Test-Path $EnvFile)) {
|
||||||
|
Write-Host "deploy\.env not found, creating from .env.example"
|
||||||
|
Copy-Item $EnvExampleFile $EnvFile
|
||||||
|
}
|
||||||
|
|
||||||
|
# Load key=value pairs from a .env file into a hashtable (last value wins)
|
||||||
|
function Read-EnvFile([string]$Path) {
|
||||||
|
$map = @{}
|
||||||
|
foreach ($line in (Get-Content $Path)) {
|
||||||
|
if ($line -match '^\s*#' -or $line.Trim() -eq '') { continue }
|
||||||
|
$idx = $line.IndexOf('=')
|
||||||
|
if ($idx -lt 1) { continue }
|
||||||
|
$map[$line.Substring(0, $idx).Trim()] = $line.Substring($idx + 1)
|
||||||
|
}
|
||||||
|
return $map
|
||||||
|
}
|
||||||
|
|
||||||
|
# Expand ${VAR} placeholders in a template string using the provided env hashtable
|
||||||
|
function Expand-Template([string]$Text, [hashtable]$Env) {
|
||||||
|
return [regex]::Replace($Text, '\$\{([A-Z0-9_]+)\}', {
|
||||||
|
param($m)
|
||||||
|
$key = $m.Groups[1].Value
|
||||||
|
if ($Env.ContainsKey($key)) { $Env[$key] } else { '' }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
# Render a template file to an output path, substituting ${VAR} with env values
|
||||||
|
function Render-Template([string]$Template, [string]$Output, [hashtable]$Env) {
|
||||||
|
if (-not (Test-Path $Template)) {
|
||||||
|
Write-Error "Template not found: $Template"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
$outDir = Split-Path -Parent $Output
|
||||||
|
if (-not (Test-Path $outDir)) { New-Item -ItemType Directory -Force -Path $outDir | Out-Null }
|
||||||
|
|
||||||
|
# If a directory exists at the output path, back it up
|
||||||
|
if (Test-Path $Output -PathType Container) {
|
||||||
|
$backup = "$Output.backup.$([DateTimeOffset]::UtcNow.ToUnixTimeSeconds())"
|
||||||
|
Move-Item $Output $backup
|
||||||
|
Write-Host "Detected directory at $Output, moved to $backup"
|
||||||
|
}
|
||||||
|
|
||||||
|
$content = Get-Content $Template -Raw
|
||||||
|
$rendered = Expand-Template $content $Env
|
||||||
|
[System.IO.File]::WriteAllText($Output, $rendered)
|
||||||
|
}
|
||||||
|
|
||||||
|
# Merge example defaults then overlay with actual .env values
|
||||||
|
$env_map = Read-EnvFile $EnvExampleFile
|
||||||
|
foreach ($kv in (Read-EnvFile $EnvFile).GetEnumerator()) {
|
||||||
|
$env_map[$kv.Key] = $kv.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
$templateMappings = @(
|
||||||
|
@{ Template = "$BasePath\backend\config.toml.tmpl"; Output = "$BasePath\backend\config.toml" }
|
||||||
|
@{ Template = "$BasePath\frontend\nginx.conf.tmpl"; Output = "$BasePath\frontend\nginx.conf" }
|
||||||
|
@{ Template = "$DeployDir\nginx\nginx.conf.tmpl"; Output = "$DeployDir\nginx\nginx.conf" }
|
||||||
|
@{ Template = "$DeployDir\nginx\conf.d\default.conf.tmpl"; Output = "$DeployDir\nginx\conf.d\default.conf" }
|
||||||
|
@{ Template = "$DeployDir\redis\redis.conf.tmpl"; Output = "$DeployDir\redis\redis.conf" }
|
||||||
|
@{ Template = "$DeployDir\rabbitmq\rabbitmq.conf.tmpl"; Output = "$DeployDir\rabbitmq\rabbitmq.conf" }
|
||||||
|
)
|
||||||
|
|
||||||
|
Write-Host "Rendering configuration files from templates..."
|
||||||
|
foreach ($m in $templateMappings) {
|
||||||
|
Render-Template $m.Template $m.Output $env_map
|
||||||
|
$rel = $m.Output.Replace("$BasePath\", '')
|
||||||
|
Write-Host " - $rel"
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "Configuration preparation completed!"
|
||||||
Executable
+75
@@ -0,0 +1,75 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
BASE_PATH="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||||
|
DEPLOY_DIR="$BASE_PATH/deploy"
|
||||||
|
ENV_EXAMPLE_FILE="$DEPLOY_DIR/.env.example"
|
||||||
|
ENV_FILE="$DEPLOY_DIR/.env"
|
||||||
|
|
||||||
|
if [ ! -f "$ENV_EXAMPLE_FILE" ]; then
|
||||||
|
echo "Missing required file: $ENV_EXAMPLE_FILE"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f "$ENV_FILE" ]; then
|
||||||
|
echo "deploy/.env not found, creating from .env.example"
|
||||||
|
cp "$ENV_EXAMPLE_FILE" "$ENV_FILE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
set -a
|
||||||
|
# shellcheck disable=SC1090
|
||||||
|
source "$ENV_EXAMPLE_FILE"
|
||||||
|
# shellcheck disable=SC1090
|
||||||
|
source "$ENV_FILE"
|
||||||
|
set +a
|
||||||
|
|
||||||
|
prepare_target_file() {
|
||||||
|
local target="$1"
|
||||||
|
if [ -d "$target" ]; then
|
||||||
|
local backup="${target}.backup.$(date +%s)"
|
||||||
|
mv "$target" "$backup"
|
||||||
|
echo "Detected directory at $target, moved to $backup"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
render_template() {
|
||||||
|
local template="$1"
|
||||||
|
local output="$2"
|
||||||
|
local tmp_file=""
|
||||||
|
|
||||||
|
if [ ! -f "$template" ]; then
|
||||||
|
echo "Template not found: $template"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$(dirname "$output")"
|
||||||
|
prepare_target_file "$output"
|
||||||
|
|
||||||
|
tmp_file="$(mktemp)"
|
||||||
|
perl -pe 's/\$\{([A-Z0-9_]+)\}/defined $ENV{$1} ? $ENV{$1} : ""/ge' "$template" > "$tmp_file"
|
||||||
|
mv "$tmp_file" "$output"
|
||||||
|
}
|
||||||
|
|
||||||
|
TEMPLATE_MAPPINGS=(
|
||||||
|
"$BASE_PATH/backend/config.toml.tmpl:$BASE_PATH/backend/config.toml"
|
||||||
|
"$BASE_PATH/frontend/nginx.conf.tmpl:$BASE_PATH/frontend/nginx.conf"
|
||||||
|
"$DEPLOY_DIR/nginx/nginx.conf.tmpl:$DEPLOY_DIR/nginx/nginx.conf"
|
||||||
|
"$DEPLOY_DIR/nginx/conf.d/default.conf.tmpl:$DEPLOY_DIR/nginx/conf.d/default.conf"
|
||||||
|
"$DEPLOY_DIR/redis/redis.conf.tmpl:$DEPLOY_DIR/redis/redis.conf"
|
||||||
|
"$DEPLOY_DIR/rabbitmq/rabbitmq.conf.tmpl:$DEPLOY_DIR/rabbitmq/rabbitmq.conf"
|
||||||
|
)
|
||||||
|
|
||||||
|
echo "Rendering configuration files from templates..."
|
||||||
|
for mapping in "${TEMPLATE_MAPPINGS[@]}"; do
|
||||||
|
template="${mapping%%:*}"
|
||||||
|
output="${mapping#*:}"
|
||||||
|
render_template "$template" "$output"
|
||||||
|
rel_output="${output#$BASE_PATH/}"
|
||||||
|
if [ "$rel_output" = "$output" ]; then
|
||||||
|
rel_output="$output"
|
||||||
|
fi
|
||||||
|
echo " - $rel_output"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "Configuration preparation completed!"
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
#Requires -Version 5.1
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory)][ValidateSet('dev','release')][string]$Environment,
|
||||||
|
[Parameter(Mandatory)][ValidateSet('rebuild','clear','restart','up','build')][string]$Action
|
||||||
|
)
|
||||||
|
Set-StrictMode -Version Latest
|
||||||
|
$ErrorActionPreference = 'Stop'
|
||||||
|
|
||||||
|
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Definition
|
||||||
|
$BasePath = (Resolve-Path "$ScriptDir\..\.." ).Path
|
||||||
|
$DeployDir = "$BasePath\deploy"
|
||||||
|
|
||||||
|
Write-Host "Environment: $Environment"
|
||||||
|
Write-Host "Action: $Action"
|
||||||
|
Write-Host "Base path: $BasePath"
|
||||||
|
|
||||||
|
$ComposeFile = if ($Environment -eq 'dev') { 'docker-compose.dev.yml' } else { 'docker-compose.yml' }
|
||||||
|
Write-Host "Compose file: $ComposeFile"
|
||||||
|
|
||||||
|
if ($Environment -eq 'dev') {
|
||||||
|
Write-Host "Generating proto code..."
|
||||||
|
docker compose -f "$DeployDir\$ComposeFile" run --rm proto-gen
|
||||||
|
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
|
||||||
|
}
|
||||||
|
|
||||||
|
Push-Location $DeployDir
|
||||||
|
try {
|
||||||
|
switch ($Action) {
|
||||||
|
'rebuild' {
|
||||||
|
Write-Host "Rebuilding and starting services..."
|
||||||
|
docker compose -f $ComposeFile down -v
|
||||||
|
docker compose -f $ComposeFile up -d --build
|
||||||
|
}
|
||||||
|
'clear' {
|
||||||
|
Write-Host "Clearing containers and volumes..."
|
||||||
|
docker compose -f $ComposeFile down -v
|
||||||
|
}
|
||||||
|
'restart' {
|
||||||
|
Write-Host "Restarting services..."
|
||||||
|
docker compose -f $ComposeFile down
|
||||||
|
docker compose -f $ComposeFile up -d
|
||||||
|
}
|
||||||
|
'up' {
|
||||||
|
Write-Host "Starting services..."
|
||||||
|
docker compose -f $ComposeFile up -d
|
||||||
|
}
|
||||||
|
'build' {
|
||||||
|
Write-Host "Building images..."
|
||||||
|
docker compose -f $ComposeFile build
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
Pop-Location
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($LASTEXITCODE -ne 0) {
|
||||||
|
Write-Error "Operation failed."
|
||||||
|
exit $LASTEXITCODE
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "Operation completed successfully."
|
||||||
Executable
+91
@@ -0,0 +1,91 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Check parameter count
|
||||||
|
if [ $# -lt 2 ]; then
|
||||||
|
echo "Usage: $0 <dev|release> <rebuild|clear|restart|up|build>"
|
||||||
|
echo " dev|release: Use docker-compose.dev.yml or docker-compose.yml"
|
||||||
|
echo " rebuild: Clean containers and volumes, then rebuild and start"
|
||||||
|
echo " clear: Clean containers and volumes"
|
||||||
|
echo " restart: Stop and restart services"
|
||||||
|
echo " up: Start services"
|
||||||
|
echo " build: Build images without starting"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
ENVIRONMENT=$1
|
||||||
|
ACTION=$2
|
||||||
|
|
||||||
|
# Parameter validation
|
||||||
|
if [[ "$ENVIRONMENT" != "dev" && "$ENVIRONMENT" != "release" ]]; then
|
||||||
|
echo "Error: First argument must be 'dev' or 'release'"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$ACTION" != "rebuild" && "$ACTION" != "clear" && "$ACTION" != "restart" && "$ACTION" != "up" && "$ACTION" != "build" ]]; then
|
||||||
|
echo "Error: Second argument must be 'rebuild', 'clear', 'restart', 'up', or 'build'"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
ORIGINAL_DIR=$(pwd)
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
BASE_PATH="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||||
|
|
||||||
|
echo "Environment: $ENVIRONMENT"
|
||||||
|
echo "Action: $ACTION"
|
||||||
|
echo "Script directory: $SCRIPT_DIR"
|
||||||
|
echo "Base path: $BASE_PATH"
|
||||||
|
|
||||||
|
cd "$BASE_PATH"/deploy/
|
||||||
|
|
||||||
|
# Select compose file based on environment
|
||||||
|
if [ "$ENVIRONMENT" = "dev" ]; then
|
||||||
|
COMPOSE_FILE="docker-compose.dev.yml"
|
||||||
|
else
|
||||||
|
COMPOSE_FILE="docker-compose.yml"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Using compose file: $COMPOSE_FILE"
|
||||||
|
|
||||||
|
if [ "$ENVIRONMENT" = "dev" ]; then
|
||||||
|
echo "Generating proto code..."
|
||||||
|
docker compose -f "$COMPOSE_FILE" run --rm proto-gen
|
||||||
|
fi
|
||||||
|
|
||||||
|
case "$ACTION" in
|
||||||
|
"rebuild")
|
||||||
|
echo "Rebuilding and starting services..."
|
||||||
|
docker compose -f "$COMPOSE_FILE" down -v
|
||||||
|
docker compose -f "$COMPOSE_FILE" up -d --build
|
||||||
|
;;
|
||||||
|
"clear")
|
||||||
|
echo "Clearing containers and volumes..."
|
||||||
|
docker compose -f "$COMPOSE_FILE" down -v
|
||||||
|
;;
|
||||||
|
"restart")
|
||||||
|
echo "Restarting services..."
|
||||||
|
docker compose -f "$COMPOSE_FILE" down
|
||||||
|
docker compose -f "$COMPOSE_FILE" up -d
|
||||||
|
;;
|
||||||
|
"up")
|
||||||
|
echo "Starting services..."
|
||||||
|
docker compose -f "$COMPOSE_FILE" up -d
|
||||||
|
;;
|
||||||
|
"build")
|
||||||
|
echo "Building images..."
|
||||||
|
docker compose -f "$COMPOSE_FILE" build
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Unknown action: $ACTION"
|
||||||
|
cd "$ORIGINAL_DIR"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
cd "$ORIGINAL_DIR"
|
||||||
|
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
echo "Operation completed successfully."
|
||||||
|
else
|
||||||
|
echo "Operation failed."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
Reference in New Issue
Block a user