Ответ
В DevOps-практике донастройка контейнеров при запуске — обычная задача. Я использую несколько проверенных подходов в зависимости от требований.
1. Entrypoint-скрипты (самый частый случай):
# Dockerfile
FROM alpine:3.18
COPY entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/entrypoint.sh
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
CMD ["nginx", "-g", "daemon off;"]
#!/bin/sh
# entrypoint.sh
set -e
# Динамическая генерация конфига из переменных окружения
if [ -n "$DB_HOST" ]; then
sed -i "s/localhost/$DB_HOST/g" /etc/app/config.yaml
fi
# Создание необходимых директорий с правильными правами
mkdir -p /var/log/app && chown app:app /var/log/app
# Запуск основного процесса (важно использовать exec)
exec "$@"
2. Многоступенчатая инициализация через Init-контейнеры (Kubernetes):
# deployment.yaml
spec:
initContainers:
- name: init-config
image: alpine:3.18
command:
- sh
- -c
- |
# Скачиваем конфиг из S3 или Vault
aws s3 cp s3://config-bucket/app-config.yaml /shared-config/
# Ждем готовности БД
until nc -z $DB_HOST 5432; do sleep 2; done
volumeMounts:
- name: shared-config
mountPath: /shared-config
containers:
- name: app
image: myapp:latest
volumeMounts:
- name: shared-config
mountPath: /etc/app/config
3. Динамическая конфигурация через ConfigMap и Volumes:
# configmap-generator.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
config.yaml: |
database:
host: ${DB_HOST}
port: 5432
logging:
level: ${LOG_LEVEL:-INFO}
---
# Используем envsubst для подстановки переменных
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
containers:
- name: app
command:
- sh
- -c
- |
export DB_HOST="$DB_HOST"
envsubst < /config-templates/config.yaml > /etc/app/config.yaml
exec /app/start.sh
4. Использование специализированных инструментов:
Для сложных случаев применяю:
- envsubst (из пакета gettext) для шаблонизации
- confd для динамического обновления конфигов
- Consul Template в связке с Service Discovery
Пример из реального проекта (PostgreSQL + wal-g):
# Dockerfile для PostgreSQL с настройкой бэкапов
FROM postgres:15-alpine
COPY docker-entrypoint-initdb.d /docker-entrypoint-initdb.d/
COPY setup-walg.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/setup-walg.sh
&& echo 'source /usr/local/bin/setup-walg.sh' >> /docker-entrypoint.sh
# setup-walg.sh настраивает WAL-G при старте контейнера
# на основе переменных окружения AWS_ACCESS_KEY_ID и т.д.
Ключевой принцип: Контейнер должен быть идемпотентным — при любом количестве перезапусков конфигурация применяется корректно.