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 文件
## 服务
| 文件名 | 服务 | 说明 |
|--------|------|------|
| `gitdata.Dockerfile` | GitData API | 主 API 服务 |
| `email.Dockerfile` | Email Service | 邮件发送服务 |
| `gitpod.Dockerfile` | GitPod Service | Git 服务 |
| `gitsync.Dockerfile` | GitSync Service | Git 同步服务 |
| `migrate.Dockerfile` | Database Migration | 数据库迁移工具 |
| `web.Dockerfile` | Web Frontend | React 前端应用 |
| Dockerfile | 服务 | 端口 | 健康检查 |
|-----------|------|------|---------|
| `gitdata.Dockerfile` | API 服务 | 8080 | `/metrics` |
| `gitpod.Dockerfile` | Git 协议 (HTTP/SSH/gRPC) | 8080, 2222, 50051 | `/health` |
| `gitsync.Dockerfile` | Git 同步 worker | 8081 | `/health` |
| `email.Dockerfile` | 邮件 worker | 8083 | `/health` |
| `web.Dockerfile` | 前端 | 80 | `/` |
### 配置文件
## 构建
| 文件名 | 说明 |
|--------|------|
| `docker-compose.yml` | 完整的开发环境配置 |
| `nginx.conf` | Nginx 反向代理配置 |
## 快速开始
### 1. 启动完整开发环境
先编译 Rust 二进制,再打镜像:
```bash
# 进入 docker 目录
cd docker
# 编译全部 Rust 服务
cargo build --release
# 启动所有服务
docker-compose up -d
# 构建全部镜像 (默认推送到 harbor.gitdata.me/app)
./docker/build.sh
# 查看服务状态
docker-compose ps
# 只构建指定服务
./docker/build.sh gitdata gitpod
# 查看日志
docker-compose logs -f
# 自定义 tag
./docker/build.sh -t v1.2.0
# 自定义 registry
./docker/build.sh -r myreg.io/app -t dev
```
### 2. 单独构建服务
## 推送
```bash
# 构建 GitData API
docker build -f docker/gitdata.Dockerfile -t gitdata-api .
# 推送全部 (默认 harbor.gitdata.me/app)
./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
# 数据库配置
POSTGRES_USER=gitdata
POSTGRES_PASSWORD=your_secure_password
POSTGRES_DB=app
# MinIO 配置
MINIO_ROOT_USER=admin
MINIO_ROOT_PASSWORD=your_secure_password
docker compose -f docker/docker-compose.yml up -d
```
## 服务端口
| 服务 | 端口 | 说明 |
|------|------|------|
| 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. 修改环境变量
compose 默认从 `harbor.gitdata.me/app` 拉取镜像,可通过环境变量覆盖:
```bash
# 复制示例配置
cp .env.example .env
# 编辑配置文件,修改密码等敏感信息
vim .env
IMAGE_REGISTRY=myreg.io/app IMAGE_TAG=v1.2.0 \
docker compose -f docker/docker-compose.yml up -d
```
### 2. 启动服务
## 镜像结构
```bash
# 使用生产配置启动
docker-compose -f docker-compose.yml up -d
# 查看服务状态
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" # 修改宿主机端口
```
- Rust 服务:`debian:bookworm-slim` + 预编译二进制(~20MB
- 前端:多阶段构建 `oven/bun` + `nginx:alpine`
- 数据库迁移在 gitdata 启动时自动执行(见 lib/migrate

View File

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

View File

@ -1,8 +1,4 @@
# GitDataAI Docker Compose
# Full stack deployment configuration
services:
# PostgreSQL Database
postgres:
image: postgres:16-alpine
container_name: gitdata-postgres
@ -21,7 +17,6 @@ services:
retries: 5
restart: unless-stopped
# Redis Cluster
redis:
image: redis:7-alpine
container_name: gitdata-redis
@ -36,7 +31,6 @@ services:
retries: 5
restart: unless-stopped
# Qdrant Vector Database
qdrant:
image: qdrant/qdrant:latest
container_name: gitdata-qdrant
@ -46,7 +40,6 @@ services:
- qdrant_data:/qdrant/storage
restart: unless-stopped
# NATS Message Queue
nats:
image: nats:alpine
container_name: gitdata-nats
@ -56,7 +49,6 @@ services:
command: "--jetstream"
restart: unless-stopped
# MinIO S3 Storage
minio:
image: minio/minio:latest
container_name: gitdata-minio
@ -71,24 +63,8 @@ services:
- minio_data:/data
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:
build:
context: ..
dockerfile: docker/gitdata.Dockerfile
image: ${IMAGE_REGISTRY:-harbor.gitdata.me/app/}gitdata-gitdata:${IMAGE_TAG:-latest}
container_name: gitdata-api
environment:
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_ACCESS_KEY_ID: ${MINIO_ROOT_USER:-admin}
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:
- "8080:8080"
- "5023:5023"
- "5030:5030"
- "5022:5022"
volumes:
- gitdata_repos:/app/data/repos
- gitdata_files:/app/data/files
@ -118,20 +95,20 @@ services:
condition: service_started
minio:
condition: service_started
migrate:
condition: service_completed_successfully
restart: unless-stopped
# Email Service
email:
build:
context: ..
dockerfile: docker/email.Dockerfile
image: ${IMAGE_REGISTRY:-harbor.gitdata.me/app/}gitdata-email:${IMAGE_TAG:-latest}
container_name: gitdata-email
environment:
APP_DATABASE_URL: postgres://${POSTGRES_USER:-gitdata}:${POSTGRES_PASSWORD:-gitdata123}@postgres:5432/${POSTGRES_DB:-app}
APP_REDIS_URLS: redis://redis:6379
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:
postgres:
condition: service_healthy
@ -141,17 +118,19 @@ services:
condition: service_started
restart: unless-stopped
# GitPod Service
gitpod:
build:
context: ..
dockerfile: docker/gitpod.Dockerfile
image: ${IMAGE_REGISTRY:-harbor.gitdata.me/app/}gitdata-gitpod:${IMAGE_TAG:-latest}
container_name: gitdata-gitpod
environment:
APP_DATABASE_URL: postgres://${POSTGRES_USER:-gitdata}:${POSTGRES_PASSWORD:-gitdata123}@postgres:5432/${POSTGRES_DB:-app}
APP_REDIS_URLS: redis://redis:6379
APP_GIT_HTTP_PORT: "8080"
APP_GIT_RPC_PORT: "50051"
APP_SSH_PORT: "2222"
ports:
- "5082:5082"
- "2222:2222"
- "8081:8080"
- "50051:50051"
volumes:
- gitdata_repos:/app/data/repos
depends_on:
@ -161,17 +140,15 @@ services:
condition: service_healthy
restart: unless-stopped
# GitSync Service
gitsync:
build:
context: ..
dockerfile: docker/gitsync.Dockerfile
image: ${IMAGE_REGISTRY:-harbor.gitdata.me/app/}gitdata-gitsync:${IMAGE_TAG:-latest}
container_name: gitdata-gitsync
environment:
APP_DATABASE_URL: postgres://${POSTGRES_USER:-gitdata}:${POSTGRES_PASSWORD:-gitdata123}@postgres:5432/${POSTGRES_DB:-app}
APP_REDIS_URLS: redis://redis:6379
APP_GITSYNC_HEALTH_PORT: "8081"
ports:
- "5083:5083"
- "8082:8081"
volumes:
- gitdata_repos:/app/data/repos
depends_on:
@ -181,11 +158,8 @@ services:
condition: service_healthy
restart: unless-stopped
# Web Frontend
web:
build:
context: ..
dockerfile: docker/web.Dockerfile
image: ${IMAGE_REGISTRY:-harbor.gitdata.me/app/}gitdata-web:${IMAGE_TAG:-latest}
container_name: gitdata-web
ports:
- "80:80"

View File

@ -1,61 +1,26 @@
# GitDataAI Backend - Email Service
# Multi-stage build for Rust application
ARG TARGET_DIR=target
# Stage 1: Build the application
FROM rust:1.96-bookworm AS builder
FROM ubuntu:26.04
# Install system dependencies
RUN apt-get update && apt-get install -y \
pkg-config \
libssl-dev \
libpq-dev \
cmake \
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates libssl3 openssh-client procps git \
&& 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
# Create directories
RUN mkdir -p /app/logs \
&& chown -R appuser:appuser /app
# Copy binary from builder
COPY --from=builder /app/target/release/email-service /app/email-service
# Set ownership
COPY ${TARGET_DIR}/release/email-service /app/email-service
RUN chown -R appuser:appuser /app
# Switch to non-root user
USER appuser
# Set working directory
WORKDIR /app
# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD pgrep email-service || exit 1
EXPOSE 8083
HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
CMD curl -f http://localhost:8083/health || exit 1
# Run the application
CMD ["./email-service"]

View File

@ -1,74 +1,26 @@
# GitDataAI Backend - GitData Service
# Multi-stage build for Rust application
ARG TARGET_DIR=target
# Stage 1: Build the application
FROM rust:1.96-bookworm AS builder
FROM ubuntu:26.04
# Install system dependencies
RUN apt-get update && apt-get install -y \
pkg-config \
libssl-dev \
libpq-dev \
cmake \
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates libssl3 openssh-client procps git \
&& 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
# 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
# Copy binary from builder
COPY --from=builder /app/target/release/gitdata /app/gitdata
# Set ownership
COPY ${TARGET_DIR}/release/gitdata /app/gitdata
RUN chown -R appuser:appuser /app
# Switch to non-root user
USER appuser
# Set working directory
WORKDIR /app
# Expose ports
# API port
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=5s --retries=3 \
CMD curl -f http://localhost:8080/health || exit 1
HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
CMD curl -f http://localhost:8080/metrics || exit 1
# Run the application
CMD ["./gitdata"]

View File

@ -1,65 +1,26 @@
# GitDataAI Backend - GitPod Service
# Multi-stage build for Rust application
ARG TARGET_DIR=target
# Stage 1: Build the application
FROM rust:1.96-bookworm AS builder
FROM ubuntu:26.04
# Install system dependencies
RUN apt-get update && apt-get install -y \
pkg-config \
libssl-dev \
libpq-dev \
cmake \
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates libssl3 openssh-client procps git \
&& 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
# Create directories
RUN mkdir -p /app/data/repos \
/app/logs \
RUN mkdir -p /app/data/repos /app/logs \
&& chown -R appuser:appuser /app
# Copy binary from builder
COPY --from=builder /app/target/release/gitpod /app/gitpod
# Set ownership
COPY ${TARGET_DIR}/release/gitpod /app/gitpod
RUN chown -R appuser:appuser /app
# Switch to non-root user
USER appuser
# Set working directory
WORKDIR /app
# Expose port
EXPOSE 5082
EXPOSE 8080 2222 50051
# Health check
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"]

View File

@ -1,65 +1,26 @@
# GitDataAI Backend - GitSync Service
# Multi-stage build for Rust application
ARG TARGET_DIR=target
# Stage 1: Build the application
FROM rust:1.96-bookworm AS builder
FROM ubuntu:26.04
# Install system dependencies
RUN apt-get update && apt-get install -y \
pkg-config \
libssl-dev \
libpq-dev \
cmake \
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates libssl3 openssh-client procps git \
&& 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
# Create directories
RUN mkdir -p /app/data/repos \
/app/logs \
RUN mkdir -p /app/data/repos /app/logs \
&& chown -R appuser:appuser /app
# Copy binary from builder
COPY --from=builder /app/target/release/gitsync /app/gitsync
# Set ownership
COPY ${TARGET_DIR}/release/gitsync /app/gitsync
RUN chown -R appuser:appuser /app
# Switch to non-root user
USER appuser
# Set working directory
WORKDIR /app
# Expose health check port
EXPOSE 5083
EXPOSE 8081
# Health check
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"]

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

View File

@ -1,62 +1,30 @@
# GitDataAI Frontend Dockerfile
# Multi-stage build for React application with Bun
FROM oven/bun:1 AS builder
# Stage 1: Build the application
FROM node:24-bookworm AS builder
# Install bun
RUN npm install -g bun
# Create app directory
WORKDIR /app
# Copy package files
COPY package.json bun.lock ./
# Install dependencies
RUN bun install --frozen-lockfile
# Copy source code
COPY src/ src/
COPY public/ public/
COPY index.html ./
COPY vite.config.ts ./
COPY tsconfig*.json ./
COPY eslint.config.js ./
COPY components.json ./
COPY orval.config.ts ./
COPY index.html vite.config.ts tsconfig*.json eslint.config.js components.json orval.config.ts ./
# Build the application
RUN bun run build
# Stage 2: Create runtime image with Nginx
FROM nginx:alpine
# Copy custom nginx configuration
COPY docker/nginx.conf /etc/nginx/conf.d/default.conf
# Copy built assets from builder
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
# Expose port
EXPOSE 80
# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost:80/ || exit 1
# Start Nginx
CMD ["nginx", "-g", "daemon off;"]