diff --git a/docker/Dockerfile.api b/docker/Dockerfile.api new file mode 100644 index 0000000..1088e53 --- /dev/null +++ b/docker/Dockerfile.api @@ -0,0 +1,36 @@ +# API Service Dockerfile +FROM golang:1.21-alpine AS builder + +WORKDIR /build + +# Copy go workspace +COPY go.work* ./ +COPY go.mod* ./services/api/ +COPY go.sum* ./services/api/ 2>/dev/null || true + +# Copy shared packages +COPY pkg/ ./pkg/ + +# Copy service +COPY services/api/ ./services/api/ + +# Build +WORKDIR /build/services/api +RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o /app/api . + +# Final image +FROM alpine:3.18 + +RUN apk --no-cache add ca-certificates curl + +WORKDIR /app + +COPY --from=builder /app/api . + +# Health check +HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ + CMD curl -f http://localhost:8080/health || exit 1 + +EXPOSE 8080 + +CMD ["/app/api"] diff --git a/docker/Dockerfile.middleware b/docker/Dockerfile.middleware new file mode 100644 index 0000000..6cd0ac5 --- /dev/null +++ b/docker/Dockerfile.middleware @@ -0,0 +1,36 @@ +# Middleware Service Dockerfile +FROM golang:1.21-alpine AS builder + +WORKDIR /build + +# Copy go workspace +COPY go.work* ./ +COPY go.mod* ./services/middleware/ +COPY go.sum* ./services/middleware/ 2>/dev/null || true + +# Copy shared packages +COPY pkg/ ./pkg/ + +# Copy service +COPY services/middleware/ ./services/middleware/ + +# Build +WORKDIR /build/services/middleware +RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o /app/middleware . + +# Final image +FROM alpine:3.18 + +RUN apk --no-cache add ca-certificates curl + +WORKDIR /app + +COPY --from=builder /app/middleware . + +# Health check +HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ + CMD curl -f http://localhost:8082/health || exit 1 + +EXPOSE 8082 + +CMD ["/app/middleware"] diff --git a/docker/Dockerfile.worker b/docker/Dockerfile.worker new file mode 100644 index 0000000..265325d --- /dev/null +++ b/docker/Dockerfile.worker @@ -0,0 +1,36 @@ +# Worker Service Dockerfile +FROM golang:1.21-alpine AS builder + +WORKDIR /build + +# Copy go workspace +COPY go.work* ./ +COPY go.mod* ./services/worker/ +COPY go.sum* ./services/worker/ 2>/dev/null || true + +# Copy shared packages +COPY pkg/ ./pkg/ + +# Copy service +COPY services/worker/ ./services/worker/ + +# Build +WORKDIR /build/services/worker +RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o /app/worker . + +# Final image +FROM alpine:3.18 + +RUN apk --no-cache add ca-certificates curl + +WORKDIR /app + +COPY --from=builder /app/worker . + +# Health check +HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ + CMD curl -f http://localhost:8081/health || exit 1 + +EXPOSE 8081 + +CMD ["/app/worker"] diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml new file mode 100644 index 0000000..b58682d --- /dev/null +++ b/docker/docker-compose.yml @@ -0,0 +1,165 @@ +version: '3.8' + +services: + # PostgreSQL (Application Database) + postgres: + image: postgres:15-alpine + container_name: YDN-Dev-Postgres + restart: unless-stopped + environment: + POSTGRES_DB: ${POSTGRES_DB:-ydn} + POSTGRES_USER: ${POSTGRES_USER:-ydn_user} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-ydn_password} + ports: + - "${POSTGRES_PORT:-5432}:5432" + volumes: + - postgres_data:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-ydn_user}"] + interval: 10s + timeout: 5s + retries: 5 + + # Redis (Queue & Cache) + redis: + image: redis:7-alpine + container_name: YDN-Dev-Redis + restart: unless-stopped + ports: + - "${REDIS_PORT:-6379}:6379" + volumes: + - redis_data:/data + healthcheck: + test: ["CMD", "redis-cli", "ping"] + interval: 10s + timeout: 5s + retries: 5 + + # MySQL (Dolibarr Database) + mysql: + image: mysql:8.0 + container_name: YDN-Dev-MySQL + restart: unless-stopped + environment: + MYSQL_DATABASE: ${DOLIBARR_DB:-dolibarr} + MYSQL_USER: ${DOLIBARR_USER:-dolibarr_user} + MYSQL_PASSWORD: ${DOLIBARR_PASSWORD:-dolibarr_password} + MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-root_password} + ports: + - "3306:3306" + volumes: + - mysql_data:/var/lib/mysql + healthcheck: + test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] + interval: 10s + timeout: 5s + retries: 5 + + # Dolibarr (ERP/CRM) + dolibarr: + image: dolibarr/dolibarr:latest + container_name: YDN-Dev-Dolibarr + restart: unless-stopped + environment: + DOLIBARR_DB_HOST: mysql + DOLIBARR_DB_USER: ${DOLIBARR_USER:-dolibarr_user} + DOLIBARR_DB_PASSWORD: ${DOLIBARR_PASSWORD:-dolibarr_password} + DOLIBARR_DB_NAME: ${DOLIBARR_DB:-dolibarr} + PHP_INI_DATE_TIMEZONE: UTC + ports: + - "8082:80" + volumes: + - dolibarr_data:/var/www/html/documents + - dolibarr_custom:/var/www/html/custom + depends_on: + mysql: + condition: service_healthy + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:80/"] + interval: 30s + timeout: 10s + retries: 3 + + # Grav CMS (Website) + grav: + image: klakegg/hugo:latest + container_name: YDN-Dev-Grav + restart: unless-stopped + ports: + - "8083:8080" + volumes: + - ./web/grav:/src + command: server --bind 0.0.0.0 --port 8080 + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8080/"] + interval: 30s + timeout: 10s + retries: 3 + + # API Service + api: + build: + context: . + dockerfile: docker/Dockerfile.api + container_name: YDN-Dev-API + restart: unless-stopped + environment: + - APP_ENV=${APP_ENV:-development} + - DATABASE_URL=postgres://${POSTGRES_USER:-ydn_user}:${POSTGRES_PASSWORD:-ydn_password}@postgres:5432/${POSTGRES_DB:-ydn} + - REDIS_URL=redis://redis:6379 + - DOLIBARR_URL=http://dolibarr:80 + - DOLIBARR_API_TOKEN=${DOLIBARR_API_TOKEN} + - STRIPE_SECRET_KEY=${STRIPE_SECRET_KEY} + - OVH_APPLICATION_KEY=${OVH_APPLICATION_KEY} + - OVH_APPLICATION_SECRET=${OVH_APPLICATION_SECRET} + - OVH_CONSUMER_KEY=${OVH_CONSUMER_KEY} + - JWT_SECRET=${JWT_SECRET} + ports: + - "${APP_PORT:-8080}:8080" + depends_on: + postgres: + condition: service_healthy + redis: + condition: service_healthy + dolibarr: + condition: service_healthy + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8080/health"] + interval: 30s + timeout: 10s + retries: 3 + + # Worker Service + worker: + build: + context: . + dockerfile: docker/Dockerfile.worker + container_name: YDN-Dev-Worker + restart: unless-stopped + environment: + - APP_ENV=${APP_ENV:-development} + - DATABASE_URL=postgres://${POSTGRES_USER:-ydn_user}:${POSTGRES_PASSWORD:-ydn_password}@postgres:5432/${POSTGRES_DB:-ydn} + - REDIS_URL=redis://redis:6379 + - DOLIBARR_URL=http://dolibarr:80 + - DOLIBARR_API_TOKEN=${DOLIBARR_API_TOKEN} + - OVH_APPLICATION_KEY=${OVH_APPLICATION_KEY} + - OVH_APPLICATION_SECRET=${OVH_APPLICATION_SECRET} + - OVH_CONSUMER_KEY=${OVH_CONSUMER_KEY} + depends_on: + postgres: + condition: service_healthy + redis: + condition: service_healthy + dolibarr: + condition: service_healthy + +volumes: + postgres_data: + redis_data: + mysql_data: + dolibarr_data: + dolibarr_custom: + +networks: + default: + name: YDN-Dev-Network