This commit is contained in:
goro 2026-03-21 11:18:44 +02:00
commit f5217f61f8
11 changed files with 482 additions and 0 deletions

21
.gitignore vendored Normal file
View File

@ -0,0 +1,21 @@
.vscode
.DS_STORE
# Environment files
deployments/.env
*.env
!.env.example
*.env.local
# Docker volumes and data
**/data.ms/
**/dumps/
**/snapshots/
# Build artifacts
**/tmp/
**/dist/
**/node_modules/
# OS files
**/.DS_Store

9
.gitmodules vendored Normal file
View File

@ -0,0 +1,9 @@
[submodule "hiling_go"]
path = hiling_go
url = https://git.nochill.in/nochill/hiling_go.git
[submodule "hiling-opengraph"]
path = hiling-opengraph
url = https://git.nochill.in/nochill/hiling-opengraph.git
[submodule "hilingriviw"]
path = hilingriviw
url = https://git.nochill.in/nochill/hilingriviw.git

48
deployments/.dockerignore Normal file
View File

@ -0,0 +1,48 @@
# Git
.git
.gitignore
.gitattributes
# Documentation
*.md
README.md
LICENSE
CHANGELOG.md
# Development files
.vscode
.idea
*.log
*.logs
# Node
node_modules
npm-debug.log
yarn-error.log
.npm
.yarn
# Go
*.test
*.out
tmp/
# Environment
.env
.env.*
!.env.example
*.local
# OS
.DS_Store
Thumbs.db
.cache
# Deployment
deployments/
docker-compose.yml
# Tests
test-results/
playwright-report/
coverage/

27
deployments/.env.example Normal file
View File

@ -0,0 +1,27 @@
# Database Configuration
DB_USERNAME=postgres
DB_PASSWORD=your_secure_password_here
DB_NAME=hiling
DB_PORT=5432
# Backend API Configuration
BACKEND_PORT=8888
TOKEN_SYMMETRIC_KEY=your_32_character_secret_key_here
TOKEN_DURATION=720h
COOKIE_DURATION=86400
REFRESH_TOKEN_DURATION=720h
# Meilisearch Configuration
MEILI_MASTER_KEY=your_secure_meilisearch_master_key
MEILI_PORT=7700
# OpenGraph Service Configuration
OPENGRAPH_PORT=1234
# Frontend Configuration
FRONTEND_PORT=80
# Production Settings
# Set to 'production' in production environment
NODE_ENV=production
GIN_MODE=release

View File

@ -0,0 +1,38 @@
# Backend Dockerfile for hiling_go
FROM golang:1.20-alpine AS builder
# Install build dependencies
RUN apk add --no-cache git
WORKDIR /app
# Copy go mod files
COPY hiling_go/go.mod hiling_go/go.sum ./
# Download dependencies
RUN go mod download
# Copy source code
COPY hiling_go/ ./
# Build the application
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main .
# Production stage
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
# Copy the binary from builder
COPY --from=builder /app/main .
# Copy public directory if it exists
COPY --from=builder /app/public ./public
# Expose port
EXPOSE 8888
# Run the binary
CMD ["./main"]

View File

@ -0,0 +1,32 @@
# Frontend Dockerfile for hilingriviw
FROM node:18-alpine AS builder
WORKDIR /app
# Install pnpm
RUN npm install -g pnpm
# Copy package files
COPY hilingriviw/package.json hilingriviw/pnpm-lock.yaml ./
# Install dependencies
RUN pnpm install --frozen-lockfile
# Copy source code
COPY hilingriviw/ ./
# Build the application
RUN pnpm build
# Production stage - serve with nginx
FROM nginx:alpine
# Copy built files
COPY --from=builder /app/dist /usr/share/nginx/html
# Copy nginx configuration
COPY deployments/nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

View File

@ -0,0 +1,15 @@
# OpenGraph Dockerfile for hiling-opengraph
FROM denoland/deno:alpine-1.41.0
WORKDIR /app
# Copy all files
COPY hiling-opengraph/ ./
# Cache dependencies
RUN deno cache main.ts
EXPOSE 1234
# Run the application
CMD ["deno", "run", "--allow-net", "--allow-read", "--allow-env", "main.ts"]

View File

@ -0,0 +1,46 @@
# Development docker-compose with hot reloading
version: '3.8'
services:
# PostgreSQL Database
postgres:
image: postgres:15-alpine
container_name: hiling_postgres_dev
environment:
POSTGRES_USER: ${DB_USERNAME:-postgres}
POSTGRES_PASSWORD: ${DB_PASSWORD:-password}
POSTGRES_DB: ${DB_NAME:-hiling}
volumes:
- postgres_data_dev:/var/lib/postgresql/data
ports:
- "${DB_PORT:-5432}:5432"
networks:
- hiling_network_dev
restart: unless-stopped
# Meilisearch
meilisearch:
image: getmeili/meilisearch:v1.7
container_name: hiling_meilisearch_dev
environment:
MEILI_MASTER_KEY: ${MEILI_MASTER_KEY:-12rchaaonetdadaaoenh}
MEILI_NO_ANALYTICS: "true"
MEILI_ENV: development
MEILI_HTTP_ADDR: 0.0.0.0:7700
volumes:
- meilisearch_data_dev:/meili_data
ports:
- "${MEILI_PORT:-7700}:7700"
networks:
- hiling_network_dev
restart: unless-stopped
volumes:
postgres_data_dev:
driver: local
meilisearch_data_dev:
driver: local
networks:
hiling_network_dev:
driver: bridge

View File

@ -0,0 +1,134 @@
version: '3.8'
services:
# PostgreSQL Database
postgres:
image: postgres:15-alpine
container_name: hiling_postgres
environment:
POSTGRES_USER: ${DB_USERNAME:-postgres}
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_DB: ${DB_NAME:-hiling}
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- "${DB_PORT:-5432}:5432"
networks:
- hiling_network
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${DB_USERNAME:-postgres}"]
interval: 10s
timeout: 5s
retries: 5
# Meilisearch
meilisearch:
image: getmeili/meilisearch:v1.7
container_name: hiling_meilisearch
environment:
MEILI_MASTER_KEY: ${MEILI_MASTER_KEY}
MEILI_NO_ANALYTICS: "true"
MEILI_ENV: production
MEILI_HTTP_ADDR: 0.0.0.0:7700
volumes:
- meilisearch_data:/meili_data
ports:
- "${MEILI_PORT:-7700}:7700"
networks:
- hiling_network
restart: unless-stopped
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--spider", "http://localhost:7700/health"]
interval: 10s
timeout: 5s
retries: 5
# Backend API (Go)
backend:
build:
context: ..
dockerfile: deployments/Dockerfile.backend
container_name: hiling_backend
environment:
DB_TYPE: postgres
DB_USERNAME: ${DB_USERNAME:-postgres}
DB_PASSWORD: ${DB_PASSWORD}
DB_NAME: ${DB_NAME:-hiling}
DB_HOST: postgres
DB_PORT: 5432
DB_SOURCE: postgresql://${DB_USERNAME:-postgres}:${DB_PASSWORD}@postgres:5432/${DB_NAME:-hiling}?sslmode=disable
SERVER_ADDRESS: 0.0.0.0:8888
TOKEN_SYMMETRIC_KEY: ${TOKEN_SYMMETRIC_KEY}
TOKEN_DURATION: ${TOKEN_DURATION:-1024h}
COOKIE_DURATION: ${COOKIE_DURATION:-86400}
REFRESH_TOKEN_DURATION: ${REFRESH_TOKEN_DURATION:-1024h}
ports:
- "${BACKEND_PORT:-8888}:8888"
depends_on:
postgres:
condition: service_healthy
meilisearch:
condition: service_healthy
networks:
- hiling_network
restart: unless-stopped
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--spider", "http://localhost:8888/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
# OpenGraph Service (Deno)
opengraph:
build:
context: ..
dockerfile: deployments/Dockerfile.opengraph
container_name: hiling_opengraph
environment:
APP_PORT: 1234
DB_TYPE: postgres
DB_USERNAME: ${DB_USERNAME:-postgres}
DB_PASSWORD: ${DB_PASSWORD}
DB_NAME: ${DB_NAME:-hiling}
DB_HOST: postgres
DB_PORT: 5432
ports:
- "${OPENGRAPH_PORT:-1234}:1234"
depends_on:
postgres:
condition: service_healthy
networks:
- hiling_network
restart: unless-stopped
# Frontend (Nginx serving static files)
frontend:
build:
context: ..
dockerfile: deployments/Dockerfile.frontend
container_name: hiling_frontend
ports:
- "${FRONTEND_PORT:-80}:80"
depends_on:
- backend
- opengraph
networks:
- hiling_network
restart: unless-stopped
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--spider", "http://localhost:80"]
interval: 30s
timeout: 10s
retries: 3
volumes:
postgres_data:
driver: local
meilisearch_data:
driver: local
networks:
hiling_network:
driver: bridge

33
deployments/nginx.conf Normal file
View File

@ -0,0 +1,33 @@
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.html;
# Enable gzip compression
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml+rss application/json application/javascript;
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
# SPA routing - serve index.html for all routes
location / {
try_files $uri $uri/ /index.html;
}
# Cache static assets
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# Disable cache for index.html
location = /index.html {
add_header Cache-Control "no-cache";
}
}

79
run-dev.sh Executable file
View File

@ -0,0 +1,79 @@
#!/bin/bash
# Script to run all development servers concurrently
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
MAGENTA='\033[0;35m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color
# Function to cleanup processes on exit
cleanup() {
echo -e "\n${YELLOW}Shutting down all services...${NC}"
kill $(jobs -p) 2>/dev/null
wait
echo -e "${GREEN}All services stopped${NC}"
exit 0
}
# Set up trap to cleanup on script exit
trap cleanup EXIT INT TERM
# Function to run a service with colored output
run_service() {
local name=$1
local color=$2
local dir=$3
shift 3
local cmd="$@"
echo -e "${color}Starting $name...${NC}"
(cd "$dir" && exec $cmd 2>&1 | sed "s/^/[$name] /" | while IFS= read -r line; do echo -e "${color}${line}${NC}"; done) &
}
# Check if required tools are installed
echo -e "${CYAN}Checking requirements...${NC}"
if ! command -v air &> /dev/null; then
echo -e "${RED}Error: 'air' is not installed. Please install it first:${NC}"
echo "go install github.com/air-verse/air@latest"
exit 1
fi
if ! command -v pnpm &> /dev/null; then
echo -e "${RED}Error: 'pnpm' is not installed. Please install it first:${NC}"
echo "npm install -g pnpm"
exit 1
fi
if ! command -v deno &> /dev/null; then
echo -e "${RED}Error: 'deno' is not installed. Please install it first:${NC}"
echo "curl -fsSL https://deno.land/x/install/install.sh | sh"
exit 1
fi
echo -e "${GREEN}All requirements satisfied${NC}\n"
# Start all services
echo -e "${CYAN}Starting all development servers...${NC}\n"
# Backend with air
run_service "Backend" "$GREEN" "hiling_go" air
# Meilisearch
run_service "Meilisearch" "$YELLOW" "hiling_go" ./dev-meilisearch.sh
# Frontend with pnpm
run_service "Frontend" "$BLUE" "hilingriviw" pnpm dev
# OpenGraph with deno
run_service "OpenGraph" "$MAGENTA" "hiling-opengraph" deno task dev
echo -e "\n${CYAN}All services started!${NC}"
echo -e "${CYAN}Press Ctrl+C to stop all services${NC}\n"
# Wait for all background processes
wait