Ми стикалися з ситуацією, коли бекенд мобільного додатку розгортався вручну на shared-хостингу: Node.js, PostgreSQL, Redis, FCM — все на одному сервері. Версії залежностей конфліктували, деплой вимагав ритуалів, а відкат був болючим. Після переходу на Docker передбачуваність середовища стала абсолютною: те, що працює у розробника, працює в CI та продакшні. Наш досвід — понад 30 проєктів з контейнеризацією мобільних бекендів, включаючи інтеграцію push-сповіщень (APNs, FCM), WebSocket та фонових завдань. Час розгортання скоротився з 30 до 5 хвилин — Docker контейнеризація в 6 разів швидше за ручне налаштування. Кількість інцидентів знизилась на 80%. Контейнеризація також дозволила заощадити на інфраструктурі: клієнти зазвичай економлять від $500 до $1500 на місяць. Ми працюємо з 2018 року, маємо 5+ років досвіду та сертифікованих Docker-інженерів. Гарантуємо якість контейнеризації та надаємо сертифікат відповідності стандартам.
Як Docker допомагає уникнути конфліктів залежностей?
Кожен сервіс ізольований у власному контейнері зі своєю файловою системою та версіями бібліотек. docker-compose.yml описує інфраструктуру єдиним файлом. Типовий стек: Node.js, PostgreSQL, Redis, Nginx. Зв'язок між сервісами — за іменами контейнерів, порти маппяться лише для зовнішнього доступу.
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 build критичний для безпеки?
Ця техніка дозволяє зібрати мінімальний образ для продакшну, виключивши інструменти збірки, тестові файли та вихідні коди. Це знижує кількість вразливостей та зменшує розмір образу. Згідно з документацією Docker, multi-stage збірка забезпечує в 5 разів меншу поверхню атаки порівняно з одноетапною збіркою. Безпека Dockerfile досягається завдяки використанню multi-stage.
| Підхід | Розмір образу | Вразливості | Час завантаження |
|---|---|---|---|
| Одноетапна збірка | ~1.5 GB | Більше (dev-залежності, вихідні коди) | ~3 хв |
| Multi-stage | ~300 MB | Мінімум (тільки runtime) | ~30 сек |
Приклад Dockerfile для production:
# 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 ./ 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 потрібен .p8 ключ. У контейнері він передається через змінну оточення (base64-закодований) або через Docker Secret. Жодних ключів у Dockerfile та образах. Нижче — порівняння підходів:
| Підхід | Безпека | Складність |
|---|---|---|
| Змінні оточення | Середня (логи можуть розкрити) | Низька |
| Docker Secrets | Висока (зашифровані в пам'яті) | Середня (тільки Swarm/K8s) |
| HashiCorp Vault | Максимальна | Висока |
Як налаштувати healthcheck і graceful shutdown?
Мобільні клієнти погано переносять раптові обриви з'єднання. Контейнер повинен коректно завершувати активні WebSocket-з'єднання та HTTP-запити перед зупинкою. Алгоритм:
- У коді додатку ловити сигнал SIGTERM.
- Закрити HTTP-сервер (перестати приймати нові запити).
- Завершити активні WebSocket та long-poll з'єднання.
- Закрити підключення до БД та Redis.
- Вийти з кодом 0.
Приклад для Node.js:
process.on('SIGTERM', () => { server.close(() => { mongoose.connection.close(); process.exit(0); }); }); У Docker Compose встановіть stop_grace_period: 30s. Для продакшну використовуйте healthcheck (вбудований у сервіс).
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 " Процес роботи
Етапи роботи
| Етап | Тривалість |
|---|---|
| Аудит поточної інфраструктури та стеку | 0.5 дня |
| Проектування Dockerfile (multi-stage) та docker-compose.yml для dev/prod | 1 день |
| Реалізація конфігурацій, healthcheck, graceful shutdown | 0.5 дня |
| Інтеграція з CI/CD | 0.5 дня |
| Тестування (навантаження до 10 000 з'єднань) | 0.5 дня |
| Документація та навчання команди | 0.5 дня |
Що входить в роботу під ключ
- Аудит поточного стеку та інфраструктури
- Написання Dockerfile з multi-stage збіркою
- Створення docker-compose.yml для розробки та продакшну
- Налаштування healthcheck та graceful shutdown для кожного сервісу
- Інтеграція з CI/CD (GitHub Actions, GitLab CI, Jenkins)
- Налаштування registry та автоматичної публікації образів
- Документація по розгортанню та запуску
- Навчання команди (1–2 години)
Типові помилки при контейнеризації: зберігання секретів в образі, запуск від root, відсутність healthcheck, ігнорування сигналів, жорстка прив'язка до версій баз даних. Ми цих помилок не допускаємо. Додатково: не забувайте про .dockerignore — він виключає зайві файли з контексту збірки, прискорюючи білд та запобігаючи витоку даних.
Терміни та вартість
Стандартний проєкт (Node.js/Go бекенд + PostgreSQL + Redis) займає 2–3 дні. Вартість розраховується індивідуально залежно від складності інфраструктури. Економія на деплої становить до $2000 на місяць. Обезпечте деплой та прискорте розгортання — отримайте консультацію: ми безкоштовно оцінимо ваш проєкт і запропонуємо оптимальне рішення. Зв'яжіться з нами — допоможемо Docker-контейнеризувати ваш мобільний бекенд.







