Обновлены скрипты резервного копирования для улучшения управления контейнерами
- Автоматическое определение project name из Docker labels - Остановка и запуск контейнеров с использованием их ID вместо docker-compose - Обновлены комментарии и документация для ясности использования - Изменены примеры в env.example и README.md для соответствия новым изменениям
This commit is contained in:
@@ -38,8 +38,8 @@ jobs:
|
|||||||
uses: docker/login-action@v3
|
uses: docker/login-action@v3
|
||||||
with:
|
with:
|
||||||
registry: ${{ env.REGISTRY }}
|
registry: ${{ env.REGISTRY }}
|
||||||
username: ${{ gitea.actor }}
|
username: ${{ secrets.REGISTRY_USERNAME }}
|
||||||
password: ${{ gitea.token }}
|
password: ${{ secrets.REGISTRY_PASSWORD }}
|
||||||
|
|
||||||
- name: Extract metadata
|
- name: Extract metadata
|
||||||
id: meta
|
id: meta
|
||||||
|
|||||||
@@ -111,9 +111,11 @@ docker exec project-backup aws s3 ls s3://your-bucket --endpoint-url=https://you
|
|||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
environment:
|
environment:
|
||||||
- BACKUP_STOP_SERVICES=app db
|
- BACKUP_STOP_SERVICES=gitea postgres
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Важно:** Контейнер `backup` должен быть запущен из **того же** `docker-compose.yaml` что и целевые сервисы. Project name определяется автоматически через Docker labels.
|
||||||
|
|
||||||
Сервисы автоматически запустятся после создания архива.
|
Сервисы автоматически запустятся после создания архива.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
93
backup.sh
93
backup.sh
@@ -64,29 +64,52 @@ stop_services() {
|
|||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Ищем docker-compose.yml в директории бекапа
|
# Определяем project name из собственных labels контейнера
|
||||||
local compose_file="/backup-source/docker-compose.yml"
|
local project_name=$(docker inspect "$HOSTNAME" --format '{{index .Config.Labels "com.docker.compose.project"}}' 2>/dev/null)
|
||||||
|
|
||||||
if [ ! -f "$compose_file" ]; then
|
if [ -z "$project_name" ]; then
|
||||||
# Пробуем docker-compose.yaml
|
log_warning "Не удалось определить project name автоматически"
|
||||||
compose_file="/backup-source/docker-compose.yaml"
|
log_warning "Контейнер backup должен быть запущен из того же docker-compose.yaml что и целевые сервисы"
|
||||||
fi
|
return 0
|
||||||
|
|
||||||
if [ ! -f "$compose_file" ]; then
|
|
||||||
log_error "Docker Compose файл не найден в /backup-source/"
|
|
||||||
return 1
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
log "Project name определён автоматически: ${project_name}"
|
||||||
log "Остановка сервисов: ${BACKUP_STOP_SERVICES}"
|
log "Остановка сервисов: ${BACKUP_STOP_SERVICES}"
|
||||||
log "Используется compose файл: ${compose_file}"
|
|
||||||
|
|
||||||
# Останавливаем указанные сервисы
|
# Запоминаем ID контейнеров для последующего запуска
|
||||||
docker compose -f "$compose_file" down $BACKUP_STOP_SERVICES || {
|
CONTAINERS_TO_RESTART=""
|
||||||
log_error "Ошибка при остановке сервисов"
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
log "Сервисы успешно остановлены"
|
for service in $BACKUP_STOP_SERVICES; do
|
||||||
|
# Ищем контейнер по service name + project name + статус running
|
||||||
|
local container_id=$(docker ps \
|
||||||
|
--filter "label=com.docker.compose.service=${service}" \
|
||||||
|
--filter "label=com.docker.compose.project=${project_name}" \
|
||||||
|
--filter "status=running" \
|
||||||
|
--format "{{.ID}}" \
|
||||||
|
| head -n1)
|
||||||
|
|
||||||
|
if [ -n "$container_id" ]; then
|
||||||
|
local container_name=$(docker inspect "$container_id" --format '{{.Name}}' | sed 's/^\///')
|
||||||
|
log "Сервис ${service} (контейнер: ${container_name}) запущен, будет остановлен"
|
||||||
|
|
||||||
|
# Останавливаем контейнер
|
||||||
|
docker stop "$container_id" >/dev/null 2>&1 || {
|
||||||
|
log_error "Ошибка при остановке контейнера ${container_name}"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Запоминаем ID для последующего запуска
|
||||||
|
CONTAINERS_TO_RESTART="${CONTAINERS_TO_RESTART} ${container_id}"
|
||||||
|
else
|
||||||
|
log "Сервис ${service} не запущен или не найден, пропускаем"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -n "$CONTAINERS_TO_RESTART" ]; then
|
||||||
|
log "Контейнеры успешно остановлены"
|
||||||
|
else
|
||||||
|
log "Нет запущенных сервисов для остановки"
|
||||||
|
fi
|
||||||
|
|
||||||
# Даем время на корректное завершение
|
# Даем время на корректное завершение
|
||||||
sleep 5
|
sleep 5
|
||||||
@@ -100,28 +123,28 @@ start_services() {
|
|||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Ищем docker-compose.yml в директории бекапа
|
# Проверяем что есть контейнеры для запуска
|
||||||
local compose_file="/backup-source/docker-compose.yml"
|
if [ -z "$CONTAINERS_TO_RESTART" ]; then
|
||||||
|
log "Нет контейнеров для запуска"
|
||||||
if [ ! -f "$compose_file" ]; then
|
return 0
|
||||||
# Пробуем docker-compose.yaml
|
|
||||||
compose_file="/backup-source/docker-compose.yaml"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ ! -f "$compose_file" ]; then
|
log "Запуск контейнеров..."
|
||||||
log_error "Docker Compose файл не найден в /backup-source/"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
log "Запуск сервисов: ${BACKUP_STOP_SERVICES}"
|
# Запускаем только те контейнеры, которые были остановлены
|
||||||
|
for container_id in $CONTAINERS_TO_RESTART; do
|
||||||
|
local container_name=$(docker inspect "$container_id" --format '{{.Name}}' 2>/dev/null | sed 's/^\///')
|
||||||
|
|
||||||
|
if [ -n "$container_name" ]; then
|
||||||
|
log "Запуск контейнера: ${container_name}"
|
||||||
|
docker start "$container_id" >/dev/null 2>&1 || {
|
||||||
|
log_error "Ошибка при запуске контейнера ${container_name}"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
# Запускаем указанные сервисы в detached режиме
|
log "Контейнеры успешно запущены"
|
||||||
docker compose -f "$compose_file" up -d $BACKUP_STOP_SERVICES || {
|
|
||||||
log_error "Ошибка при запуске сервисов"
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
log "Сервисы успешно запущены"
|
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,8 @@ services:
|
|||||||
# Запускать ли бэкап сразу при старте контейнера (true/false)
|
# Запускать ли бэкап сразу при старте контейнера (true/false)
|
||||||
- BACKUP_ON_START=${BACKUP_ON_START:-false}
|
- BACKUP_ON_START=${BACKUP_ON_START:-false}
|
||||||
|
|
||||||
# Список сервисов для остановки перед бекапом через пробел (необязательно): gitea gitea-db
|
# Список сервисов для остановки перед бекапом через пробел (необязательно): gitea postgres
|
||||||
|
# Контейнер backup должен быть запущен из того же docker-compose.yaml что и целевые сервисы
|
||||||
- BACKUP_STOP_SERVICES=${BACKUP_STOP_SERVICES:-}
|
- BACKUP_STOP_SERVICES=${BACKUP_STOP_SERVICES:-}
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
|
|||||||
@@ -54,9 +54,9 @@ BACKUP_SCHEDULE=0 5 * * *
|
|||||||
BACKUP_ON_START=false
|
BACKUP_ON_START=false
|
||||||
|
|
||||||
# Список сервисов для остановки перед бекапом (необязательно)
|
# Список сервисов для остановки перед бекапом (необязательно)
|
||||||
# Сервисы будут остановлены через "docker compose down",
|
# Сервисы будут остановлены через "docker stop",
|
||||||
# а после создания архива запущены через "docker compose up -d"
|
# а после создания архива запущены через "docker start"
|
||||||
# Укажите названия сервисов через пробел, например: gitea gitea-db
|
# Укажите названия сервисов через пробел, например: gitea postgres
|
||||||
# Если не указано - сервисы НЕ будут останавливаться
|
# Если не указано - сервисы НЕ будут останавливаться
|
||||||
# Примечание: автоматически ищется docker-compose.yml в директории бекапа
|
# ВАЖНО: Контейнер backup должен быть запущен из того же docker-compose.yaml что и целевые сервисы
|
||||||
BACKUP_STOP_SERVICES=
|
BACKUP_STOP_SERVICES=
|
||||||
|
|||||||
Reference in New Issue
Block a user