## 🐳 Что такое `docker-entrypoint.sh`
`docker-entrypoint.sh` — это **скрипт, который выполняется при запуске контейнера Docker**.
Он служит **точкой входа (entrypoint)** и позволяет:
- Выполнить инициализацию окружения;
- Настроить переменные среды, конфиги, права;
- Выполнить миграции БД, сборку статики и т.д.;
- Затем **передать управление основному процессу**, чтобы контейнер продолжал работу.
---
## 🔹 ENTRYPOINT и CMD: в чём разница
В `Dockerfile` часто встречаются две похожие инструкции: `ENTRYPOINT` и `CMD`.
| Инструкция | Что делает | Когда использовать |
|-------------|-------------|--------------------|
| **ENTRYPOINT** | Задает обязательную программу или скрипт, который всегда выполняется при запуске контейнера | Когда нужен фиксированный стартовый скрипт |
| **CMD** | Указывает аргументы по умолчанию для `ENTRYPOINT` или команду, если `ENTRYPOINT` не задан | Когда нужно задать команду по умолчанию |
🧩 Пример:
```dockerfile
ENTRYPOINT ["./docker-entrypoint.sh"]
CMD ["python3", "app.py"]
````
Docker выполнит:
```bash
./docker-entrypoint.sh python3 app.py
```
---
## 🔹 Пример 1: Минимальный `docker-entrypoint.sh`
```bash
#!/bin/sh
set -e # Останавливает выполнение при ошибке
echo "Starting the container..."
exec "$@" # Передаёт управление команде из CMD
```
> 💡 `exec "$@"` заменяет текущий процесс скрипта на процесс, переданный в аргументах (`CMD`).
> Это позволяет контейнеру корректно получать сигналы (например, `SIGTERM`, `SIGINT`).
---
## 🔹 Пример 2: Python / Flask приложение
**Dockerfile:**
```dockerfile
FROM python:3.11-slim
WORKDIR /app
COPY . .
RUN pip install -r requirements.txt
COPY docker-entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["gunicorn", "app:app", "-b", "0.0.0.0:80"]
```
**docker-entrypoint.sh:**
```bash
#!/bin/sh
set -e
echo "Checking environment..."
if [ -z "$DATABASE_URL" ]; then
echo "Warning: DATABASE_URL is not set!"
fi
echo "Running migrations..."
flask db upgrade || true
echo "Starting Flask app..."
exec "$@"
```
📊 При запуске:
```bash
docker run -e DATABASE_URL=mysql://user:pass@db/app myflaskapp
```
Сначала выполнится скрипт, затем запустится `gunicorn`.
---
## 🔹 Пример 3: Node.js приложение
**docker-entrypoint.sh:**
```bash
#!/bin/bash
set -e
echo "Installing dependencies if needed..."
if [ ! -d "node_modules" ]; then
npm install
fi
echo "Starting application..."
exec "$@"
```
**Dockerfile:**
```dockerfile
ENTRYPOINT ["./docker-entrypoint.sh"]
CMD ["npm", "start"]
```
---
## 🔹 Пример 4: Инициализация базы данных (PostgreSQL)
```bash
#!/bin/sh
set -e
if [ "$1" = "postgres" ]; then
echo "Initializing PostgreSQL database..."
if [ ! -d "/var/lib/postgresql/data" ]; then
initdb -D /var/lib/postgresql/data
fi
fi
exec "$@"
```
Теперь при запуске контейнера с `postgres` база инициализируется автоматически.
---
## 🔹 Отладка entrypoint-скрипта
Запустить контейнер вручную:
```bash
docker run --rm -it myimage /bin/sh
```
Запустить без entrypoint:
```bash
docker run --entrypoint /bin/sh -it myimage
```
Так можно протестировать команды внутри контейнера и найти ошибку.
---
## 🔹 Типичные ошибки и решения
|Ошибка|Причина|Решение|
|---|---|---|
|`permission denied`|Нет прав на выполнение|`chmod +x docker-entrypoint.sh`|
|Скрипт не запускается|Неверный путь|Убедитесь, что скопирован и указан в `ENTRYPOINT`|
|Переменные не подставляются|Shell не поддерживает расширения|Используйте `#!/bin/bash`|
|Контейнер сразу завершается|Нет `exec "$@"`|Добавьте передачу команды в конце|
---
## 🔹 Минимальный тестовый пример
```bash
mkdir entrypoint-demo && cd entrypoint-demo
```
**Dockerfile**
```dockerfile
FROM alpine:latest
COPY docker-entrypoint.sh /
RUN chmod +x /docker-entrypoint.sh
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["echo", "Hello from CMD!"]
```
**docker-entrypoint.sh**
```bash
#!/bin/sh
echo "Running entrypoint..."
exec "$@"
```
Соберите и запустите:
```bash
docker build -t entrypoint-demo .
docker run entrypoint-demo
```
🧾 Результат:
```
Running entrypoint...
Hello from CMD!
```
---
## 🧩 Вывод
Файл **`docker-entrypoint.sh`** — это мощный инструмент, который позволяет:
- Инициализировать контейнер перед запуском приложения;
- Гибко управлять конфигурацией и окружением;
- Запускать контейнеры предсказуемо и безопасно.
📈 Он особенно полезен в продакшн-среде, CI/CD и Kubernetes, где важно, чтобы контейнеры запускались с нужными параметрами и корректной инициализацией.
---
✍️ Автор: _Vlad Levinas_
📅 Обновлено: _12 ноября 2025_
🔗 [levintalk.media](https://levintalk.media/)
```
---
Хочешь, я подготовлю этот файл (`docker-entrypoint-guide.md`) и сразу создам `.zip`-архив, чтобы ты мог загрузить его в свою CMS или GitHub-репозиторий?
```