Alpine vs Debian для контейнеров: что выбрать и почему
Сравнение Alpine и Debian для production-контейнеров. Размер, безопасность, совместимость и реальные кейсы использования.
Выбор базового образа для контейнера определяет не только его размер, но и стабильность, скорость обновлений и совместимость со старым кодом. Alpine и Debian — два самых популярных варианта, но они решают разные задачи.
Ключевые различия
| Параметр | Alpine Linux | Debian |
|---|---|---|
| Базовый размер образа | ~5 МБ | ~120 МБ |
| libc | musl | glibc |
| Пакетный менеджер | apk | apt |
| Цикл обновлений | Rolling (постоянный) | Stable (2 года) |
| Поддержка legacy | Слабая | Отличная |
| Поверхность атаки | Минимальная | Широкая (но контролируемая) |
Когда выбирать Alpine
Alpine — это дистрибутив, заточенный под безопасность и минимализм. Его основное преимущество — размер. Образ на 5 МБ стартует за доли секунды и занимает на диске в десятки раз меньше места, чем Debian-аналог.
Выбирайте Alpine, если:
- Развёртываете микросервисы, где важен масштаб (сотни контейнеров на одном хосте)
- Приложение на Go, Rust или статически скомпилированном C — без внешних зависимостей от glibc
- Нужен максимально быстрый CI/CD — меньше образ, быстрее pull
- Фронтенд-сборщики (Nginx с HTML, Node.js для сборки статики)
Подводный камень musl. Некоторые приложения, скомпилированные под glibc, ведут себя непредсказуемо в Alpine. Я видел случаи, когда Python-приложение с нативными модулями (numpy, pandas) падало с segfault при сборке в Alpine, хотя локально на Debian работало стабильно. Решение — либо пересобирать зависимости под musl, либо отказаться от Alpine.
Когда выбирать Debian
Debian — это стабильность и предсказуемость. Если Alpine — это гоночный болид, то Debian — грузовик: тяжелее, но везёт всё.
Выбирайте Debian, если:
- Контейнеризуете legacy-приложение на PHP 5.6, Python 2.7 или старом Node.js
- Нужны проприетарные библиотеки, собранные только под glibc (1С-коннекторы, некоторые SDK)
- Важен долгосрочный LTS: Debian Stable получает обновления безопасности 5 лет
- Команда не готова разбираться с musl-специфичными багами
Мой реальный кейс. Клиенту нужно было контейнеризовать ERP на PHP 5.6. В Alpine PHP 5.6 давно выпилен из репозиториев, а в Debian 11 он есть в виде стороннего репозитория. Собрали контейнер на Debian, ограничили поверхность атаки — убрали всё лишнее через multi-stage build. Итог: образ 180 МБ вместо 5 МБ Alpine, но приложение работает без переделок.
Практический подход: multi-stage build
Необязательно выбирать одно на всё. Для сборки используйте Debian (где есть все инструменты), а в финальный образ копируйте бинарник в Alpine или scratch:
# Этап сборки
FROM debian:12 AS builder
RUN apt-get update && apt-get install -y build-essential
COPY . /app
RUN make /app
# Финальный образ
FROM alpine:latest
COPY --from=builder /app/bin/myapp /usr/local/bin/
ENTRYPOINT ["myapp"]
Так вы получаете совместимость на этапе сборки и минимальный размер в production.
Rootless-контейнеры и systemd Quadlet
Если вы используете Podman (а я рекомендую), разница между Alpine и Debian в плане безопасности сглаживается. Podman и так запускает контейнеры без root, так что поверхность атаки уже ограничена. В этом случае выбор дистрибутива можно делать исходя из совместимости, а не из страха перед уязвимостями.
Итог
- Alpine — для новых проектов, микросервисов, статической сборки и когда размер критичен.
- Debian — для legacy, сложных зависимостей и когда важнее стабильность, чем мегабайты.
- Multi-stage — чтобы совместить совместимость и размер.
Если не уверены, с чего начать — начните с Debian. Проще отладить, проще найти информацию, проще нанять человека, который разберётся. Переход на Alpine можно сделать позже, когда поймёте, что именно тормозит.
Нужна помощь с выбором инфраструктуры под ваш проект — от консультации до настройки контейнеров в Podman? Пишите, подберём оптимальный стек.