Налаштування Docker-контейнеризації бекенду мобільного додатку
Бекенд мобільного додатку — це не просто REST API. Це push-сповіщення через FCM/APNs, WebSocket для чату, фонові завдання з обробки медіа, Redis для кешування сесій. На одному серверу всім цим запускається як попало, версії бібліотек конфліктують, деплой перетворюється на «сподіваюся, не сломається». Docker вирішує передбачуваність середовища: те, що працює у розробника, працює в CI та production.
Структура для типового мобільного бекенду
Стек, який зустрічається найчастіше: Node.js / Go / Python + PostgreSQL + Redis + Nginx. docker-compose.yml для локальної розробки:
version: '3.9'
services:
api:
build:
context: .
dockerfile: Dockerfile
target: development
ports:
- "3000:3000"
environment:
- DATABASE_URL=postgresql://app:password@postgres:5432/mobile_app
- REDIS_URL=redis://redis:6379
- FCM_SERVER_KEY=${FCM_SERVER_KEY}
volumes:
- .:/app
- /app/node_modules
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_started
postgres:
image: postgres:16-alpine
environment:
POSTGRES_DB: mobile_app
POSTGRES_USER: app
POSTGRES_PASSWORD: password
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U app"]
interval: 5s
timeout: 5s
retries: 5
redis:
image: redis:7-alpine
volumes:
- redis_data:/data
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d
- ./ssl:/etc/nginx/ssl
depends_on:
- api
volumes:
postgres_data:
redis_data:
Multi-stage Dockerfile
Один Dockerfile для development та production через multi-stage build:
# Stage 1: Dependencies
FROM node:20-alpine AS deps
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
# Stage 2: Development
FROM node:20-alpine AS development
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
CMD ["npm", "run", "dev"]
# Stage 3: Build
FROM node:20-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build
# Stage 4: Production
FROM node:20-alpine AS production
WORKDIR /app
ENV NODE_ENV=production
COPY --from=deps /app/node_modules ./node_modules
COPY --from=builder /app/dist ./dist
COPY package*.json ./
# Запускаємо не як root
RUN addgroup -g 1001 -S nodejs && adduser -S nodeuser -u 1001
USER nodeuser
EXPOSE 3000
CMD ["node", "dist/server.js"]
Production-образ не містить dev-залежностей, вихідних кодів та запускається від непривілейованого користувача. Розмір образу зменшується в 2–3 рази порівняно з наївним підходом.
Push-сповіщення у контейнері
Для APNs (Apple Push Notification service) потрібен .p8 ключ. У контейнері він передається через змінну окруження (base64-encoded) або через Docker Secret (у Swarm/Kubernetes). Ніяких ключів у Dockerfile та образах.
# Кодування
APNS_KEY_BASE64=$(base64 -w 0 AuthKey_XXXXXX.p8)
# У docker-compose через secrets або env:
APNS_KEY_BASE64=${APNS_KEY_BASE64}
APNS_KEY_ID=XXXXXXXXXX
APNS_TEAM_ID=YYYYYYYYYY
Healthcheck та graceful shutdown
Мобільні клієнти погано переносять раптові обриви з'єднання. Контейнер має коректно завершувати активні WebSocket-з'єднання та HTTP-запити перед зупинкою. Node.js:
process.on('SIGTERM', () => {
server.close(() => {
mongoose.connection.close();
process.exit(0);
});
});
У Docker Compose/Kubernetes stop_grace_period: 30s дає контейнеру час на shutdown.
Інтеграція CI/CD
# .github/workflows/deploy.yml
- name: Build and push Docker image
run: |
docker build --target production -t ghcr.io/myorg/mobile-api:${{ github.sha }} .
docker push ghcr.io/myorg/mobile-api:${{ github.sha }}
- name: Deploy
run: |
ssh deploy@server "
docker pull ghcr.io/myorg/mobile-api:${{ github.sha }}
docker-compose up -d --no-deps api
"
Процес
Аудит поточного деплою → написання Dockerfile (multi-stage) → написання docker-compose.yml для dev та prod → налаштування healthcheck → інтеграція з CI → налаштування registry → тест деплою → документація.
Тривалість: 2–3 дні для стандартного Node.js/Go бекенду. Вартість розраховується індивідуально після вивчення стека та інфраструктури.







