diff --git a/.env.dev.example b/.env.dev.example new file mode 100644 index 0000000..97c45f5 --- /dev/null +++ b/.env.dev.example @@ -0,0 +1,43 @@ +# Local dev environment — copy to .env and adjust as needed +# docker compose -f docker-compose.dev.yml up + +# Server +PORT=3000 +NODE_ENV=development +CORS_ALLOWED_ORIGINS=http://localhost:3000,http://localhost:5173 + +# Auth +API_KEYS=dev-api-key +JWT_SECRET=dev-secret-change-in-production + +# Database (matches docker-compose.dev.yml postgres service) +DATABASE_URL=postgresql://paystream:paystream_dev@postgres:5432/paystream +TESTNET_DATABASE_URL=postgresql://paystream:paystream_dev@postgres:5432/paystream +MAINNET_DATABASE_URL=postgresql://paystream:paystream_dev@postgres:5432/paystream + +# Redis (matches docker-compose.dev.yml redis service) +REDIS_URL=redis://redis:6379 + +# Stellar +STELLAR_NETWORK=testnet +TESTNET_RPC_URL=https://soroban-testnet.stellar.org +TESTNET_STREAM_CONTRACT_ID= +TESTNET_TOKEN_CONTRACT_ID= +MAINNET_RPC_URL=https://mainnet.stellar.validationcloud.io/v1/soroban/rpc +MAINNET_STREAM_CONTRACT_ID= +MAINNET_TOKEN_CONTRACT_ID= + +# AWS Secrets Manager (disabled locally) +USE_AWS_SECRETS_MANAGER=false +AWS_SECRETS_MANAGER_SECRET_NAME=paystream/secrets +AWS_REGION=us-east-1 + +# Rate limiting +RATE_LIMIT_WINDOW_MS=900000 +RATE_LIMIT_MAX_REQUESTS=100 + +# Logging +LOG_LEVEL=info + +# Frontend +VITE_API_URL=http://localhost:3000 diff --git a/api/Dockerfile.dev b/api/Dockerfile.dev new file mode 100644 index 0000000..d798365 --- /dev/null +++ b/api/Dockerfile.dev @@ -0,0 +1,7 @@ +FROM node:20-alpine +WORKDIR /app +COPY package*.json ./ +RUN npm install +COPY . . +EXPOSE 3000 +CMD ["node", "server.js"] diff --git a/demo/Dockerfile.dev b/demo/Dockerfile.dev new file mode 100644 index 0000000..2ee5d44 --- /dev/null +++ b/demo/Dockerfile.dev @@ -0,0 +1,7 @@ +FROM node:20-alpine +WORKDIR /app +COPY package*.json ./ +RUN npm install +COPY . . +EXPOSE 5173 +CMD ["npm", "run", "dev", "--", "--host", "0.0.0.0"] diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml new file mode 100644 index 0000000..65ede8d --- /dev/null +++ b/docker-compose.dev.yml @@ -0,0 +1,105 @@ +services: + postgres: + image: postgres:15-alpine + environment: + POSTGRES_DB: paystream + POSTGRES_USER: paystream + POSTGRES_PASSWORD: paystream_dev + ports: ['5432:5432'] + volumes: [postgres_data:/var/lib/postgresql/data] + healthcheck: + test: ['CMD-SHELL', 'pg_isready -U paystream'] + interval: 10s + timeout: 5s + retries: 5 + + redis: + image: redis:7-alpine + ports: ['6379:6379'] + volumes: [redis_data:/data] + healthcheck: + test: ['CMD', 'redis-cli', 'ping'] + interval: 10s + timeout: 5s + retries: 5 + + api: + build: + context: ./api + dockerfile: Dockerfile.dev + ports: ['3000:3000'] + environment: + NODE_ENV: development + PORT: 3000 + DATABASE_URL: postgresql://paystream:paystream_dev@postgres:5432/paystream + REDIS_URL: redis://redis:6379 + CORS_ALLOWED_ORIGINS: http://localhost:3000,http://localhost:5173 + JWT_SECRET: ${JWT_SECRET:-dev-secret-change-in-production} + API_KEYS: ${API_KEYS:-dev-api-key} + STELLAR_NETWORK: ${STELLAR_NETWORK:-testnet} + TESTNET_RPC_URL: ${TESTNET_RPC_URL:-https://soroban-testnet.stellar.org} + TESTNET_STREAM_CONTRACT_ID: ${TESTNET_STREAM_CONTRACT_ID:-} + TESTNET_TOKEN_CONTRACT_ID: ${TESTNET_TOKEN_CONTRACT_ID:-} + LOG_LEVEL: ${LOG_LEVEL:-info} + RATE_LIMIT_WINDOW_MS: ${RATE_LIMIT_WINDOW_MS:-900000} + RATE_LIMIT_MAX_REQUESTS: ${RATE_LIMIT_MAX_REQUESTS:-100} + USE_AWS_SECRETS_MANAGER: 'false' + depends_on: + postgres: + condition: service_healthy + redis: + condition: service_healthy + volumes: ['./api:/app', '/app/node_modules'] + healthcheck: + test: ['CMD-SHELL', 'curl -f http://localhost:3000/health || exit 1'] + interval: 30s + timeout: 10s + retries: 3 + + frontend: + build: + context: ./demo + dockerfile: Dockerfile.dev + ports: ['5173:5173'] + environment: + VITE_API_URL: http://localhost:3000 + depends_on: [api] + volumes: ['./demo:/app', '/app/node_modules'] + + indexer: + build: + context: ./services/indexer + dockerfile: Dockerfile.dev + environment: + NODE_ENV: development + DATABASE_URL: postgresql://paystream:paystream_dev@postgres:5432/paystream + REDIS_URL: redis://redis:6379 + STELLAR_NETWORK: ${STELLAR_NETWORK:-testnet} + TESTNET_RPC_URL: ${TESTNET_RPC_URL:-https://soroban-testnet.stellar.org} + TESTNET_STREAM_CONTRACT_ID: ${TESTNET_STREAM_CONTRACT_ID:-} + depends_on: + postgres: + condition: service_healthy + redis: + condition: service_healthy + volumes: ['./services/indexer:/app', '/app/node_modules'] + + notification: + build: + context: ./services/notification + dockerfile: Dockerfile.dev + environment: + NODE_ENV: development + REDIS_URL: redis://redis:6379 + depends_on: + redis: + condition: service_healthy + volumes: ['./services/notification:/app', '/app/node_modules'] + +volumes: + postgres_data: + redis_data: + +networks: + default: + name: paystream_dev diff --git a/services/indexer/Dockerfile.dev b/services/indexer/Dockerfile.dev new file mode 100644 index 0000000..9b0428b --- /dev/null +++ b/services/indexer/Dockerfile.dev @@ -0,0 +1,6 @@ +FROM node:20-alpine +WORKDIR /app +COPY package*.json ./ +RUN npm install +COPY . . +CMD ["node", "src/index.js"] diff --git a/services/notification/Dockerfile.dev b/services/notification/Dockerfile.dev new file mode 100644 index 0000000..9b0428b --- /dev/null +++ b/services/notification/Dockerfile.dev @@ -0,0 +1,6 @@ +FROM node:20-alpine +WORKDIR /app +COPY package*.json ./ +RUN npm install +COPY . . +CMD ["node", "src/index.js"]