add docker

This commit is contained in:
abakumov-a-a committed 2025-12-11 21:47:42 +03:00
1 parent 1fefe5a809
commit d6ea4314b0
10 files changed
+741 -6

No files matched your search

+21
View File
@@ -0,0 +1,21 @@
node_modules
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.git
.gitignore
.env
.env.local
.env.*.local
.DS_Store
*.log
coverage
.vscode
.idea
client
tests
*.md
.eslintrc.json
eslint.config.js
logs
*.test.js
+158
View File
@@ -0,0 +1,158 @@
# Docker Setup для Shop Platform
## Быстрый старт
### 1. Использование готовых образов из registry (рекомендуется для production)
```bash
# Копируем пример файла с переменными окружения
cp .env.example .env
# Редактируем .env файл и укажите образы из registry:
# FRONTEND_IMAGE=your-registry.com/shop-platform-frontend:latest
# BACKEND_IMAGE=your-registry.com/shop-platform-backend:latest
# POSTGRES_IMAGE=postgres:15-alpine
# MINIO_IMAGE=minio/minio:latest
# Особенно важно изменить JWT_SECRET для продакшена!
# Если registry требует аутентификацию, выполните:
# docker login your-registry.com
# Запускаем все сервисы (образы будут скачаны из registry)
docker-compose up -d
# Просмотр логов
docker-compose logs -f backend
```
### 2. Локальная сборка образов
```bash
# Собираем образы локально
docker-compose -f docker-compose.build.yml build
# Помечаем образы для registry (опционально)
docker tag shop-platform-frontend:latest your-registry/shop-platform-frontend:latest
docker tag shop-platform-backend:latest your-registry/shop-platform-backend:latest
# Отправляем в registry (опционально)
docker push your-registry/shop-platform-frontend:latest
docker push your-registry/shop-platform-backend:latest
# Затем используйте docker-compose.yml с указанием образов в .env
```
### 3. Только бэкенд (если PostgreSQL и MinIO уже запущены)
```bash
# Сборка образа
docker build -t shop-platform-backend .
# Запуск контейнера
docker run -d \
--name shop-platform-backend \
-p 80:80 -p 443:443 \
-e POSTGRES_HOST=your-postgres-host \
-e POSTGRES_PASSWORD=your-password \
-e MINIO_ENDPOINT=your-minio-host \
-e JWT_SECRET=your-secret-key \
-v ./tsl:/app/tsl:ro \
shop-platform-backend
```
## Переменные окружения
Все переменные окружения описаны в файле `.env.example`. Основные:
### Backend:
- **POSTGRES_*** - настройки подключения к PostgreSQL
- **MINIO_*** - настройки подключения к MinIO
- **WEB_*** - настройки веб-сервера (порты, TLS)
- **TSL_*** - настройки SSL/TLS сертификатов
- **JWT_SECRET** - секретный ключ для JWT (ОБЯЗАТЕЛЬНО измените!)
### Frontend:
- **FRONTEND_IMAGE** - имя образа фронтенда из registry (по умолчанию: `shop-platform-frontend:latest`)
- **VITE_API_URL** - URL бэкенда для клиентского приложения (по умолчанию: `/api/v1` - относительный путь, проксируется через nginx)
- **BACKEND_URL** - URL бэкенда для nginx proxy (по умолчанию: `http://backend:443`)
- **BACKEND_SSL_VERIFY** - настройка SSL проверки для бэкенда (по умолчанию: `# proxy_ssl_verify off;` - проверка отключена)
- **FRONTEND_PORT** - порт для фронтенда (по умолчанию: `3000`)
### Образы из registry:
- **FRONTEND_IMAGE** - образ фронтенда (например: `registry.example.com/shop-platform-frontend:v1.0.0`)
- **BACKEND_IMAGE** - образ бэкенда (например: `registry.example.com/shop-platform-backend:v1.0.0`)
- **POSTGRES_IMAGE** - образ PostgreSQL (по умолчанию: `postgres:15-alpine`)
- **MINIO_IMAGE** - образ MinIO (по умолчанию: `minio/minio:latest`)
## Структура сервисов
Docker Compose включает:
1. **frontend** - React приложение (Vite + Nginx)
2. **backend** - основное приложение на Fastify
3. **postgres** - база данных PostgreSQL
4. **minio** - объектное хранилище для изображений
## Сертификаты TLS
Если вы используете HTTPS (WEB_TSL=true), поместите сертификаты в папку `tsl/`:
- `tsl/key.pem` - приватный ключ
- `tsl/cert.pem` - сертификат
Если сертификатов нет, приложение автоматически создаст самоподписанные сертификаты при первом запуске.
## Healthcheck
Приложение имеет встроенный healthcheck endpoint:
- HTTP: `http://localhost:80/health`
- HTTPS: `https://localhost:443/health`
## Логи
Логи сохраняются в папку `logs/` (если FILE_LOG_LEVEL задан) или выводятся в stdout.
## Миграции базы данных
SQL скрипты из папки `sql/` автоматически выполняются при первом запуске PostgreSQL контейнера (благодаря монтированию в `/docker-entrypoint-initdb.d`).
## Полезные команды
```bash
# Остановить все сервисы
docker-compose down
# Остановить и удалить volumes (ОСТОРОЖНО: удалит данные!)
docker-compose down -v
# Пересобрать образы локально (используя docker-compose.build.yml)
docker-compose -f docker-compose.build.yml build --no-cache
# Отправить образы в registry (после сборки)
docker tag shop-platform-frontend:latest ${REGISTRY_URL}/shop-platform-frontend:latest
docker tag shop-platform-backend:latest ${REGISTRY_URL}/shop-platform-backend:latest
docker push ${REGISTRY_URL}/shop-platform-frontend:latest
docker push ${REGISTRY_URL}/shop-platform-backend:latest
# Просмотр логов конкретного сервиса
docker-compose logs -f frontend
docker-compose logs -f backend
docker-compose logs -f postgres
docker-compose logs -f minio
# Выполнить команду в контейнере
docker-compose exec backend sh
# Проверить статус
docker-compose ps
```
## Production рекомендации
1. **Измените JWT_SECRET** на сложный случайный ключ
2. **Используйте сильные пароли** для PostgreSQL и MinIO
3. **Настройте правильные TLS сертификаты** (не самоподписанные)
4. **Используйте secrets** для хранения паролей (Docker Secrets или внешний менеджер)
5. **Настройте резервное копирование** для PostgreSQL
6. **Ограничьте доступ** к портам через firewall
7. **Используйте reverse proxy** (nginx) перед приложением
+54
View File
@@ -0,0 +1,54 @@
# Multi-stage build для бэкенда
# Stage 1: Сборка зависимостей
FROM node:18-alpine AS dependencies
WORKDIR /app
# Копируем файлы зависимостей
COPY package*.json ./
# Устанавливаем зависимости
RUN npm ci --only=production && npm cache clean --force
# Stage 2: Production образ
FROM node:18-alpine
# Устанавливаем wget для healthcheck
RUN apk add --no-cache wget
WORKDIR /app
# Создаем пользователя для запуска приложения (безопасность)
RUN addgroup -g 1001 -S nodejs && \
adduser -S nodejs -u 1001
# Копируем зависимости из stage dependencies
COPY --from=dependencies --chown=nodejs:nodejs /app/node_modules ./node_modules
# Копируем исходный код
COPY --chown=nodejs:nodejs . .
# Создаем директории для логов и сертификатов
RUN mkdir -p logs tsl && \
chown -R nodejs:nodejs logs tsl
# Переключаемся на пользователя nodejs
USER nodejs
# Открываем порты (HTTP и HTTPS)
# Порты можно настроить через переменные окружения WEB_HTTP_PORT и WEB_HTTPS_PORT
EXPOSE 80 443
# Переменные окружения по умолчанию
# Все переменные можно переопределить через docker-compose или docker run
ENV NODE_ENV=production \
LOG_LEVEL=info \
STDOUT_LOG_LEVEL=info
# Healthcheck для проверки работоспособности
# Используем wget или curl (должны быть установлены в alpine)
HEALTHCHECK --interval=30s --timeout=3s --start-period=40s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost:80/health || exit 1
# Запускаем приложение
CMD ["node", "app.js"]
+21 -6
View File
@@ -1,7 +1,6 @@
import { YmlParser } from "./src/utils/yml-parser.js";
import daoPlugin from './src/plugins/dao.js';
import pino from "pino";
import pretty from 'pino-pretty';
import autoload from '@fastify/autoload';
import fastifySwagger from "@fastify/swagger";
import fastifySwaggerUi from "@fastify/swagger-ui";
@@ -22,20 +21,36 @@ import minioPlugin from "./src/plugins/minio.js";
(async () => {
let streams;
// Используем pino-pretty только в development режиме
const isDevelopment = process.env.NODE_ENV !== 'production';
let prettyStream = process.stdout;
if (isDevelopment) {
try {
const pretty = (await import('pino-pretty')).default;
prettyStream = pretty({ colorize: true });
} catch (err) {
// Если pino-pretty не установлен, используем обычный stdout
console.warn('pino-pretty не найден, используется обычный вывод логов');
}
}
if (process.env.FILE_LOG_LEVEL !== undefined) {
const logFileStream = fs.createWriteStream(`./logs/event-log.log`, { flags: 'a' });
logFileStream.on('error', (err) => {
console.error('Ошибка при создании потока для файла логов:', err);
});
streams = [
{ level: process.env.FILE_LOG_LEVEL || 'debug', stream: logFileStream },
{ level: process.env.STDOUT_LOG_LEVEL || 'trace', stream: pretty({ colorize: true }) }
{ level: process.env.STDOUT_LOG_LEVEL || 'trace', stream: prettyStream }
];
}
else {
streams = [
{ level: process.env.STDOUT_LOG_LEVEL || 'trace', stream: prettyStream }
];
}
else streams = [
{ level: process.env.STDOUT_LOG_LEVEL || 'trace', stream: pretty({ colorize: true }) }
];
const logger = pino(
{ level: process.env.LOG_LEVEL || 'info' },
+16
View File
@@ -0,0 +1,16 @@
node_modules
dist
.git
.gitignore
.env
.env.local
.env.*.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.DS_Store
*.log
coverage
.vscode
.idea
README.md
+50
View File
@@ -0,0 +1,50 @@
# Multi-stage build для фронтенда
# Stage 1: Сборка приложения
FROM node:18-alpine AS builder
WORKDIR /app
# Копируем файлы зависимостей
COPY package*.json ./
# Устанавливаем зависимости
RUN npm ci && npm cache clean --force
# Копируем исходный код
COPY . .
# Переменные окружения для сборки
# VITE_API_URL используется в runtime через import.meta.env
ARG VITE_API_URL
ENV VITE_API_URL=${VITE_API_URL}
# Собираем приложение
RUN npm run build
# Stage 2: Production образ с nginx
FROM nginx:alpine
# Устанавливаем wget и gettext (для envsubst)
RUN apk add --no-cache wget gettext
# Копируем собранные файлы из builder stage
COPY --from=builder /app/dist /usr/share/nginx/html
# Копируем шаблон конфигурации nginx
COPY nginx.conf.template /etc/nginx/templates/default.conf.template
# Переменные окружения для nginx конфигурации (значения по умолчанию)
# Если бэкенд использует HTTPS, используйте https://backend:443
ENV BACKEND_URL=https://backend:443
# BACKEND_SSL_VERIFY: "on" = проверка включена, "off" = проверка отключена (по умолчанию отключена для самоподписанных сертификатов)
ENV BACKEND_SSL_VERIFY=off
# Открываем порт 80
EXPOSE 80
# Healthcheck
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost/ || exit 1
# Запускаем nginx
CMD ["nginx", "-g", "daemon off;"]
+58
View File
@@ -0,0 +1,58 @@
server {
listen 80;
server_name _;
root /usr/share/nginx/html;
index index.html;
# Gzip compression
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml+rss application/json application/javascript;
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
# SPA routing - все запросы направляем на index.html
location / {
try_files $uri $uri/ /index.html;
}
# Кеширование статических ресурсов
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# API проксирование к бэкенду
# Все запросы к /api проксируются на бэкенд
location /api {
# Проксируем на бэкенд (используется переменная окружения BACKEND_URL)
proxy_pass ${BACKEND_URL};
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
# Для HTTPS бэкенда раскомментируйте следующую строку
# proxy_ssl_verify off;
# Таймауты
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
# Healthcheck endpoint
location /health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
}
+58
View File
@@ -0,0 +1,58 @@
server {
listen 80;
server_name _;
root /usr/share/nginx/html;
index index.html;
# Gzip compression
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml+rss application/json application/javascript;
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
# SPA routing - все запросы направляем на index.html
location / {
try_files $uri $uri/ /index.html;
}
# Кеширование статических ресурсов
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# API проксирование к бэкенду
# Все запросы к /api проксируются на бэкенд
location /api {
# Проксируем на бэкенд (используется переменная окружения BACKEND_URL)
proxy_pass ${BACKEND_URL};
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
# Для HTTPS бэкенда (BACKEND_SSL_VERIFY: "on" = проверка включена, "off" = проверка отключена)
proxy_ssl_verify ${BACKEND_SSL_VERIFY};
# Таймауты
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
# Healthcheck endpoint
location /health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
}
+159
View File
@@ -0,0 +1,159 @@
version: '3.8'
# Docker Compose для локальной сборки образов
# Используйте: docker-compose -f docker-compose.build.yml build
# Затем: docker-compose up -d
services:
frontend:
build:
context: ./client
dockerfile: Dockerfile
args:
# URL бэкенда для сборки (используется в runtime через import.meta.env.VITE_API_URL)
VITE_API_URL: ${VITE_API_URL:-/api/v1}
image: ${FRONTEND_IMAGE:-shop-platform-frontend:latest}
container_name: shop-platform-frontend
ports:
- "${FRONTEND_PORT:-3000}:80"
environment:
# URL бэкенда для nginx proxy (используется в nginx.conf.template)
# Если бэкенд использует HTTPS (WEB_TSL=true), используйте https://backend:443
- BACKEND_URL=${BACKEND_URL:-https://backend:443}
# Настройка SSL проверки для бэкенда ("on" = проверка включена, "off" = проверка отключена)
- BACKEND_SSL_VERIFY=${BACKEND_SSL_VERIFY:-off}
# URL бэкенда для клиентского приложения (используется в runtime через import.meta.env.VITE_API_URL)
# Если не задан, используется относительный путь /api/v1 (проксируется через nginx)
- VITE_API_URL=${VITE_API_URL:-/api/v1}
depends_on:
- backend
restart: unless-stopped
networks:
- shop-network
backend:
build:
context: .
dockerfile: Dockerfile
image: ${BACKEND_IMAGE:-shop-platform-backend:latest}
container_name: shop-platform-backend
ports:
- "${WEB_HTTP_PORT:-80}:80"
- "${WEB_HTTPS_PORT:-443}:443"
environment:
# PostgreSQL настройки
- POSTGRES_HOST=${POSTGRES_HOST:-postgres}
- POSTGRES_PORT=${POSTGRES_PORT:-5432}
- POSTGRES_USER=${POSTGRES_USER:-postgres}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-postgres}
- POSTGRES_DB=${POSTGRES_DB:-shop_platform}
# Web настройки
- WEB_HTTP_PORT=${WEB_HTTP_PORT:-80}
- WEB_HTTPS_PORT=${WEB_HTTPS_PORT:-443}
- WEB_TSL=${WEB_TSL:-true}
- WEB_HOST=${WEB_HOST:-0.0.0.0}
# TLS/SSL настройки
- TSL_PATH=${TSL_PATH:-./tsl}
- TSL_KEY=${TSL_KEY:-key.pem}
- TSL_CERT=${TSL_CERT:-cert.pem}
- TSL_HOST=${TSL_HOST:-localhost}
- TSL_C=${TSL_C:-RU}
- TSL_ST=${TSL_ST:-Moscow}
- TSL_L=${TSL_L:-Moscow}
- TSL_O=${TSL_O:-Softline}
- TSL_OU=${TSL_OU:-Digital}
# MinIO настройки
- MINIO_ENDPOINT=${MINIO_ENDPOINT:-minio}
- MINIO_PORT=${MINIO_PORT:-9000}
- MINIO_USE_SSL=${MINIO_USE_SSL:-false}
- MINIO_ACCESS_KEY=${MINIO_ACCESS_KEY:-administrator}
- MINIO_SECRET_KEY=${MINIO_SECRET_KEY:-123QWEasd}
- MINIO_REGION=${MINIO_REGION:-us-east-1}
- MINIO_BUCKET_NAME=${MINIO_BUCKET_NAME:-store-images}
# Логирование
- LOG_LEVEL=${LOG_LEVEL:-info}
- STDOUT_LOG_LEVEL=${STDOUT_LOG_LEVEL:-info}
- FILE_LOG_LEVEL=${FILE_LOG_LEVEL:-}
# JWT Secret (важно для безопасности!)
- JWT_SECRET=${JWT_SECRET:-your-secret-key-change-in-production}
volumes:
# Монтируем сертификаты (если они есть на хосте)
- ./tsl:/app/tsl:ro
# Монтируем логи (опционально)
- ./logs:/app/logs
depends_on:
- postgres
- minio
restart: unless-stopped
networks:
- shop-network
postgres:
image: ${POSTGRES_IMAGE:-postgres:15-alpine}
container_name: shop-platform-postgres
environment:
- POSTGRES_USER=${POSTGRES_USER:-postgres}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-postgres}
- POSTGRES_DB=${POSTGRES_DB:-shop_platform}
volumes:
- postgres_data:/var/lib/postgresql/data
# Можно монтировать SQL скрипты для инициализации
- ./sql:/docker-entrypoint-initdb.d:ro
ports:
- "${POSTGRES_PORT:-5432}:5432"
restart: unless-stopped
networks:
- shop-network
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-postgres}"]
interval: 10s
timeout: 5s
retries: 5
minio:
image: ${MINIO_IMAGE:-minio/minio:latest}
container_name: shop-platform-minio
command: server /data --console-address ":9001"
environment:
- MINIO_ROOT_USER=${MINIO_ACCESS_KEY:-administrator}
- MINIO_ROOT_PASSWORD=${MINIO_SECRET_KEY:-123QWEasd}
volumes:
- minio_data:/data
ports:
- "${MINIO_PORT:-9000}:9000"
- "9001:9001" # MinIO Console
restart: unless-stopped
networks:
- shop-network
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 30s
timeout: 20s
retries: 3
cloudbeaver:
image: ${CLOUDBEAVER_IMAGE:-dbeaver/cloudbeaver:latest}
container_name: shop-platform-cloudbeaver
ports:
- "${CLOUDBEAVER_PORT:-8978}:8978"
volumes:
- cloudbeaver_data:/opt/cloudbeaver/workspace
depends_on:
- postgres
restart: unless-stopped
networks:
- shop-network
volumes:
postgres_data:
minio_data:
cloudbeaver_data:
networks:
shop-network:
driver: bridge
+146
View File
@@ -0,0 +1,146 @@
version: '3.8'
services:
frontend:
image: ${FRONTEND_IMAGE:-allexd2010/shop-platform-frontend:0.1}
container_name: shop-platform-frontend
ports:
- "${FRONTEND_PORT:-3000}:80"
environment:
# URL бэкенда для nginx proxy (используется в nginx.conf.template)
# Если бэкенд использует HTTPS (WEB_TSL=true), используйте https://backend:443
- BACKEND_URL=${BACKEND_URL:-https://backend:443}
# Настройка SSL проверки для бэкенда ("on" = проверка включена, "off" = проверка отключена)
- BACKEND_SSL_VERIFY=${BACKEND_SSL_VERIFY:-off}
# URL бэкенда для клиентского приложения (используется в runtime через import.meta.env.VITE_API_URL)
# Если не задан, используется относительный путь /api/v1 (проксируется через nginx)
- VITE_API_URL=${VITE_API_URL:-/api/v1}
depends_on:
- backend
restart: unless-stopped
networks:
- shop-network
backend:
image: ${BACKEND_IMAGE:-allexd2010/shop-platform-backend:0.1}
container_name: shop-platform-backend
ports:
- "${WEB_HTTP_PORT:-80}:80"
- "${WEB_HTTPS_PORT:-443}:443"
environment:
# PostgreSQL настройки
- POSTGRES_HOST=${POSTGRES_HOST:-postgres}
- POSTGRES_PORT=${POSTGRES_PORT:-5432}
- POSTGRES_USER=${POSTGRES_USER:-postgres}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-postgres}
- POSTGRES_DB=${POSTGRES_DB:-shop_platform}
# Web настройки
- WEB_HTTP_PORT=${WEB_HTTP_PORT:-80}
- WEB_HTTPS_PORT=${WEB_HTTPS_PORT:-443}
- WEB_TSL=${WEB_TSL:-true}
- WEB_HOST=${WEB_HOST:-0.0.0.0}
# TLS/SSL настройки
- TSL_PATH=${TSL_PATH:-./tsl}
- TSL_KEY=${TSL_KEY:-key.pem}
- TSL_CERT=${TSL_CERT:-cert.pem}
- TSL_HOST=${TSL_HOST:-localhost}
- TSL_C=${TSL_C:-RU}
- TSL_ST=${TSL_ST:-Moscow}
- TSL_L=${TSL_L:-Moscow}
- TSL_O=${TSL_O:-Softline}
- TSL_OU=${TSL_OU:-Digital}
# MinIO настройки
- MINIO_ENDPOINT=${MINIO_ENDPOINT:-minio}
- MINIO_PORT=${MINIO_PORT:-9000}
- MINIO_USE_SSL=${MINIO_USE_SSL:-false}
- MINIO_ACCESS_KEY=${MINIO_ACCESS_KEY:-administrator}
- MINIO_SECRET_KEY=${MINIO_SECRET_KEY:-123QWEasd}
- MINIO_REGION=${MINIO_REGION:-us-east-1}
- MINIO_BUCKET_NAME=${MINIO_BUCKET_NAME:-store-images}
# Логирование
- LOG_LEVEL=${LOG_LEVEL:-info}
- STDOUT_LOG_LEVEL=${STDOUT_LOG_LEVEL:-info}
- FILE_LOG_LEVEL=${FILE_LOG_LEVEL:-}
# JWT Secret (важно для безопасности!)
- JWT_SECRET=${JWT_SECRET:-your-secret-key-change-in-production}
volumes:
# Монтируем сертификаты (если они есть на хосте)
- ./tsl:/app/tsl:ro
# Монтируем логи (опционально)
- ./logs:/app/logs
depends_on:
- postgres
- minio
restart: unless-stopped
networks:
- shop-network
postgres:
image: ${POSTGRES_IMAGE:-postgres:15-alpine}
container_name: shop-platform-postgres
environment:
- POSTGRES_USER=${POSTGRES_USER:-postgres}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-postgres}
- POSTGRES_DB=${POSTGRES_DB:-shop_platform}
volumes:
- postgres_data:/var/lib/postgresql/data
# Можно монтировать SQL скрипты для инициализации
- ./sql:/docker-entrypoint-initdb.d:ro
ports:
- "${POSTGRES_PORT:-5432}:5432"
restart: unless-stopped
networks:
- shop-network
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-postgres}"]
interval: 10s
timeout: 5s
retries: 5
minio:
image: ${MINIO_IMAGE:-minio/minio:latest}
container_name: shop-platform-minio
command: server /data --console-address ":9001"
environment:
- MINIO_ROOT_USER=${MINIO_ACCESS_KEY:-administrator}
- MINIO_ROOT_PASSWORD=${MINIO_SECRET_KEY:-123QWEasd}
volumes:
- minio_data:/data
ports:
- "${MINIO_PORT:-9000}:9000"
- "9001:9001" # MinIO Console
restart: unless-stopped
networks:
- shop-network
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 30s
timeout: 20s
retries: 3
cloudbeaver:
image: ${CLOUDBEAVER_IMAGE:-dbeaver/cloudbeaver:latest}
container_name: shop-platform-cloudbeaver
ports:
- "${CLOUDBEAVER_PORT:-8978}:8978"
volumes:
- cloudbeaver_data:/opt/cloudbeaver/workspace
depends_on:
- postgres
restart: unless-stopped
networks:
- shop-network
volumes:
postgres_data:
minio_data:
cloudbeaver_data:
networks:
shop-network:
driver: bridge