Heroku — это Platform-as-a-Service (PaaS), которая упрощает развертывание, беря на себя инфраструктуру, масштабирование и операционные задачи. Хотя Heroku дороже «сырой» инфраструктуры, она существенно снижает нагрузку на DevOps для небольших команд. Это руководство посвящено развертыванию production-приложений в Heroku с точки зрения senior-разработчика.
Почему Heroku
Heroku особенно хороша в определённых сценариях:
- Быстрое развертывание:
git push для деплоя - Управляемая инфраструктура: без администрирования серверов
- Экосистема add-ons: базы данных, кэширование, мониторинг в один клик
- Автомасштабирование: автоматическая обработка всплесков трафика
- Интеграция CI/CD: встроенные pipelines
Лучше всего подходит для: MVP, небольших команд, приложений, где скорость разработки важнее оптимизации затрат.
Начало работы
Установка CLI
# macOS
brew tap heroku/brew && brew install heroku
# Ubuntu/Debian
curl https://cli-assets.heroku.com/install.sh | sh
# npm (любая платформа)
npm install -g heroku
Аутентификация
heroku login
# Открывает браузер для аутентификации
# Или в неинтерактивном режиме
heroku login -i
Создание приложения
# Создать приложение со случайным именем
heroku create
# Создать с конкретным именем
heroku create my-awesome-app
# Создать в конкретном регионе
heroku create my-app --region eu
Развертывание Node.js
Структура проекта
my-app/
├── package.json
├── package-lock.json
├── Procfile
├── app.js
└── .gitignore
package.json
{
"name": "my-heroku-app",
"version": "1.0.0",
"engines": {
"node": "18.x"
},
"scripts": {
"start": "node app.js",
"dev": "nodemon app.js"
},
"dependencies": {
"express": "^4.18.2"
}
}
Procfile
Определяет типы процессов:
web: node app.js
worker: node worker.js
app.js
const express = require('express');
const app = express();
// Heroku предоставляет переменную окружения PORT
const PORT = process.env.PORT || 3000;
app.get('/', (req, res) => {
res.json({ message: 'Hello from Heroku!' });
});
app.get('/health', (req, res) => {
res.json({ status: 'ok' });
});
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
Развертывание
# Инициализировать git при необходимости
git init
git add .
git commit -m "Initial commit"
# Добавить Heroku remote
heroku git:remote -a my-awesome-app
# Развернуть
git push heroku main
# Открыть в браузере
heroku open
Развертывание Python/Django
Структура проекта
my-django-app/
├── requirements.txt
├── runtime.txt
├── Procfile
├── manage.py
├── myproject/
│ ├── settings.py
│ └── wsgi.py
└── staticfiles/
requirements.txt
Django==4.2
gunicorn==21.2.0
whitenoise==6.6.0
dj-database-url==2.1.0
psycopg2-binary==2.9.9
runtime.txt
python-3.11.4
Procfile
web: gunicorn myproject.wsgi --log-file -
release: python manage.py migrate
Обновления settings.py
import os
import dj_database_url
# Безопасность
SECRET_KEY = os.environ.get('SECRET_KEY', 'dev-secret-key')
DEBUG = os.environ.get('DEBUG', 'False') == 'True'
ALLOWED_HOSTS = ['*'] # Корректно настроить для production
# База данных
DATABASES = {
'default': dj_database_url.config(
default='sqlite:///db.sqlite3',
conn_max_age=600
)
}
# Статические файлы
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
# Whitenoise для статических файлов
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware',
# ... другое middleware
]
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
Развертывание PHP/Laravel
Procfile
web: vendor/bin/heroku-php-apache2 public/
Команды развертывания
# Задать buildpack
heroku buildpacks:set heroku/php
# Задать переменные окружения
heroku config:set APP_KEY=$(php artisan key:generate --show)
heroku config:set APP_ENV=production
heroku config:set APP_DEBUG=false
# Развернуть
git push heroku main
# Выполнить миграции
heroku run php artisan migrate --force
Переменные окружения
Задать Config Vars
# Задать одну переменную
heroku config:set DATABASE_URL=postgres://...
heroku config:set SECRET_KEY=your-secret-key
# Задать несколько
heroku config:set NODE_ENV=production DEBUG=false
# Просмотреть все config vars
heroku config
# Удалить переменную
heroku config:unset DEBUG
Использование в приложении
// Node.js
const dbUrl = process.env.DATABASE_URL;
const secret = process.env.SECRET_KEY;
# Python
import os
db_url = os.environ.get('DATABASE_URL')
secret = os.environ.get('SECRET_KEY')
Add-ons
База данных (Heroku Postgres)
# Добавить free tier
heroku addons:create heroku-postgresql:mini
# Добавить production tier
heroku addons:create heroku-postgresql:standard-0
# Получить информацию о подключении
heroku pg:info
heroku config:get DATABASE_URL
# Открыть psql
heroku pg:psql
Redis
# Добавить Redis
heroku addons:create heroku-redis:mini
# Получить URL подключения
heroku config:get REDIS_URL
Другие полезные add-ons
# Логирование
heroku addons:create papertrail:choklad
# Мониторинг
heroku addons:create newrelic:wayne
# Email
heroku addons:create sendgrid:starter
# Scheduler (cron jobs)
heroku addons:create scheduler:standard
Масштабирование
Ручное масштабирование
# Масштабировать web dyno
heroku ps:scale web=2
# Масштабировать workers
heroku ps:scale worker=1
# Просмотреть текущее масштабирование
heroku ps
# Выключить
heroku ps:scale web=0 worker=0
Типы dyno
# Повысить тип dyno
heroku ps:type web=standard-1x
heroku ps:type worker=standard-2x
Логи и мониторинг
Просмотр логов
# Потоковый вывод логов
heroku logs --tail
# Фильтр по процессу
heroku logs --tail --ps web
# Последние N строк
heroku logs -n 500
# Фильтр по источнику
heroku logs --source app
heroku logs --source heroku
One-off команды
# Выполнить команду
heroku run node scripts/seed.js
heroku run python manage.py shell
# Запустить bash
heroku run bash
Pipelines и Review Apps
Создать pipeline
# Создать pipeline
heroku pipelines:create my-pipeline -a my-app-production
# Добавить staging-приложение
heroku pipelines:add my-pipeline -a my-app-staging -s staging
# Продвинуть staging в production
heroku pipelines:promote -a my-app-staging
app.json для Review Apps
{
"name": "My App",
"scripts": {
"postdeploy": "npm run db:seed"
},
"env": {
"NODE_ENV": "development",
"SECRET_KEY": {
"generator": "secret"
}
},
"addons": [
"heroku-postgresql:mini",
"heroku-redis:mini"
],
"buildpacks": [
{ "url": "heroku/nodejs" }
]
}
Интеграция CI/CD
GitHub Actions
name: Deploy to Heroku
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Deploy to Heroku
uses: akhileshns/[email protected]
with:
heroku_api_key: ${{ secrets.HEROKU_API_KEY }}
heroku_app_name: my-app
heroku_email: [email protected]
Heroku CI
app.json:
{
"environments": {
"test": {
"scripts": {
"test": "npm test"
},
"addons": [
"heroku-postgresql:mini"
]
}
}
}
Пользовательские домены и SSL
Добавить пользовательский домен
# Добавить домен
heroku domains:add www.example.com
heroku domains:add example.com
# Просмотреть DNS targets
heroku domains
# Настроить DNS
# Указать www на <app>.herokudns.com (CNAME)
# Указать apex на <app>.herokudns.com (ALIAS/ANAME)
SSL
# Автоматический SSL (только для платных dyno)
heroku certs:auto:enable
# Ручной SSL
heroku certs:add server.crt server.key
Устранение неполадок
Частые проблемы
# Проверить статус приложения
heroku ps
# Перезапустить все dyno
heroku restart
# Проверить наличие ошибок
heroku logs --tail
# Проверить releases
heroku releases
# Откатиться к предыдущему release
heroku rollback v10
Проблемы сборки
# Просмотреть логи сборки
heroku builds:output
# Очистить кэш сборки
heroku builds:cache:purge -a my-app
Ключевые выводы
- Procfile обязателен: определяет, как запускать ваше приложение
- Переменные окружения: никогда не хардкодьте секреты
- Используйте add-ons: управляемые сервисы экономят время
- Масштабируйтесь уместно: начните с малого и увеличивайте при необходимости
- Следите за логами: критично для отладки проблем в production
- Используйте pipelines: workflow Staging → Production
Heroku обменивает стоимость на простоту — идеально для команд, которым нужно быстро поставлять продукт без выделенных DevOps-ресурсов.