diff --git a/.env.example b/.env.example index e6ff17d..bcd305c 100644 --- a/.env.example +++ b/.env.example @@ -16,6 +16,9 @@ FRONTEND_PORT=5173 NODE_ENV=development +CLEARNET_DOMAIN=localhost +ONION_HOSTNAME=samplexxxxxxxxx.onion + CORS_ORIGINS=http://localhost:5173,http://127.0.0.1:5173 ALTCHA_ENABLED=true @@ -35,7 +38,7 @@ VALIDATION_UPLOAD_JSON_BODY_PADDING_BYTES=2097152 # 2MiB VITE_API_BASE_URL=http://localhost:3000/api VITE_CLEARNET_SCHEME=http VITE_CLEARNET_DOMAIN=localhost:5173 -VITE_ONION_HOSTNAME=abcdefghijklmnop.onion +VITE_ONION_HOSTNAME=samplexxxxxxxxx.onion VITE_ALTCHA_ENABLED=true VITE_ALTCHA_MAX_NUMBER=250000 VITE_UPLOAD_MAX_QUEUE_SIZE=10 diff --git a/backend/Dockerfile.prod b/backend/Dockerfile.prod new file mode 100644 index 0000000..1f8cf45 --- /dev/null +++ b/backend/Dockerfile.prod @@ -0,0 +1,15 @@ +FROM node:22.23.4-alpine + +WORKDIR /backend + +RUN apk add --no-cache curl + +COPY package*.json . + +RUN npm ci + +COPY . . + +RUN npm run build + +CMD ["node", "dist/main"] diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml new file mode 100644 index 0000000..c42e985 --- /dev/null +++ b/docker-compose.prod.yml @@ -0,0 +1,95 @@ +services: + postgres: + image: postgres:16 + container_name: ${COMPOSE_PROJECT_NAME}_postgres + restart: unless-stopped + environment: + POSTGRES_DB: ${POSTGRES_DB} + POSTGRES_USER: ${POSTGRES_USER} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + volumes: + - private_image.postgres.prod.data:/var/lib/postgresql/data + healthcheck: + test: ['CMD-SHELL', 'pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}'] + interval: 5s + timeout: 5s + retries: 10 + + pgadmin: + image: dpage/pgadmin4:8 + container_name: ${COMPOSE_PROJECT_NAME}_pgadmin + restart: unless-stopped + environment: + PGADMIN_DEFAULT_EMAIL: ${PGADMIN_DEFAULT_EMAIL} + PGADMIN_DEFAULT_PASSWORD: ${PGADMIN_DEFAULT_PASSWORD} + volumes: + - private_image.pgadmin.prod.data:/var/lib/pgadmin + depends_on: + postgres: + condition: service_healthy + + backend: + build: + context: ./backend + dockerfile: Dockerfile.prod + container_name: ${COMPOSE_PROJECT_NAME}_backend + restart: unless-stopped + depends_on: + postgres: + condition: service_healthy + env_file: + - .env.prod + volumes: + - ./backend/uploads:/backend/uploads + healthcheck: + test: ['CMD-SHELL', 'curl -f http://backend:${BACKEND_PORT}/api/health-check/'] + interval: 10s + timeout: 30s + retries: 10 + start_period: 30s + + nginx: + build: + context: . + dockerfile: nginx/Dockerfile.prod + args: + VITE_API_BASE_URL: ${VITE_API_BASE_URL} + VITE_CLEARNET_SCHEME: ${VITE_CLEARNET_SCHEME} + VITE_CLEARNET_DOMAIN: ${VITE_CLEARNET_DOMAIN} + VITE_ONION_HOSTNAME: ${VITE_ONION_HOSTNAME} + VITE_ALTCHA_ENABLED: ${VITE_ALTCHA_ENABLED} + VITE_ALTCHA_MAX_NUMBER: ${VITE_ALTCHA_MAX_NUMBER} + VITE_UPLOAD_MAX_QUEUE_SIZE: ${VITE_UPLOAD_MAX_QUEUE_SIZE} + VITE_VALIDATION_UPLOAD_MAX_VIEWS_MAX: ${VITE_VALIDATION_UPLOAD_MAX_VIEWS_MAX} + VITE_VALIDATION_UPLOAD_MAX_IMAGE_BYTES: ${VITE_VALIDATION_UPLOAD_MAX_IMAGE_BYTES} + container_name: ${COMPOSE_PROJECT_NAME}_nginx + restart: unless-stopped + env_file: + - .env.prod + ports: + - '80:80' + - '443:443' + volumes: + - ./deploy/certs:/etc/nginx/certs:ro + - ./deploy/certbot/www:/var/www/certbot:ro + depends_on: + backend: + condition: service_healthy + pgadmin: + condition: service_started + + tor: + build: + context: ./deploy/tor + container_name: ${COMPOSE_PROJECT_NAME}_tor + restart: unless-stopped + volumes: + - private_image.tor.prod.data:/var/lib/tor + depends_on: + nginx: + condition: service_started + +volumes: + private_image.postgres.prod.data: + private_image.pgadmin.prod.data: + private_image.tor.prod.data: