From f6c0e892905c4e6176ce3ec6c19a4070e09934af Mon Sep 17 00:00:00 2001 From: dimitar Date: Mon, 31 Mar 2025 06:27:21 +0200 Subject: [PATCH] production --- .env | 14 ---- _docker-compose.yml | 131 ++++++++++++++++------------------- backend/.env | 4 +- backend/Dockerfile | 49 ++++++++----- backend/_Dockerfile | 42 +++++++++++ backend/src/main.ts | 2 + docker-compose.yml | 83 +++++++++------------- frontend/src/services/api.js | 6 +- 8 files changed, 175 insertions(+), 156 deletions(-) create mode 100644 backend/_Dockerfile diff --git a/.env b/.env index ff2c520..2b5fddd 100644 --- a/.env +++ b/.env @@ -1,8 +1,3 @@ -# Environment variables declared in this file are automatically made available to Prisma. -# See the documentation for more detail: https://pris.ly/d/prisma-schema#accessing-environment-variables-from-the-schema - -# Prisma supports the native connection string format for PostgreSQL, MySQL, SQLite, SQL Server, MongoDB and CockroachDB. -# See the documentation for all the connection string options: https://pris.ly/d/connection-strings POSTGRES_USER=root POSTGRES_PASSWORD=irina76 POSTGRES_DB=imk_db @@ -15,24 +10,15 @@ AWS_SECRET_ACCESS_KEY=6d4723e14c0d799b89948c24dbe983e4 AWS_S3_BUCKET_NAME=imk-data AWS_ENDPOINT_URL=https://eu2.contabostorage.com -#Email Configuration -# SMTP_HOST=smtp.gmail.com -# SMTP_PORT=587 -# SMTP_USER=taratur@gmail.com -# SMTP_PASS=dziy nccc svgg bovb -# EMAIL_FROM=taratur@gmail.com - SMTP_HOST=imk.mk SMTP_PORT=465 SMTP_USER=mailer@imk.mk SMTP_PASS=76Avtostoperski76 SMTP_FROM=mailer@imk.mk -# FRONTEND_URL=https://imk.mk EMAIL_FROM=mailer@yandex.com ADMIN_EMAIL=taratur@gmail.com -# default app ADMIN DEFAULT_ADMIN_EMAIL=taratur@gmail.com DEFAULT_ADMIN_PASSWORD=irina7654321 DEFAULT_ADMIN_NAME=admin diff --git a/_docker-compose.yml b/_docker-compose.yml index 583e283..0555ce8 100644 --- a/_docker-compose.yml +++ b/_docker-compose.yml @@ -1,108 +1,97 @@ version: "3.8" services: - postgres: - image: postgres:15-alpine - container_name: imk-postgres - environment: - POSTGRES_USER: postgres - POSTGRES_PASSWORD: postgres - POSTGRES_DB: imk_db - volumes: - - postgres_data:/var/lib/postgresql/data - ports: - - "5432:5432" - networks: - - imk_copy_imk_network - healthcheck: - test: ["CMD-SHELL", "pg_isready -U postgres"] - interval: 10s - timeout: 5s - retries: 5 - backend: + logging: + driver: "json-file" + options: + max-size: "10m" + max-file: "3" + container_name: imk-backend build: context: ./backend dockerfile: Dockerfile - container_name: imk-backend - # environment: - # - NODE_ENV=development - # - DATABASE_URL=postgresql://postgres:postgres@postgres:5432/imk_db - # - AWS_ACCESS_KEY_ID=4d2f5655369a02100375e3247d7e1fe6 - # - AWS_ENDPOINT_URL=https://eu2.contabostorage.com - # - AWS_REGION=EU2 - # - AWS_S3_BUCKET_NAME=imk-data - # - AWS_SECRET_ACCESS_KEY=6d4723e14c0d799b89948c24dbe983e4 - # - DEFAULT_ADMIN_EMAIL=taratur@gmail.com - # - DEFAULT_ADMIN_NAME=admin - # - DEFAULT_ADMIN_PASSWORD=irina7654321 - # - EMAIL_FROM=mailer@yandex.com - # - JWT_SECRET=some-secret - # - PORT=3000 - # - SMTP_HOST=imk.mk - # - SMTP_PASS=76Avtostoperski76 - # - SMTP_PORT=465 - # - SMTP_USER=mailer@imk.mk - # ports: - # - "3000:3000" - # depends_on: - # postgres: - # condition: service_healthy ports: - "3000:3000" environment: - NODE_ENV=production - # - PORT=3000 - - DATABASE_URL=postgresql://postgres:postgres@imk-postgres:5432/postgres?schema=public - - AWS_ACCESS_KEY_ID=4d2f5655369a02100375e3247d7e1fe6 - - AWS_ENDPOINT_URL=https://eu2.contabostorage.com - - AWS_REGION=EU2 - - AWS_S3_BUCKET_NAME=imk-data - - AWS_SECRET_ACCESS_KEY=6d4723e14c0d799b89948c24dbe983e4 - - DEFAULT_ADMIN_EMAIL=taratur@gmail.com - - DEFAULT_ADMIN_NAME=admin - - DEFAULT_ADMIN_PASSWORD=irina7654321 - - EMAIL_FROM=mailer@yandex.com - - JWT_SECRET=some-secret - PORT=3000 - - SMTP_HOST=imk.mk - - SMTP_PASS=76Avtostoperski76 - - SMTP_PORT=465 - - SMTP_USER=mailer@imk.mk - # env_file: - # - .env + - DATABASE_URL=postgresql://postgres:postgres@imk-postgres:5432/postgres?schema=public + - FRONTEND_URL=https://www.placebo.mk + env_file: + - .env + deploy: + resources: + limits: + memory: 2G + reservations: + memory: 512M depends_on: postgres: condition: service_healthy redis: condition: service_started + networks: + - app_network healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:3000/health"] + test: + [ + "CMD", + "wget", + "-q", + "--spider", + "http://localhost:3000/health || exit 1", + ] interval: 30s timeout: 10s retries: 3 start_period: 15s - networks: - - imk_copy_imk_network + restart: always + postgres: + container_name: imk-postgres + image: postgres:14-alpine + environment: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: postgres + PGDATA: /var/lib/postgresql/data/pgdata + ports: + - "5432:5432" volumes: - - ./backend:/usr/src/app - - /usr/src/app/node_modules - command: sh -c "npm run prisma:generate && npm run prisma:migrate:deploy && npm run start:dev" + - postgres_data:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U postgres"] + interval: 10s + timeout: 5s + retries: 5 + networks: + - app_network + restart: always redis: - image: redis:alpine container_name: imk-redis + image: redis:alpine + command: redis-server --appendonly yes ports: - "6379:6379" - networks: - - imk_copy_imk_network volumes: - redis_data:/data + networks: + - app_network + healthcheck: + test: ["CMD", "redis-cli", "ping"] + interval: 10s + timeout: 5s + retries: 3 + restart: always networks: - imk_copy_imk_network: + app_network: driver: bridge + name: app_network volumes: postgres_data: + name: imk_postgres_data redis_data: + name: imk_redis_data diff --git a/backend/.env b/backend/.env index b9f5661..4b3b433 100644 --- a/backend/.env +++ b/backend/.env @@ -37,5 +37,5 @@ DEFAULT_ADMIN_EMAIL=taratur@gmail.com DEFAULT_ADMIN_PASSWORD=irina7654321 DEFAULT_ADMIN_NAME=admin -CORS_ORIGIN=http://localhost:5173 -NODE_ENV=development +# CORS_ORIGIN=http://localhost:5173 +# NODE_ENV=development diff --git a/backend/Dockerfile b/backend/Dockerfile index 68223f1..f055f1a 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -1,23 +1,43 @@ +# backend/Dockerfile +FROM node:18-alpine -FROM node:18.19.1-alpine3.18 +# Add build arguments +ARG NODE_ENV +ARG API_URL +ARG CORS_ORIGIN +ARG DATABASE_URL +ARG JWT_SECRET +ARG SMTP_HOST +ARG SMTP_PORT +ARG SMTP_USER +ARG SMTP_PASS +ARG EMAIL_FROM + +# Set environment variables from build args +ENV NODE_ENV=${NODE_ENV} +ENV API_URL=${API_URL} +ENV CORS_ORIGIN=${CORS_ORIGIN} +ENV DATABASE_URL=${DATABASE_URL} +ENV JWT_SECRET=${JWT_SECRET} +ENV SMTP_HOST=${SMTP_HOST} +ENV SMTP_PORT=${SMTP_PORT} +ENV SMTP_USER=${SMTP_USER} +ENV SMTP_PASS=${SMTP_PASS} +ENV EMAIL_FROM=${EMAIL_FROM} WORKDIR /usr/src/app -# Install necessary tools and dependencies -RUN apk add --no-cache \ - curl \ - wget \ - python3 \ - make \ - g++ \ - && rm -rf /var/cache/apk/* +# Install necessary tools +RUN apk add --no-cache curl wget # Copy package files COPY package*.json ./ -COPY prisma ./prisma/ # Install dependencies -# RUN npm ci --only=production +RUN npm install + +# Copy prisma schema +COPY prisma ./prisma/ # Generate Prisma client RUN npx prisma generate @@ -35,8 +55,5 @@ EXPOSE 3000 HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ CMD wget -q --spider http://localhost:3000/health || exit 1 -# Set Node options -ENV NODE_OPTIONS="--max-old-space-size=2048" - -# Start the application directly with node -CMD ["node", "dist/main.js"] +# Start the application +CMD ["npm", "run", "start:prod"] diff --git a/backend/_Dockerfile b/backend/_Dockerfile new file mode 100644 index 0000000..68223f1 --- /dev/null +++ b/backend/_Dockerfile @@ -0,0 +1,42 @@ + +FROM node:18.19.1-alpine3.18 + +WORKDIR /usr/src/app + +# Install necessary tools and dependencies +RUN apk add --no-cache \ + curl \ + wget \ + python3 \ + make \ + g++ \ + && rm -rf /var/cache/apk/* + +# Copy package files +COPY package*.json ./ +COPY prisma ./prisma/ + +# Install dependencies +# RUN npm ci --only=production + +# Generate Prisma client +RUN npx prisma generate + +# Copy source code +COPY . . + +# Build the application +RUN npm run build + +# Expose port +EXPOSE 3000 + +# Add healthcheck +HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ + CMD wget -q --spider http://localhost:3000/health || exit 1 + +# Set Node options +ENV NODE_OPTIONS="--max-old-space-size=2048" + +# Start the application directly with node +CMD ["node", "dist/main.js"] diff --git a/backend/src/main.ts b/backend/src/main.ts index 583d885..9ec3a1e 100644 --- a/backend/src/main.ts +++ b/backend/src/main.ts @@ -27,6 +27,8 @@ async function bootstrap() { "Content-Type", "Accept", "Authorization", + "Access-Control-Allow-Origin", + "Access-Control-Allow-Credentials", ], exposedHeaders: [ 'Access-Control-Allow-Origin', diff --git a/docker-compose.yml b/docker-compose.yml index 0555ce8..6a08295 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,96 +2,79 @@ version: "3.8" services: backend: - logging: - driver: "json-file" - options: - max-size: "10m" - max-file: "3" container_name: imk-backend build: context: ./backend dockerfile: Dockerfile + args: + - NODE_ENV=${NODE_ENV} + - API_URL=${API_URL} + - CORS_ORIGIN=${CORS_ORIGIN} + - DATABASE_URL=${DATABASE_URL} + - JWT_SECRET=${JWT_SECRET} + - SMTP_HOST=${SMTP_HOST} + - SMTP_PORT=${SMTP_PORT} + - SMTP_USER=${SMTP_USER} + - SMTP_PASS=${SMTP_PASS} + - EMAIL_FROM=${EMAIL_FROM} ports: - "3000:3000" environment: - - NODE_ENV=production - - PORT=3000 - - DATABASE_URL=postgresql://postgres:postgres@imk-postgres:5432/postgres?schema=public - - FRONTEND_URL=https://www.placebo.mk - env_file: - - .env - deploy: - resources: - limits: - memory: 2G - reservations: - memory: 512M + - NODE_ENV=${NODE_ENV} + - API_URL=${API_URL} + - CORS_ORIGIN=${CORS_ORIGIN} + - DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB} + - JWT_SECRET=${JWT_SECRET} + - SMTP_HOST=${SMTP_HOST} + - SMTP_PORT=${SMTP_PORT} + - SMTP_USER=${SMTP_USER} + - SMTP_PASS=${SMTP_PASS} + - EMAIL_FROM=${EMAIL_FROM} depends_on: postgres: condition: service_healthy redis: - condition: service_started + condition: service_healthy networks: - app_network - healthcheck: - test: - [ - "CMD", - "wget", - "-q", - "--spider", - "http://localhost:3000/health || exit 1", - ] - interval: 30s - timeout: 10s - retries: 3 - start_period: 15s - restart: always + postgres: container_name: imk-postgres image: postgres:14-alpine environment: - POSTGRES_USER: postgres - POSTGRES_PASSWORD: postgres - POSTGRES_DB: postgres - PGDATA: /var/lib/postgresql/data/pgdata - ports: - - "5432:5432" + - POSTGRES_USER=${POSTGRES_USER} + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} + - POSTGRES_DB=${POSTGRES_DB} volumes: - postgres_data:/var/lib/postgresql/data + networks: + - app_network healthcheck: - test: ["CMD-SHELL", "pg_isready -U postgres"] + test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"] interval: 10s timeout: 5s retries: 5 - networks: - - app_network - restart: always redis: container_name: imk-redis image: redis:alpine - command: redis-server --appendonly yes - ports: - - "6379:6379" + command: redis-server --requirepass ${REDIS_PASSWORD} + environment: + - REDIS_PASSWORD=${REDIS_PASSWORD} volumes: - redis_data:/data networks: - app_network healthcheck: - test: ["CMD", "redis-cli", "ping"] + test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD}", "ping"] interval: 10s timeout: 5s retries: 3 - restart: always networks: app_network: driver: bridge - name: app_network volumes: postgres_data: - name: imk_postgres_data redis_data: - name: imk_redis_data diff --git a/frontend/src/services/api.js b/frontend/src/services/api.js index a4fd3d4..4c12752 100644 --- a/frontend/src/services/api.js +++ b/frontend/src/services/api.js @@ -1,9 +1,9 @@ import axios from "axios"; const API_URL = - process.env.NODE_ENV === "production" - ? "https://imkapi.oblak.solutions" - : "http://localhost:3000"; + // process.env.NODE_ENV === "production" + "https://imkapi.oblak.solutions"; +// : "http://localhost:3000"; const api = axios.create({ baseURL: API_URL,