Когда происходит миграция базы данных при деплое?

«Когда происходит миграция базы данных при деплое?» — вопрос из категории DevOps, который задают на 26% собеседований Node.js Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В Node.js проектах миграции базы данных обычно выполняются до деплоя нового кода, как часть пайплайна CI/CD. Вот как я это организую:

Типичный процесс деплоя с миграциями:

  1. Подготовительный этап (Pre-deployment)

    // package.json
    {
    "scripts": {
    "migrate:up": "knex migrate:latest",
    "migrate:down": "knex migrate:rollback",
    "migrate:status": "knex migrate:status"
    }
    }
  2. Пайплайн в CI/CD (например, GitHub Actions)

    # .github/workflows/deploy.yml
    jobs:
    deploy:
    steps:
      - name: Run database migrations
        run: npm run migrate:up
        env:
          DATABASE_URL: ${{ secrets.PRODUCTION_DB_URL }}
    
      - name: Verify migrations
        run: npm run migrate:status
    
      - name: Deploy application
        run: ./deploy.sh

Практический пример с Knex.js:

// migrations/20240101_create_users.js
exports.up = function(knex) {
  return knex.schema.createTable('users', (table) => {
    table.increments('id');
    table.string('email').unique().notNullable();
    table.string('password_hash').notNullable();
    table.timestamps(true, true);
  });
};

exports.down = function(knex) {
  return knex.schema.dropTable('users');
};

// Скрипт для безопасного применения миграций
const runMigrations = async () => {
  try {
    console.log('Starting database migrations...');

    // Бэкап перед миграциями (для production)
    if (process.env.NODE_ENV === 'production') {
      await backupDatabase();
    }

    // Применение миграций
    const [batchNo, log] = await knex.migrate.latest();

    console.log(`Migrations completed. Batch: ${batchNo}`);
    log.forEach((migration) => {
      console.log(`✓ ${migration}`);
    });

    return true;
  } catch (error) {
    console.error('Migration failed:', error);

    // В production можно автоматически откатиться
    if (process.env.NODE_ENV === 'production') {
      await knex.migrate.rollback();
      console.log('Rollback completed due to migration error');
    }

    throw error;
  }
};

Лучшие практики, которые я применяю:

  • Всегда делаю бэкап базы перед миграциями в production
  • Использую транзакции для миграций, изменяющих данные
  • Тестирую миграции на staging-окружении
  • Реализую откатываемые стратегии деплоя (blue-green)
  • Добавляю проверки целостности данных после миграций