diff --git a/.dockerignore b/.dockerignore index 321d874..a04823d 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,4 +1,16 @@ node_modules +npm-debug.log* +coverage +dist +.git +.github +.env +.env.local +.env.*.local +test +docker-compose*.yml +*.log +.DS_Store npm-debug.log coverage .git @@ -8,4 +20,4 @@ README.md .env .env.local docker-compose.override.yml -.dockerignore \ No newline at end of file +.dockerignore diff --git a/.env.example b/.env.example index d8ad42b..e8a9eb2 100644 --- a/.env.example +++ b/.env.example @@ -19,6 +19,10 @@ PORT=3000 # REDIS_URL: URL. Required in production. Development/test default: redis://localhost:6379. REDIS_URL=redis://localhost:6379 +# PostgreSQL (used by the Docker local stack and future persistence features) +DATABASE_URL=postgres://smartdrop:smartdrop@localhost:5432/smartdrop + +# Stellar Horizon # DATABASE_URL: URL. Required in production. Development default: postgres://localhost/smartdrop. Test default: postgres://localhost/smartdrop_test. DATABASE_URL=postgres://localhost/smartdrop diff --git a/.gitignore b/.gitignore index 35bd2d0..dfd5103 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ node_modules/ .env .env.local .env.*.local +docker-compose.override.yml dist/ *.log .DS_Store diff --git a/Dockerfile b/Dockerfile index 9ff0706..a3423f7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,3 +1,7 @@ +FROM node:20-alpine AS builder + +WORKDIR /app +ENV NODE_ENV=production # --- Base & Development Stage --- FROM node:20-alpine AS development WORKDIR /app @@ -19,6 +23,8 @@ WORKDIR /app COPY package*.json ./ RUN npm ci --omit=dev +FROM node:20-alpine AS production + COPY src ./src # --- Production Stage --- @@ -27,8 +33,15 @@ WORKDIR /app ENV NODE_ENV=production COPY --from=builder /app/node_modules ./node_modules +COPY package*.json ./ +COPY src ./src + +USER node +EXPOSE 3000 + +CMD ["npm", "start"] COPY --from=builder /app/src ./src COPY package*.json ./ EXPOSE 4000 -CMD ["node", "src/index.js"] \ No newline at end of file +CMD ["node", "src/index.js"] diff --git a/README.md b/README.md index 4e69aa5..c5c0d8b 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,31 @@ Registers subscriber endpoints for SmartDrop lifecycle events and delivers signe You can spin up the entire local development stack—including the API, PostgreSQL database, and Redis instance—using a single command. +### Quick Start With Docker + +Run the local API, Redis, and Postgres stack with Docker Compose: + +```bash +docker compose up --build +``` + +The API listens on port `4000` in the compose environment: + +```bash +curl http://localhost:4000/health +``` + +The compose stack mounts `./src` into the API container and runs +`npm run dev`, so source changes restart the Node process automatically. Redis +and Postgres include health checks, and `docker-compose.override.yml` is ignored +for local-only secrets or service tweaks. + +To remove containers and the local Postgres volume: + +```bash +docker compose down -v +``` + ### Prerequisites * Ensure you have [Docker and Docker Compose](https://docs.docker.com/get-docker/) installed. diff --git a/docker-compose.yml b/docker-compose.yml index 96d3886..72e3694 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,5 +1,24 @@ services: api: + build: . + command: npm run dev + environment: + NODE_ENV: development + PORT: 4000 + REDIS_HOST: redis + REDIS_PORT: 6379 + REDIS_PASSWORD: '' + DATABASE_URL: postgres://smartdrop:smartdrop@postgres:5432/smartdrop + STELLAR_HORIZON_URL: https://horizon.stellar.org + USDC_ISSUER: GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335AX2OBFLDTQLNUEHRGPTM6RIA + PRICE_CACHE_TTL: 60 + PRICE_REFRESH_INTERVAL: 30 + PRICE_STALE_THRESHOLD: 5 + PRICE_ANOMALY_THRESHOLD: 10 + LOG_LEVEL: info + CORS_ALLOWED_ORIGINS: http://localhost:3000,http://localhost:3001,http://localhost:4000 + ports: + - '4000:4000' build: context: . target: development @@ -17,11 +36,18 @@ services: postgres: condition: service_healthy volumes: + - ./src:/app/src - ./src:/app/src # Hot reload en desarrollo redis: image: redis:7-alpine ports: + - '6379:6379' + healthcheck: + test: ['CMD', 'redis-cli', 'ping'] + interval: 5s + timeout: 3s + retries: 12 - "6379:6379" healthcheck: test: ["CMD", "redis-cli", "ping"] @@ -36,9 +62,20 @@ services: POSTGRES_PASSWORD: smartdrop POSTGRES_DB: smartdrop ports: + - '5432:5432' + healthcheck: + test: ['CMD-SHELL', 'pg_isready -U smartdrop -d smartdrop'] + interval: 5s + timeout: 3s + retries: 12 + volumes: + - postgres-data:/var/lib/postgresql/data + +volumes: + postgres-data: - "5432:5432" healthcheck: test: ["CMD", "pg_isready", "-U", "smartdrop"] interval: 5s timeout: 3s - retries: 5 \ No newline at end of file + retries: 5