chore: update docker configuration

This commit is contained in:
zhenyi 2026-06-01 22:04:17 +08:00
parent b65ea19b85
commit e44f3d13c4
10 changed files with 220 additions and 624 deletions

View File

@ -1,137 +1,69 @@
# GitDataAI Docker 配置 # GitDataAI Docker
## 文件说明 默认镜像仓库:`harbor.gitdata.me/app`
### Dockerfile 文件 ## 服务
| 文件名 | 服务 | 说明 | | Dockerfile | 服务 | 端口 | 健康检查 |
|--------|------|------| |-----------|------|------|---------|
| `gitdata.Dockerfile` | GitData API | 主 API 服务 | | `gitdata.Dockerfile` | API 服务 | 8080 | `/metrics` |
| `email.Dockerfile` | Email Service | 邮件发送服务 | | `gitpod.Dockerfile` | Git 协议 (HTTP/SSH/gRPC) | 8080, 2222, 50051 | `/health` |
| `gitpod.Dockerfile` | GitPod Service | Git 服务 | | `gitsync.Dockerfile` | Git 同步 worker | 8081 | `/health` |
| `gitsync.Dockerfile` | GitSync Service | Git 同步服务 | | `email.Dockerfile` | 邮件 worker | 8083 | `/health` |
| `migrate.Dockerfile` | Database Migration | 数据库迁移工具 | | `web.Dockerfile` | 前端 | 80 | `/` |
| `web.Dockerfile` | Web Frontend | React 前端应用 |
### 配置文件 ## 构建
| 文件名 | 说明 | 先编译 Rust 二进制,再打镜像:
|--------|------|
| `docker-compose.yml` | 完整的开发环境配置 |
| `nginx.conf` | Nginx 反向代理配置 |
## 快速开始
### 1. 启动完整开发环境
```bash ```bash
# 进入 docker 目录 # 编译全部 Rust 服务
cd docker cargo build --release
# 启动所有服务 # 构建全部镜像 (默认推送到 harbor.gitdata.me/app)
docker-compose up -d ./docker/build.sh
# 查看服务状态 # 只构建指定服务
docker-compose ps ./docker/build.sh gitdata gitpod
# 查看日志 # 自定义 tag
docker-compose logs -f ./docker/build.sh -t v1.2.0
# 自定义 registry
./docker/build.sh -r myreg.io/app -t dev
``` ```
### 2. 单独构建服务 ## 推送
```bash ```bash
# 构建 GitData API # 推送全部 (默认 harbor.gitdata.me/app)
docker build -f docker/gitdata.Dockerfile -t gitdata-api . ./docker/push.sh
# 构建前端 # 推送指定服务
docker build -f docker/web.Dockerfile -t gitdata-web . ./docker/push.sh gitdata gitpod
# 自定义 tag / registry
./docker/push.sh -t v1.2.0
./docker/push.sh -r myreg.io/app -t dev
``` ```
### 3. 环境变量配置 ## 本地开发
创建 `.env` 文件配置环境变量 使用 docker compose 启动全部服务(含依赖的 Postgres/Redis/Qdrant/NATS/MinIO
```bash ```bash
# 数据库配置 docker compose -f docker/docker-compose.yml up -d
POSTGRES_USER=gitdata
POSTGRES_PASSWORD=your_secure_password
POSTGRES_DB=app
# MinIO 配置
MINIO_ROOT_USER=admin
MINIO_ROOT_PASSWORD=your_secure_password
``` ```
## 服务端口 compose 默认从 `harbor.gitdata.me/app` 拉取镜像,可通过环境变量覆盖:
| 服务 | 端口 | 说明 |
|------|------|------|
| Web Frontend | 80 | 前端访问入口 |
| GitData API | 8080 | 主 API 服务 |
| Git HTTP | 5023 | Git HTTP 访问 |
| Git RPC | 5030 | Git RPC 服务 |
| SSH | 5022 | SSH Git 访问 |
| GitPod | 5082 | GitPod 服务 |
| GitSync | 5083 | GitSync 健康检查 |
| PostgreSQL | 5432 | 数据库 |
| Redis | 6379 | 缓存 |
| Qdrant | 6333 | 向量数据库 |
| NATS | 4222 | 消息队列 |
| MinIO | 9000/9001 | 对象存储 |
## 生产环境部署
### 1. 修改环境变量
```bash ```bash
# 复制示例配置 IMAGE_REGISTRY=myreg.io/app IMAGE_TAG=v1.2.0 \
cp .env.example .env docker compose -f docker/docker-compose.yml up -d
# 编辑配置文件,修改密码等敏感信息
vim .env
``` ```
### 2. 启动服务 ## 镜像结构
```bash - Rust 服务:`debian:bookworm-slim` + 预编译二进制(~20MB
# 使用生产配置启动 - 前端:多阶段构建 `oven/bun` + `nginx:alpine`
docker-compose -f docker-compose.yml up -d - 数据库迁移在 gitdata 启动时自动执行(见 lib/migrate
# 查看服务状态
docker-compose ps
```
### 3. 数据备份
```bash
# 备份 PostgreSQL
docker exec gitdata-postgres pg_dump -U gitdata app > backup.sql
# 备份 MinIO 数据
docker cp gitdata-minio:/data ./minio-backup
```
## 常见问题
### 1. 服务启动失败
检查日志:
```bash
docker-compose logs <service-name>
```
### 2. 数据库连接失败
确保 PostgreSQL 健康检查通过:
```bash
docker-compose ps postgres
```
### 3. 端口冲突
修改 `docker-compose.yml` 中的端口映射:
```yaml
ports:
- "8081:8080" # 修改宿主机端口
```

View File

@ -1,131 +1,117 @@
#!/bin/bash #!/bin/bash
# GitDataAI Docker Build Script
set -e set -e
# Get version from Cargo.toml
PROJECT_ROOT="$(cd "$(dirname "$0")/.." && pwd)" PROJECT_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
CARGO_VERSION=$(grep -m1 'version' "${PROJECT_ROOT}/Cargo.toml" | sed 's/.*"\(.*\)".*/\1/') CARGO_VERSION=$(grep -m1 'version' "${PROJECT_ROOT}/Cargo.toml" | sed 's/.*"\(.*\)".*/\1/')
# Configuration REGISTRY=${REGISTRY:-"harbor.gitdata.me/app"}
REGISTRY=${REGISTRY:-""}
TAG=${TAG:-"${CARGO_VERSION:-latest}"} TAG=${TAG:-"${CARGO_VERSION:-latest}"}
PLATFORM=${PLATFORM:-"linux/amd64"} PLATFORM=${PLATFORM:-"linux/amd64"}
TARGET_DIR=${CARGO_TARGET_DIR:-target}
# Colors for output if command -v podman &>/dev/null; then
RED='\033[0;31m' DOCKER=podman
GREEN='\033[0;32m' elif command -v docker &>/dev/null; then
YELLOW='\033[1;33m' DOCKER=docker
NC='\033[0m' # No Color else
echo "ERROR: neither podman nor docker found"
exit 1
fi
# Services to build RUST_BINS=("gitdata" "gitpod" "gitsync" "email-service")
SERVICES=("gitdata" "email" "gitpod" "gitsync" "migrate" "web") ALL_SERVICES=("gitdata" "gitpod" "gitsync" "email" "web")
# Function to print colored output log_info() { echo -e "\033[0;32m[INFO]\033[0m $1"; }
log_info() { log_error() { echo -e "\033[0;31m[ERROR]\033[0m $1"; }
echo -e "${GREEN}[INFO]${NC} $1"
build_rust() {
log_info "Building Rust binaries: $*"
cd "$PROJECT_ROOT"
cargo build --release "$@"
} }
log_warn() { build_image() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# Function to build a service
build_service() {
local service=$1 local service=$1
local dockerfile="${PROJECT_ROOT}/docker/${service}.Dockerfile" local dockerfile="${PROJECT_ROOT}/docker/${service}.Dockerfile"
local image_name="gitdata-${service}" local image_name="${REGISTRY}/gitdata-${service}"
# Add registry prefix if set log_info "Building image ${image_name}:${TAG}"
if [ -n "$REGISTRY" ]; then
image_name="${REGISTRY}/${image_name}"
fi
log_info "Building ${service}..." $DOCKER build \
if [ ! -f "$dockerfile" ]; then
log_error "Dockerfile not found: ${dockerfile}"
return 1
fi
docker build \
-f "$dockerfile" \ -f "$dockerfile" \
-t "${image_name}:${TAG}" \ -t "${image_name}:${TAG}" \
--platform "$PLATFORM" \ --platform "$PLATFORM" \
--build-arg TARGET_DIR="$TARGET_DIR" \
"$PROJECT_ROOT" "$PROJECT_ROOT"
log_info "Successfully built ${image_name}:${TAG}"
} }
# Parse command line arguments svc_to_bin() {
case $1 in
gitdata) echo "gitdata" ;;
gitpod) echo "gitpod" ;;
gitsync) echo "gitsync" ;;
email) echo "email-service" ;;
web) echo "" ;;
*) echo "" ;;
esac
}
BUILD_SERVICES=() BUILD_SERVICES=()
BUILD_ALL=true BUILD_ALL=true
while [[ $# -gt 0 ]]; do while [[ $# -gt 0 ]]; do
case $1 in case $1 in
--tag|-t) --tag|-t) TAG="$2"; shift 2 ;;
TAG="$2" --registry|-r) REGISTRY="$2"; shift 2 ;;
shift 2 --platform|-p) PLATFORM="$2"; shift 2 ;;
;;
--registry|-r)
REGISTRY="$2"
shift 2
;;
--platform|-p)
PLATFORM="$2"
shift 2
;;
--help|-h) --help|-h)
echo "Usage: $0 [OPTIONS] [SERVICE...]" echo "Usage: $0 [OPTIONS] [SERVICE...]"
echo "" echo ""
echo "Options:" echo "Options:"
echo " -t, --tag TAG Docker image tag (default: latest)" echo " -t, --tag TAG Image tag (default: from Cargo.toml)"
echo " -r, --registry REG Docker registry prefix" echo " -r, --registry REG Registry prefix (default: harbor.gitdata.me/app)"
echo " -p, --platform PLAT Target platform (default: linux/amd64)" echo " -p, --platform PLAT Target platform (default: linux/amd64)"
echo " -h, --help Show this help message"
echo "" echo ""
echo "Services:" echo "Services:"
echo " gitdata Main API service" echo " gitdata gitpod gitsync email web"
echo " email Email service"
echo " gitpod GitPod service"
echo " gitsync GitSync service"
echo " migrate Database migration"
echo " web Web frontend"
echo "" echo ""
echo "Examples:" echo "Examples:"
echo " $0 # Build all services" echo " $0 # Build all"
echo " $0 gitdata web # Build specific services" echo " $0 gitdata gitpod # Build specific services"
echo " $0 -t v1.0.0 -r registry.com # Build with custom tag and registry" echo " $0 -t v1.2.0 # Build with custom tag"
echo " $0 -r myreg.io/app -t dev # Build with custom registry and tag"
exit 0 exit 0
;; ;;
*) *) BUILD_SERVICES+=("$1"); BUILD_ALL=false; shift ;;
BUILD_SERVICES+=("$1")
BUILD_ALL=false
shift
;;
esac esac
done done
# Build services
log_info "Starting Docker build..."
log_info "Registry: ${REGISTRY:-none}"
log_info "Tag: ${TAG}"
log_info "Platform: ${PLATFORM}"
if [ "$BUILD_ALL" = true ]; then if [ "$BUILD_ALL" = true ]; then
log_info "Building all services..." log_info "Building all services (registry=${REGISTRY}, tag=${TAG})"
for service in "${SERVICES[@]}"; do
build_service "$service" build_rust
for svc in "${ALL_SERVICES[@]}"; do
build_image "$svc"
done done
else else
log_info "Building specified services: ${BUILD_SERVICES[*]}" log_info "Building services: ${BUILD_SERVICES[*]} (registry=${REGISTRY}, tag=${TAG})"
for service in "${BUILD_SERVICES[@]}"; do
build_service "$service" rust_bins=()
for svc in "${BUILD_SERVICES[@]}"; do
bin=$(svc_to_bin "$svc")
if [ -n "$bin" ]; then
rust_bins+=("--bin" "$bin")
fi
done
if [ ${#rust_bins[@]} -gt 0 ]; then
build_rust "${rust_bins[@]}"
fi
for svc in "${BUILD_SERVICES[@]}"; do
build_image "$svc"
done done
fi fi
log_info "Build completed successfully!" log_info "Done."

View File

@ -1,8 +1,4 @@
# GitDataAI Docker Compose
# Full stack deployment configuration
services: services:
# PostgreSQL Database
postgres: postgres:
image: postgres:16-alpine image: postgres:16-alpine
container_name: gitdata-postgres container_name: gitdata-postgres
@ -21,7 +17,6 @@ services:
retries: 5 retries: 5
restart: unless-stopped restart: unless-stopped
# Redis Cluster
redis: redis:
image: redis:7-alpine image: redis:7-alpine
container_name: gitdata-redis container_name: gitdata-redis
@ -36,7 +31,6 @@ services:
retries: 5 retries: 5
restart: unless-stopped restart: unless-stopped
# Qdrant Vector Database
qdrant: qdrant:
image: qdrant/qdrant:latest image: qdrant/qdrant:latest
container_name: gitdata-qdrant container_name: gitdata-qdrant
@ -46,7 +40,6 @@ services:
- qdrant_data:/qdrant/storage - qdrant_data:/qdrant/storage
restart: unless-stopped restart: unless-stopped
# NATS Message Queue
nats: nats:
image: nats:alpine image: nats:alpine
container_name: gitdata-nats container_name: gitdata-nats
@ -56,7 +49,6 @@ services:
command: "--jetstream" command: "--jetstream"
restart: unless-stopped restart: unless-stopped
# MinIO S3 Storage
minio: minio:
image: minio/minio:latest image: minio/minio:latest
container_name: gitdata-minio container_name: gitdata-minio
@ -71,24 +63,8 @@ services:
- minio_data:/data - minio_data:/data
restart: unless-stopped restart: unless-stopped
# Database Migration
migrate:
build:
context: ..
dockerfile: docker/migrate.Dockerfile
container_name: gitdata-migrate
environment:
DATABASE_URL: postgres://${POSTGRES_USER:-gitdata}:${POSTGRES_PASSWORD:-gitdata123}@postgres:5432/${POSTGRES_DB:-app}
depends_on:
postgres:
condition: service_healthy
restart: "no"
# GitData Main API Service
gitdata: gitdata:
build: image: ${IMAGE_REGISTRY:-harbor.gitdata.me/app/}gitdata-gitdata:${IMAGE_TAG:-latest}
context: ..
dockerfile: docker/gitdata.Dockerfile
container_name: gitdata-api container_name: gitdata-api
environment: environment:
APP_DATABASE_URL: postgres://${POSTGRES_USER:-gitdata}:${POSTGRES_PASSWORD:-gitdata123}@postgres:5432/${POSTGRES_DB:-app} APP_DATABASE_URL: postgres://${POSTGRES_USER:-gitdata}:${POSTGRES_PASSWORD:-gitdata123}@postgres:5432/${POSTGRES_DB:-app}
@ -98,11 +74,12 @@ services:
APP_STORAGE_S3_ENDPOINT_URL: http://minio:9000 APP_STORAGE_S3_ENDPOINT_URL: http://minio:9000
APP_STORAGE_S3_ACCESS_KEY_ID: ${MINIO_ROOT_USER:-admin} APP_STORAGE_S3_ACCESS_KEY_ID: ${MINIO_ROOT_USER:-admin}
APP_STORAGE_S3_SECRET_ACCESS_KEY: ${MINIO_ROOT_PASSWORD:-mysecret123} APP_STORAGE_S3_SECRET_ACCESS_KEY: ${MINIO_ROOT_PASSWORD:-mysecret123}
APP_STORAGE_S3_BUCKET: ${APP_STORAGE_S3_BUCKET:-gitdata}
APP_SESSION_SECRET: ${APP_SESSION_SECRET:-supersecretdevkey123}
APP_GIT_RPC_ADDR: gitpod
APP_GIT_RPC_PORT: "50051"
ports: ports:
- "8080:8080" - "8080:8080"
- "5023:5023"
- "5030:5030"
- "5022:5022"
volumes: volumes:
- gitdata_repos:/app/data/repos - gitdata_repos:/app/data/repos
- gitdata_files:/app/data/files - gitdata_files:/app/data/files
@ -118,20 +95,20 @@ services:
condition: service_started condition: service_started
minio: minio:
condition: service_started condition: service_started
migrate:
condition: service_completed_successfully
restart: unless-stopped restart: unless-stopped
# Email Service
email: email:
build: image: ${IMAGE_REGISTRY:-harbor.gitdata.me/app/}gitdata-email:${IMAGE_TAG:-latest}
context: ..
dockerfile: docker/email.Dockerfile
container_name: gitdata-email container_name: gitdata-email
environment: environment:
APP_DATABASE_URL: postgres://${POSTGRES_USER:-gitdata}:${POSTGRES_PASSWORD:-gitdata123}@postgres:5432/${POSTGRES_DB:-app} APP_DATABASE_URL: postgres://${POSTGRES_USER:-gitdata}:${POSTGRES_PASSWORD:-gitdata123}@postgres:5432/${POSTGRES_DB:-app}
APP_REDIS_URLS: redis://redis:6379 APP_REDIS_URLS: redis://redis:6379
NATS_URL: nats://nats:4222 NATS_URL: nats://nats:4222
APP_SMTP_HOST: ${APP_SMTP_HOST:-mailhog}
APP_SMTP_PORT: ${APP_SMTP_PORT:-1025}
APP_SMTP_USERNAME: ${APP_SMTP_USERNAME:-dev}
APP_SMTP_PASSWORD: ${APP_SMTP_PASSWORD:-dev}
APP_SMTP_FROM: ${APP_SMTP_FROM:-Gitdata <noreply@localhost>}
depends_on: depends_on:
postgres: postgres:
condition: service_healthy condition: service_healthy
@ -141,17 +118,19 @@ services:
condition: service_started condition: service_started
restart: unless-stopped restart: unless-stopped
# GitPod Service
gitpod: gitpod:
build: image: ${IMAGE_REGISTRY:-harbor.gitdata.me/app/}gitdata-gitpod:${IMAGE_TAG:-latest}
context: ..
dockerfile: docker/gitpod.Dockerfile
container_name: gitdata-gitpod container_name: gitdata-gitpod
environment: environment:
APP_DATABASE_URL: postgres://${POSTGRES_USER:-gitdata}:${POSTGRES_PASSWORD:-gitdata123}@postgres:5432/${POSTGRES_DB:-app} APP_DATABASE_URL: postgres://${POSTGRES_USER:-gitdata}:${POSTGRES_PASSWORD:-gitdata123}@postgres:5432/${POSTGRES_DB:-app}
APP_REDIS_URLS: redis://redis:6379 APP_REDIS_URLS: redis://redis:6379
APP_GIT_HTTP_PORT: "8080"
APP_GIT_RPC_PORT: "50051"
APP_SSH_PORT: "2222"
ports: ports:
- "5082:5082" - "2222:2222"
- "8081:8080"
- "50051:50051"
volumes: volumes:
- gitdata_repos:/app/data/repos - gitdata_repos:/app/data/repos
depends_on: depends_on:
@ -161,17 +140,15 @@ services:
condition: service_healthy condition: service_healthy
restart: unless-stopped restart: unless-stopped
# GitSync Service
gitsync: gitsync:
build: image: ${IMAGE_REGISTRY:-harbor.gitdata.me/app/}gitdata-gitsync:${IMAGE_TAG:-latest}
context: ..
dockerfile: docker/gitsync.Dockerfile
container_name: gitdata-gitsync container_name: gitdata-gitsync
environment: environment:
APP_DATABASE_URL: postgres://${POSTGRES_USER:-gitdata}:${POSTGRES_PASSWORD:-gitdata123}@postgres:5432/${POSTGRES_DB:-app} APP_DATABASE_URL: postgres://${POSTGRES_USER:-gitdata}:${POSTGRES_PASSWORD:-gitdata123}@postgres:5432/${POSTGRES_DB:-app}
APP_REDIS_URLS: redis://redis:6379 APP_REDIS_URLS: redis://redis:6379
APP_GITSYNC_HEALTH_PORT: "8081"
ports: ports:
- "5083:5083" - "8082:8081"
volumes: volumes:
- gitdata_repos:/app/data/repos - gitdata_repos:/app/data/repos
depends_on: depends_on:
@ -181,11 +158,8 @@ services:
condition: service_healthy condition: service_healthy
restart: unless-stopped restart: unless-stopped
# Web Frontend
web: web:
build: image: ${IMAGE_REGISTRY:-harbor.gitdata.me/app/}gitdata-web:${IMAGE_TAG:-latest}
context: ..
dockerfile: docker/web.Dockerfile
container_name: gitdata-web container_name: gitdata-web
ports: ports:
- "80:80" - "80:80"
@ -200,4 +174,4 @@ volumes:
minio_data: minio_data:
gitdata_repos: gitdata_repos:
gitdata_files: gitdata_files:
gitdata_avatar: gitdata_avatar:

View File

@ -1,61 +1,26 @@
# GitDataAI Backend - Email Service ARG TARGET_DIR=target
# Multi-stage build for Rust application
# Stage 1: Build the application FROM ubuntu:26.04
FROM rust:1.96-bookworm AS builder
# Install system dependencies RUN apt-get update && apt-get install -y --no-install-recommends \
RUN apt-get update && apt-get install -y \ ca-certificates libssl3 openssh-client procps git \
pkg-config \
libssl-dev \
libpq-dev \
cmake \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/*
RUN git config --system --add safe.directory '*'
# Create app directory
WORKDIR /app
# Copy workspace files
COPY Cargo.toml Cargo.lock ./
COPY app/ app/
COPY lib/ lib/
# Build the application in release mode
RUN cargo build --release --bin email-service
# Stage 2: Create runtime image
FROM debian:bookworm-slim
# Install runtime dependencies
RUN apt-get update && apt-get install -y \
libssl3 \
libpq5 \
ca-certificates \
curl \
&& rm -rf /var/lib/apt/lists/*
# Create non-root user
RUN useradd -r -s /bin/false appuser RUN useradd -r -s /bin/false appuser
# Create directories
RUN mkdir -p /app/logs \ RUN mkdir -p /app/logs \
&& chown -R appuser:appuser /app && chown -R appuser:appuser /app
# Copy binary from builder COPY ${TARGET_DIR}/release/email-service /app/email-service
COPY --from=builder /app/target/release/email-service /app/email-service
# Set ownership
RUN chown -R appuser:appuser /app RUN chown -R appuser:appuser /app
# Switch to non-root user
USER appuser USER appuser
# Set working directory
WORKDIR /app WORKDIR /app
# Health check EXPOSE 8083
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD pgrep email-service || exit 1
# Run the application HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
CMD ["./email-service"] CMD curl -f http://localhost:8083/health || exit 1
CMD ["./email-service"]

View File

@ -1,74 +1,26 @@
# GitDataAI Backend - GitData Service ARG TARGET_DIR=target
# Multi-stage build for Rust application
# Stage 1: Build the application FROM ubuntu:26.04
FROM rust:1.96-bookworm AS builder
# Install system dependencies RUN apt-get update && apt-get install -y --no-install-recommends \
RUN apt-get update && apt-get install -y \ ca-certificates libssl3 openssh-client procps git \
pkg-config \
libssl-dev \
libpq-dev \
cmake \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/*
RUN git config --system --add safe.directory '*'
# Create app directory
WORKDIR /app
# Copy workspace files
COPY Cargo.toml Cargo.lock ./
COPY app/ app/
COPY lib/ lib/
# Build the application in release mode
RUN cargo build --release --bin gitdata
# Stage 2: Create runtime image
FROM debian:bookworm-slim
# Install runtime dependencies
RUN apt-get update && apt-get install -y \
libssl3 \
libpq5 \
ca-certificates \
curl \
&& rm -rf /var/lib/apt/lists/*
# Create non-root user
RUN useradd -r -s /bin/false appuser RUN useradd -r -s /bin/false appuser
# Create directories RUN mkdir -p /app/data/repos /app/data/files /app/data/avatar /app/logs \
RUN mkdir -p /app/data/repos \
/app/data/files \
/app/data/avatar \
/app/logs \
&& chown -R appuser:appuser /app && chown -R appuser:appuser /app
# Copy binary from builder COPY ${TARGET_DIR}/release/gitdata /app/gitdata
COPY --from=builder /app/target/release/gitdata /app/gitdata
# Set ownership
RUN chown -R appuser:appuser /app RUN chown -R appuser:appuser /app
# Switch to non-root user
USER appuser USER appuser
# Set working directory
WORKDIR /app WORKDIR /app
# Expose ports
# API port
EXPOSE 8080 EXPOSE 8080
# Git HTTP port
EXPOSE 5023
# Git RPC port
EXPOSE 5030
# SSH port
EXPOSE 5022
# Health check HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ CMD curl -f http://localhost:8080/metrics || exit 1
CMD curl -f http://localhost:8080/health || exit 1
# Run the application CMD ["./gitdata"]
CMD ["./gitdata"]

View File

@ -1,65 +1,26 @@
# GitDataAI Backend - GitPod Service ARG TARGET_DIR=target
# Multi-stage build for Rust application
# Stage 1: Build the application FROM ubuntu:26.04
FROM rust:1.96-bookworm AS builder
# Install system dependencies RUN apt-get update && apt-get install -y --no-install-recommends \
RUN apt-get update && apt-get install -y \ ca-certificates libssl3 openssh-client procps git \
pkg-config \
libssl-dev \
libpq-dev \
cmake \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/*
RUN git config --system --add safe.directory '*'
# Create app directory
WORKDIR /app
# Copy workspace files
COPY Cargo.toml Cargo.lock ./
COPY app/ app/
COPY lib/ lib/
# Build the application in release mode
RUN cargo build --release --bin gitpod
# Stage 2: Create runtime image
FROM debian:bookworm-slim
# Install runtime dependencies
RUN apt-get update && apt-get install -y \
libssl3 \
libpq5 \
ca-certificates \
curl \
&& rm -rf /var/lib/apt/lists/*
# Create non-root user
RUN useradd -r -s /bin/false appuser RUN useradd -r -s /bin/false appuser
# Create directories RUN mkdir -p /app/data/repos /app/logs \
RUN mkdir -p /app/data/repos \
/app/logs \
&& chown -R appuser:appuser /app && chown -R appuser:appuser /app
# Copy binary from builder COPY ${TARGET_DIR}/release/gitpod /app/gitpod
COPY --from=builder /app/target/release/gitpod /app/gitpod
# Set ownership
RUN chown -R appuser:appuser /app RUN chown -R appuser:appuser /app
# Switch to non-root user
USER appuser USER appuser
# Set working directory
WORKDIR /app WORKDIR /app
# Expose port EXPOSE 8080 2222 50051
EXPOSE 5082
# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:5082/health || exit 1 CMD curl -f http://localhost:8080/health || exit 1
# Run the application CMD ["./gitpod"]
CMD ["./gitpod"]

View File

@ -1,65 +1,26 @@
# GitDataAI Backend - GitSync Service ARG TARGET_DIR=target
# Multi-stage build for Rust application
# Stage 1: Build the application FROM ubuntu:26.04
FROM rust:1.96-bookworm AS builder
# Install system dependencies RUN apt-get update && apt-get install -y --no-install-recommends \
RUN apt-get update && apt-get install -y \ ca-certificates libssl3 openssh-client procps git \
pkg-config \
libssl-dev \
libpq-dev \
cmake \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/*
RUN git config --system --add safe.directory '*'
# Create app directory
WORKDIR /app
# Copy workspace files
COPY Cargo.toml Cargo.lock ./
COPY app/ app/
COPY lib/ lib/
# Build the application in release mode
RUN cargo build --release --bin gitsync
# Stage 2: Create runtime image
FROM debian:bookworm-slim
# Install runtime dependencies
RUN apt-get update && apt-get install -y \
libssl3 \
libpq5 \
ca-certificates \
curl \
&& rm -rf /var/lib/apt/lists/*
# Create non-root user
RUN useradd -r -s /bin/false appuser RUN useradd -r -s /bin/false appuser
# Create directories RUN mkdir -p /app/data/repos /app/logs \
RUN mkdir -p /app/data/repos \
/app/logs \
&& chown -R appuser:appuser /app && chown -R appuser:appuser /app
# Copy binary from builder COPY ${TARGET_DIR}/release/gitsync /app/gitsync
COPY --from=builder /app/target/release/gitsync /app/gitsync
# Set ownership
RUN chown -R appuser:appuser /app RUN chown -R appuser:appuser /app
# Switch to non-root user
USER appuser USER appuser
# Set working directory
WORKDIR /app WORKDIR /app
# Expose health check port EXPOSE 8081
EXPOSE 5083
# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:5083/health || exit 1 CMD curl -f http://localhost:8081/health || exit 1
# Run the application CMD ["./gitsync"]
CMD ["./gitsync"]

View File

@ -1,58 +0,0 @@
# GitDataAI Database Migration Dockerfile
# Multi-stage build for Rust migration tool
# Stage 1: Build the application
FROM rust:1.96-bookworm AS builder
# Install system dependencies
RUN apt-get update && apt-get install -y \
pkg-config \
libssl-dev \
libpq-dev \
cmake \
&& rm -rf /var/lib/apt/lists/*
# Create app directory
WORKDIR /app
# Copy workspace files
COPY Cargo.toml Cargo.lock ./
COPY app/ app/
COPY lib/ lib/
# Build the migration binary
RUN cargo build --release --bin migrate
# Stage 2: Create runtime image
FROM debian:bookworm-slim
# Install runtime dependencies
RUN apt-get update && apt-get install -y \
libssl3 \
libpq5 \
ca-certificates \
&& rm -rf /var/lib/apt/lists/*
# Create non-root user
RUN useradd -r -s /bin/false appuser
# Create app directory
RUN mkdir -p /app && chown -R appuser:appuser /app
# Copy binary from builder
COPY --from=builder /app/target/release/migrate /app/migrate
# Copy migration files
COPY --from=builder /app/lib/migrate/sql /app/sql
# Set ownership
RUN chown -R appuser:appuser /app
# Switch to non-root user
USER appuser
# Set working directory
WORKDIR /app
# Run migrations by default
CMD ["./migrate", "up"]

View File

@ -1,128 +1,83 @@
#!/bin/bash #!/bin/bash
# GitDataAI Docker Push Script
set -e set -e
# Get version from Cargo.toml
PROJECT_ROOT="$(cd "$(dirname "$0")/.." && pwd)" PROJECT_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
CARGO_VERSION=$(grep -m1 'version' "${PROJECT_ROOT}/Cargo.toml" | sed 's/.*"\(.*\)".*/\1/') CARGO_VERSION=$(grep -m1 'version' "${PROJECT_ROOT}/Cargo.toml" | sed 's/.*"\(.*\)".*/\1/')
# Configuration REGISTRY=${REGISTRY:-"harbor.gitdata.me/app"}
REGISTRY=${REGISTRY:-""}
TAG=${TAG:-"${CARGO_VERSION:-latest}"} TAG=${TAG:-"${CARGO_VERSION:-latest}"}
# Colors for output if command -v podman &>/dev/null; then
RED='\033[0;31m' DOCKER=podman
GREEN='\033[0;32m' elif command -v docker &>/dev/null; then
YELLOW='\033[1;33m' DOCKER=docker
NC='\033[0m' # No Color else
echo "ERROR: neither podman nor docker found"
exit 1
fi
# Services to push SERVICES=("gitdata" "gitpod" "gitsync" "email" "web")
SERVICES=("gitdata" "email" "gitpod" "gitsync" "migrate" "web")
# Function to print colored output log_info() { echo -e "\033[0;32m[INFO]\033[0m $1"; }
log_info() { log_warn() { echo -e "\033[1;33m[WARN]\033[0m $1"; }
echo -e "${GREEN}[INFO]${NC} $1" log_error() { echo -e "\033[0;31m[ERROR]\033[0m $1"; }
}
log_warn() { push_image() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# Function to push a service
push_service() {
local service=$1 local service=$1
local image_name="gitdata-${service}" local image="${REGISTRY}/gitdata-${service}:${TAG}"
# Add registry prefix if set if ! $DOCKER image inspect "$image" >/dev/null 2>&1; then
if [ -n "$REGISTRY" ]; then log_error "Image not found: $image"
image_name="${REGISTRY}/${image_name}" log_error "Build first: ./build.sh $service"
fi
log_info "Pushing ${service}..."
# Check if image exists locally
if ! docker image inspect "${image_name}:${TAG}" > /dev/null 2>&1; then
log_error "Image not found: ${image_name}:${TAG}"
log_error "Please build the image first with: ./build.sh ${service}"
return 1 return 1
fi fi
docker push "${image_name}:${TAG}" log_info "Pushing $image"
$DOCKER push "$image"
log_info "Successfully pushed ${image_name}:${TAG}" log_info "Pushed $image"
} }
# Parse command line arguments
PUSH_SERVICES=() PUSH_SERVICES=()
PUSH_ALL=true PUSH_ALL=true
while [[ $# -gt 0 ]]; do while [[ $# -gt 0 ]]; do
case $1 in case $1 in
--tag|-t) --tag|-t) TAG="$2"; shift 2 ;;
TAG="$2" --registry|-r) REGISTRY="$2"; shift 2 ;;
shift 2
;;
--registry|-r)
REGISTRY="$2"
shift 2
;;
--help|-h) --help|-h)
echo "Usage: $0 [OPTIONS] [SERVICE...]" echo "Usage: $0 [OPTIONS] [SERVICE...]"
echo "" echo ""
echo "Options:" echo "Options:"
echo " -t, --tag TAG Docker image tag (default: latest)" echo " -t, --tag TAG Image tag (default: from Cargo.toml)"
echo " -r, --registry REG Docker registry prefix (required)" echo " -r, --registry REG Registry prefix (default: harbor.gitdata.me/app)"
echo " -h, --help Show this help message"
echo "" echo ""
echo "Services:" echo "Services:"
echo " gitdata Main API service" echo " gitdata gitpod gitsync email web"
echo " email Email service"
echo " gitpod GitPod service"
echo " gitsync GitSync service"
echo " migrate Database migration"
echo " web Web frontend"
echo "" echo ""
echo "Examples:" echo "Examples:"
echo " $0 -r registry.com # Push all services" echo " $0 # Push all"
echo " $0 -r registry.com gitdata web # Push specific services" echo " $0 gitdata gitpod # Push specific services"
echo " $0 -r registry.com -t v1.0.0 # Push with custom tag" echo " $0 -t v1.2.0 # Push with custom tag"
echo " $0 -r myreg.io/app -t dev # Push with custom registry and tag"
exit 0 exit 0
;; ;;
*) *) PUSH_SERVICES+=("$1"); PUSH_ALL=false; shift ;;
PUSH_SERVICES+=("$1")
PUSH_ALL=false
shift
;;
esac esac
done done
# Validate registry
if [ -z "$REGISTRY" ]; then
log_error "Registry is required. Use -r or --registry to specify."
echo "Example: $0 -r registry.com"
exit 1
fi
# Push services
log_info "Starting Docker push..."
log_info "Registry: ${REGISTRY}" log_info "Registry: ${REGISTRY}"
log_info "Tag: ${TAG}" log_info "Tag: ${TAG}"
if [ "$PUSH_ALL" = true ]; then if [ "$PUSH_ALL" = true ]; then
log_info "Pushing all services..." log_info "Pushing all services..."
for service in "${SERVICES[@]}"; do for svc in "${SERVICES[@]}"; do
push_service "$service" push_image "$svc"
done done
else else
log_info "Pushing specified services: ${PUSH_SERVICES[*]}" log_info "Pushing: ${PUSH_SERVICES[*]}"
for service in "${PUSH_SERVICES[@]}"; do for svc in "${PUSH_SERVICES[@]}"; do
push_service "$service" push_image "$svc"
done done
fi fi
log_info "Push completed successfully!" log_info "Done."

View File

@ -1,62 +1,30 @@
# GitDataAI Frontend Dockerfile FROM oven/bun:1 AS builder
# Multi-stage build for React application with Bun
# Stage 1: Build the application
FROM node:24-bookworm AS builder
# Install bun
RUN npm install -g bun
# Create app directory
WORKDIR /app WORKDIR /app
# Copy package files
COPY package.json bun.lock ./ COPY package.json bun.lock ./
# Install dependencies
RUN bun install --frozen-lockfile RUN bun install --frozen-lockfile
# Copy source code
COPY src/ src/ COPY src/ src/
COPY public/ public/ COPY public/ public/
COPY index.html ./ COPY index.html vite.config.ts tsconfig*.json eslint.config.js components.json orval.config.ts ./
COPY vite.config.ts ./
COPY tsconfig*.json ./
COPY eslint.config.js ./
COPY components.json ./
COPY orval.config.ts ./
# Build the application
RUN bun run build RUN bun run build
# Stage 2: Create runtime image with Nginx
FROM nginx:alpine FROM nginx:alpine
# Copy custom nginx configuration
COPY docker/nginx.conf /etc/nginx/conf.d/default.conf COPY docker/nginx.conf /etc/nginx/conf.d/default.conf
# Copy built assets from builder
COPY --from=builder /app/dist /usr/share/nginx/html COPY --from=builder /app/dist /usr/share/nginx/html
# Create non-root user RUN adduser -D -S -h /var/cache/nginx -s /sbin/nologin -G nginx appuser \
RUN adduser -D -S -h /var/cache/nginx -s /sbin/nologin -G nginx appuser && chown -R appuser:nginx /var/cache/nginx /var/log/nginx /etc/nginx/conf.d \
&& touch /var/run/nginx.pid && chown appuser:nginx /var/run/nginx.pid
# Set ownership
RUN chown -R appuser:nginx /var/cache/nginx \
&& chown -R appuser:nginx /var/log/nginx \
&& chown -R appuser:nginx /etc/nginx/conf.d \
&& touch /var/run/nginx.pid \
&& chown -R appuser:nginx /var/run/nginx.pid
# Switch to non-root user
USER appuser USER appuser
# Expose port
EXPOSE 80 EXPOSE 80
# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost:80/ || exit 1 CMD wget --no-verbose --tries=1 --spider http://localhost:80/ || exit 1
# Start Nginx CMD ["nginx", "-g", "daemon off;"]
CMD ["nginx", "-g", "daemon off;"]