feat: Скрипт для запуска
This commit is contained in:
51
apps/backend/Dockerfile
Normal file
51
apps/backend/Dockerfile
Normal file
@ -0,0 +1,51 @@
|
||||
FROM oven/bun:1.3 AS base
|
||||
WORKDIR /app
|
||||
|
||||
# Install dependencies
|
||||
FROM base AS deps
|
||||
# Copy root package files and lockfile first
|
||||
COPY package.json bun.lock ./
|
||||
# Copy workspace structure - all package.json files needed for workspace resolution
|
||||
COPY packages ./packages
|
||||
COPY apps ./apps
|
||||
# Install all dependencies (bun will resolve workspace dependencies)
|
||||
# Note: We copy full directories but bun only needs package.json files for resolution
|
||||
RUN bun install --frozen-lockfile
|
||||
|
||||
# Build stage
|
||||
FROM base AS build
|
||||
COPY --from=deps /app/node_modules ./node_modules
|
||||
COPY --from=deps /app/packages ./packages
|
||||
# Copy backend source
|
||||
COPY apps/backend ./apps/backend
|
||||
# Build backend
|
||||
WORKDIR /app/apps/backend
|
||||
RUN bun run build
|
||||
|
||||
# Production stage
|
||||
FROM base AS production
|
||||
WORKDIR /app
|
||||
|
||||
# Copy dependencies and built files
|
||||
COPY --from=deps /app/node_modules ./node_modules
|
||||
COPY --from=deps /app/packages ./packages
|
||||
# Copy source code (needed for migrations and tests)
|
||||
COPY --from=build /app/apps/backend/src ./apps/backend/src
|
||||
COPY --from=build /app/apps/backend/dist ./apps/backend/dist
|
||||
COPY --from=build /app/apps/backend/drizzle ./apps/backend/drizzle
|
||||
COPY --from=build /app/apps/backend/package.json ./apps/backend/
|
||||
COPY --from=build /app/apps/backend/tsconfig.json ./apps/backend/
|
||||
COPY --from=build /app/apps/backend/drizzle.config.ts ./apps/backend/
|
||||
|
||||
# Set working directory to backend
|
||||
WORKDIR /app/apps/backend
|
||||
|
||||
# Set environment to production
|
||||
ENV NODE_ENV=production
|
||||
|
||||
# Expose port
|
||||
EXPOSE 3000
|
||||
|
||||
# Default command (can be overridden)
|
||||
CMD ["bun", "run", "start"]
|
||||
|
||||
137
docker-compose.yml
Normal file
137
docker-compose.yml
Normal file
@ -0,0 +1,137 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:16
|
||||
container_name: p1ctos4ve-postgres
|
||||
environment:
|
||||
POSTGRES_USER: p1ctos4ve
|
||||
POSTGRES_PASSWORD: p1ctos4ve_password
|
||||
POSTGRES_DB: p1ctos4ve
|
||||
ports:
|
||||
- "5432:5432"
|
||||
volumes:
|
||||
- postgres_data:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U p1ctos4ve"]
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
networks:
|
||||
- p1ctos4ve-network
|
||||
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
container_name: p1ctos4ve-redis
|
||||
ports:
|
||||
- "6379:6379"
|
||||
volumes:
|
||||
- redis_data:/data
|
||||
healthcheck:
|
||||
test: ["CMD", "redis-cli", "ping"]
|
||||
interval: 5s
|
||||
timeout: 3s
|
||||
retries: 5
|
||||
networks:
|
||||
- p1ctos4ve-network
|
||||
|
||||
seaweedfs-master:
|
||||
image: chrislusf/seaweedfs:latest
|
||||
container_name: p1ctos4ve-seaweedfs-master
|
||||
command: "master -ip=seaweedfs-master"
|
||||
ports:
|
||||
- "9333:9333"
|
||||
- "19333:19333"
|
||||
volumes:
|
||||
- seaweedfs_master_data:/data
|
||||
networks:
|
||||
- p1ctos4ve-network
|
||||
|
||||
seaweedfs-volume:
|
||||
image: chrislusf/seaweedfs:latest
|
||||
container_name: p1ctos4ve-seaweedfs-volume
|
||||
command: "volume -mserver=seaweedfs-master:9333 -port=8080"
|
||||
ports:
|
||||
- "8080:8080"
|
||||
depends_on:
|
||||
- seaweedfs-master
|
||||
volumes:
|
||||
- seaweedfs_volume_data:/data
|
||||
networks:
|
||||
- p1ctos4ve-network
|
||||
|
||||
seaweedfs-filer:
|
||||
image: chrislusf/seaweedfs:latest
|
||||
container_name: p1ctos4ve-seaweedfs-filer
|
||||
command: "filer -master=seaweedfs-master:9333"
|
||||
ports:
|
||||
- "8888:8888"
|
||||
depends_on:
|
||||
- seaweedfs-master
|
||||
volumes:
|
||||
- seaweedfs_filer_data:/data
|
||||
networks:
|
||||
- p1ctos4ve-network
|
||||
|
||||
seaweedfs-s3:
|
||||
image: chrislusf/seaweedfs:latest
|
||||
container_name: p1ctos4ve-seaweedfs-s3
|
||||
entrypoint: ["/bin/sh", "-c"]
|
||||
command:
|
||||
- |
|
||||
mkdir -p /data
|
||||
cat > /data/s3.json << 'EOF'
|
||||
{
|
||||
"identities": [
|
||||
{
|
||||
"name": "anonymous",
|
||||
"credentials": [
|
||||
{
|
||||
"accessKey": "",
|
||||
"secretKey": ""
|
||||
}
|
||||
],
|
||||
"actions": ["Read:p1ctos4ve"]
|
||||
},
|
||||
{
|
||||
"name": "any",
|
||||
"credentials": [
|
||||
{
|
||||
"accessKey": "any",
|
||||
"secretKey": "any"
|
||||
}
|
||||
],
|
||||
"actions": ["Admin", "Read", "Write"]
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
exec /entrypoint.sh s3 -filer=seaweedfs-filer:8888 -port=8333 -ip.bind=0.0.0.0 -config=/data/s3.json
|
||||
ports:
|
||||
- "8333:8333"
|
||||
depends_on:
|
||||
- seaweedfs-master
|
||||
- seaweedfs-volume
|
||||
- seaweedfs-filer
|
||||
volumes:
|
||||
- seaweedfs_s3_data:/data
|
||||
networks:
|
||||
- p1ctos4ve-network
|
||||
|
||||
volumes:
|
||||
postgres_data:
|
||||
driver: local
|
||||
redis_data:
|
||||
driver: local
|
||||
seaweedfs_master_data:
|
||||
driver: local
|
||||
seaweedfs_volume_data:
|
||||
driver: local
|
||||
seaweedfs_filer_data:
|
||||
driver: local
|
||||
seaweedfs_s3_data:
|
||||
driver: local
|
||||
|
||||
networks:
|
||||
p1ctos4ve-network:
|
||||
driver: bridge
|
||||
254
scripts/run.sh
Normal file
254
scripts/run.sh
Normal file
@ -0,0 +1,254 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e # Exit on any error
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Cleanup function
|
||||
cleanup() {
|
||||
echo -e "\n${YELLOW}Cleaning up...${NC}"
|
||||
docker compose down
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Trap Ctrl+C
|
||||
trap cleanup SIGINT SIGTERM
|
||||
|
||||
# Get the project root directory
|
||||
PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
cd "$PROJECT_ROOT"
|
||||
|
||||
echo -e "${GREEN}🚀 Starting RealApp backend setup...${NC}"
|
||||
|
||||
# Step 1: Start Docker services
|
||||
echo -e "${YELLOW}📦 Step 1: Starting Docker services (PostgreSQL, Redis, SeaweedFS)...${NC}"
|
||||
docker compose up -d
|
||||
|
||||
# Get the actual network name from docker compose (it adds project prefix)
|
||||
# Docker Compose uses directory name as project prefix, so network will be {project}_p1ctos4ve-network
|
||||
NETWORK_NAME=$(docker network ls --format "{{.Name}}" | grep "p1ctos4ve-network" | head -n 1)
|
||||
# Fallback to default if not found
|
||||
if [ -z "$NETWORK_NAME" ]; then
|
||||
# Try to get from docker compose config
|
||||
NETWORK_NAME=$(docker compose config 2>/dev/null | grep -A 2 "networks:" | grep "name:" | awk '{print $2}' | tr -d '"' | head -n 1)
|
||||
# Final fallback
|
||||
if [ -z "$NETWORK_NAME" ]; then
|
||||
NETWORK_NAME="realapp_p1ctos4ve-network"
|
||||
fi
|
||||
fi
|
||||
echo -e "${YELLOW}Using network: ${NETWORK_NAME}${NC}"
|
||||
|
||||
# Wait for services to be healthy
|
||||
echo -e "${YELLOW}⏳ Waiting for services to be ready...${NC}"
|
||||
|
||||
# Wait for PostgreSQL
|
||||
echo -n "Waiting for PostgreSQL..."
|
||||
until docker exec p1ctos4ve-postgres pg_isready -U p1ctos4ve > /dev/null 2>&1; do
|
||||
echo -n "."
|
||||
sleep 1
|
||||
done
|
||||
echo -e " ${GREEN}✓${NC}"
|
||||
|
||||
# Wait for Redis
|
||||
echo -n "Waiting for Redis..."
|
||||
until docker exec p1ctos4ve-redis redis-cli ping > /dev/null 2>&1; do
|
||||
echo -n "."
|
||||
sleep 1
|
||||
done
|
||||
echo -e " ${GREEN}✓${NC}"
|
||||
|
||||
# Wait for SeaweedFS master
|
||||
echo -n "Waiting for SeaweedFS master..."
|
||||
for i in {1..30}; do
|
||||
if curl -s http://localhost:9333/cluster/status > /dev/null 2>&1; then
|
||||
break
|
||||
fi
|
||||
echo -n "."
|
||||
sleep 1
|
||||
done
|
||||
echo -e " ${GREEN}✓${NC}"
|
||||
|
||||
# Wait for SeaweedFS filer
|
||||
echo -n "Waiting for SeaweedFS filer..."
|
||||
for i in {1..30}; do
|
||||
if curl -s http://localhost:8888 > /dev/null 2>&1; then
|
||||
break
|
||||
fi
|
||||
echo -n "."
|
||||
sleep 1
|
||||
done
|
||||
echo -e " ${GREEN}✓${NC}"
|
||||
|
||||
# Wait for SeaweedFS S3
|
||||
echo -n "Waiting for SeaweedFS S3..."
|
||||
for i in {1..30}; do
|
||||
if curl -s http://localhost:8333 > /dev/null 2>&1; then
|
||||
break
|
||||
fi
|
||||
echo -n "."
|
||||
sleep 1
|
||||
done
|
||||
echo -e " ${GREEN}✓${NC}"
|
||||
|
||||
# Wait a bit more for SeaweedFS to fully initialize
|
||||
sleep 2
|
||||
|
||||
# Create S3 bucket in SeaweedFS if it doesn't exist
|
||||
echo -e "${YELLOW}📦 Creating S3 bucket in SeaweedFS...${NC}"
|
||||
BUCKET_NAME="p1ctos4ve"
|
||||
# Try to create bucket via S3 API (using AWS CLI-like approach)
|
||||
if ! curl -s -X PUT "http://localhost:8333/${BUCKET_NAME}" > /dev/null 2>&1; then
|
||||
# Alternative: create via filer API
|
||||
curl -X PUT "http://localhost:8888/buckets/${BUCKET_NAME}" > /dev/null 2>&1 || true
|
||||
fi
|
||||
echo -e "${GREEN}✓ Bucket ready${NC}"
|
||||
|
||||
# Step 2: Build backend
|
||||
echo -e "${YELLOW}🔨 Step 2: Building backend...${NC}"
|
||||
cd "$PROJECT_ROOT"
|
||||
docker build -t p1ctos4ve-backend:latest -f apps/backend/Dockerfile .
|
||||
|
||||
# Step 3: Run migrations
|
||||
echo -e "${YELLOW}🗄️ Step 3: Running database migrations...${NC}"
|
||||
docker run --rm \
|
||||
--network "${NETWORK_NAME}" \
|
||||
-e DATABASE_URL="postgresql://p1ctos4ve:p1ctos4ve_password@postgres:5432/p1ctos4ve" \
|
||||
-e REDIS_URL="redis://redis:6379" \
|
||||
-e S3_ENDPOINT="http://seaweedfs-s3:8333" \
|
||||
-e S3_REGION="us-east-1" \
|
||||
-e S3_BUCKET="${BUCKET_NAME}" \
|
||||
-e S3_ACCESS_KEY_ID="any" \
|
||||
-e S3_SECRET_ACCESS_KEY="any" \
|
||||
-e S3_FORCE_PATH_STYLE="true" \
|
||||
-e BETTER_AUTH_SECRET="$(openssl rand -hex 32)" \
|
||||
-e BETTER_AUTH_URL="http://localhost:3000" \
|
||||
-e BASE_URL="http://localhost:3000" \
|
||||
-e NODE_ENV="production" \
|
||||
-e PORT="3000" \
|
||||
p1ctos4ve-backend:latest \
|
||||
bun run db:migrate
|
||||
|
||||
# Step 4: Run unit tests
|
||||
echo -e "${YELLOW}🧪 Step 4: Running unit tests...${NC}"
|
||||
docker run --rm \
|
||||
--network "${NETWORK_NAME}" \
|
||||
-e DATABASE_URL="postgresql://p1ctos4ve:p1ctos4ve_password@postgres:5432/p1ctos4ve" \
|
||||
-e REDIS_URL="redis://redis:6379" \
|
||||
-e S3_ENDPOINT="http://seaweedfs-s3:8333" \
|
||||
-e S3_REGION="us-east-1" \
|
||||
-e S3_BUCKET="${BUCKET_NAME}" \
|
||||
-e S3_ACCESS_KEY_ID="any" \
|
||||
-e S3_SECRET_ACCESS_KEY="any" \
|
||||
-e S3_FORCE_PATH_STYLE="true" \
|
||||
-e BETTER_AUTH_SECRET="$(openssl rand -hex 32)" \
|
||||
-e BETTER_AUTH_URL="http://localhost:3000" \
|
||||
-e BASE_URL="http://localhost:3000" \
|
||||
-e NODE_ENV="test" \
|
||||
-e PORT="3000" \
|
||||
p1ctos4ve-backend:latest \
|
||||
bun test src/tests/unit/
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo -e "${GREEN}✓ Unit tests passed${NC}"
|
||||
else
|
||||
echo -e "${RED}✗ Unit tests failed${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Step 5: Run integration tests
|
||||
echo -e "${YELLOW}🔗 Step 5: Running integration tests...${NC}"
|
||||
|
||||
# Start backend server in background for e2e tests
|
||||
echo -e "${YELLOW}Starting backend server for e2e tests...${NC}"
|
||||
BACKEND_CONTAINER=$(docker run -d \
|
||||
--name p1ctos4ve-backend-test \
|
||||
--network "${NETWORK_NAME}" \
|
||||
-p 3000:3000 \
|
||||
-e DATABASE_URL="postgresql://p1ctos4ve:p1ctos4ve_password@postgres:5432/p1ctos4ve" \
|
||||
-e REDIS_URL="redis://redis:6379" \
|
||||
-e S3_ENDPOINT="http://seaweedfs-s3:8333" \
|
||||
-e S3_REGION="us-east-1" \
|
||||
-e S3_BUCKET="${BUCKET_NAME}" \
|
||||
-e S3_ACCESS_KEY_ID="any" \
|
||||
-e S3_SECRET_ACCESS_KEY="any" \
|
||||
-e S3_FORCE_PATH_STYLE="true" \
|
||||
-e BETTER_AUTH_SECRET="$(openssl rand -hex 32)" \
|
||||
-e BETTER_AUTH_URL="http://localhost:3000" \
|
||||
-e BASE_URL="http://localhost:3000" \
|
||||
-e NODE_ENV="test" \
|
||||
-e PORT="3000" \
|
||||
p1ctos4ve-backend:latest)
|
||||
|
||||
# Wait for server to be ready
|
||||
echo -n "Waiting for backend server to start..."
|
||||
for i in {1..30}; do
|
||||
if curl -s http://localhost:3000 > /dev/null 2>&1; then
|
||||
break
|
||||
fi
|
||||
echo -n "."
|
||||
sleep 1
|
||||
done
|
||||
echo -e " ${GREEN}✓${NC}"
|
||||
|
||||
# Run e2e tests in the same container (server runs in background via exec)
|
||||
# This way tests can access localhost:3000
|
||||
docker exec p1ctos4ve-backend-test sh -c "bun test --preload ./src/tests/setup.ts src/tests/e2e/" || \
|
||||
docker run --rm \
|
||||
--network "${NETWORK_NAME}" \
|
||||
-e DATABASE_URL="postgresql://p1ctos4ve:p1ctos4ve_password@postgres:5432/p1ctos4ve" \
|
||||
-e REDIS_URL="redis://redis:6379" \
|
||||
-e S3_ENDPOINT="http://seaweedfs-s3:8333" \
|
||||
-e S3_REGION="us-east-1" \
|
||||
-e S3_BUCKET="${BUCKET_NAME}" \
|
||||
-e S3_ACCESS_KEY_ID="any" \
|
||||
-e S3_SECRET_ACCESS_KEY="any" \
|
||||
-e S3_FORCE_PATH_STYLE="true" \
|
||||
-e BETTER_AUTH_SECRET="$(openssl rand -hex 32)" \
|
||||
-e BETTER_AUTH_URL="http://p1ctos4ve-backend-test:3000" \
|
||||
-e BASE_URL="http://p1ctos4ve-backend-test:3000" \
|
||||
-e NODE_ENV="test" \
|
||||
-e PORT="3000" \
|
||||
p1ctos4ve-backend:latest \
|
||||
sh -c "find src/tests/e2e -name '*.test.ts' -exec sed -i 's|http://localhost:3000|http://p1ctos4ve-backend-test:3000|g' {} \; && bun test --preload ./src/tests/setup.ts src/tests/e2e/"
|
||||
|
||||
TEST_EXIT_CODE=$?
|
||||
|
||||
# Stop and remove backend test container
|
||||
echo -e "${YELLOW}Stopping test backend server...${NC}"
|
||||
docker stop p1ctos4ve-backend-test > /dev/null 2>&1 || true
|
||||
docker rm p1ctos4ve-backend-test > /dev/null 2>&1 || true
|
||||
|
||||
if [ $TEST_EXIT_CODE -eq 0 ]; then
|
||||
echo -e "${GREEN}✓ Integration tests passed${NC}"
|
||||
else
|
||||
echo -e "${RED}✗ Integration tests failed${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Step 6: Start the application
|
||||
echo -e "${YELLOW}🚀 Step 6: Starting the application...${NC}"
|
||||
echo -e "${GREEN}Application will be available at http://localhost:3000${NC}"
|
||||
echo -e "${YELLOW}Press Ctrl+C to stop${NC}"
|
||||
|
||||
docker run --rm \
|
||||
--network "${NETWORK_NAME}" \
|
||||
-p 3000:3000 \
|
||||
-e DATABASE_URL="postgresql://p1ctos4ve:p1ctos4ve_password@postgres:5432/p1ctos4ve" \
|
||||
-e REDIS_URL="redis://redis:6379" \
|
||||
-e S3_ENDPOINT="http://seaweedfs-s3:8333" \
|
||||
-e S3_REGION="us-east-1" \
|
||||
-e S3_BUCKET="${BUCKET_NAME}" \
|
||||
-e S3_ACCESS_KEY_ID="any" \
|
||||
-e S3_SECRET_ACCESS_KEY="any" \
|
||||
-e S3_FORCE_PATH_STYLE="true" \
|
||||
-e BETTER_AUTH_SECRET="$(openssl rand -hex 32)" \
|
||||
-e BETTER_AUTH_URL="http://localhost:3000" \
|
||||
-e BASE_URL="http://localhost:3000" \
|
||||
-e NODE_ENV="production" \
|
||||
-e PORT="3000" \
|
||||
p1ctos4ve-backend:latest
|
||||
|
||||
Reference in New Issue
Block a user