1. Что нужно бэкапить

Полная копия Jira состоит из двух частей. Потеря любой из них = потеря данных:

  • База данных PostgreSQL — все задачи, проекты, пользователи, настройки
  • Jira Home Directory (/var/atlassian/application-data/jira) — вложения к задачам, индексы поиска, кэш, конфиги
Встроенный XML-бэкап Jira (Administration → System → Backup System) содержит только данные БД и НЕ включает вложения файлов. Для полного бэкапа нужны оба метода описанных ниже.

2. Бэкап PostgreSQL с pg_dump

pg_dump создаёт консистентный снапшот базы без необходимости останавливать Jira. Это главное преимущество перед файловым копированием данных PostgreSQL.

# Базовая команда
pg_dump -U jirauser -h localhost -d jiradb -F c -f /backup/jira-db-$(date +%Y%m%d).dump

# Параметры:
# -F c  — кастомный бинарный формат (сжатый, оптимален для pg_restore)
# -F p  — plain SQL (читаем, но большой размер)
# -Z 9  — максимальное сжатие

Создаём директорию для бэкапов:

mkdir -p /backup/jira-db
mkdir -p /backup/jira-home
chmod 750 /backup
chown postgres:postgres /backup/jira-db

Проверяем что бэкап создался:

ls -lh /backup/jira-db/
# jira-db-20260205.dump  156M

# Проверка целостности
pg_restore --list /backup/jira-db/jira-db-20260205.dump | head -20

3. Бэкап Jira Home Directory

Home-директория содержит вложения к задачам — это часто самое ценное что есть в Jira. Копируем с rsync:

# Останавливаем Jira перед бэкапом home-директории
# (или делаем бэкап на лету с пониманием что индексы могут быть в непоследовательном состоянии)

BACKUP_DIR="/backup/jira-home/$(date +%Y%m%d)"
mkdir -p "$BACKUP_DIR"

rsync -avz --exclude='log/' --exclude='tmp/' --exclude='cache/' \
  /var/atlassian/application-data/jira/ \
  "$BACKUP_DIR/"

echo "Backup size: $(du -sh $BACKUP_DIR | cut -f1)"

Что исключаем из бэкапа (не нужно восстанавливать):

log/      — логи (пересоздаются)
tmp/      — временные файлы
cache/    — кэш (пересоздаётся при старте)
plugins/  — плагины (можно исключить если ставите заново)

4. Автоматизация через cron

Создаём скрипт бэкапа:

#!/bin/bash
# /usr/local/bin/jira-backup.sh

BACKUP_ROOT="/backup"
DATE=$(date +%Y%m%d_%H%M)
DB_BACKUP="$BACKUP_ROOT/jira-db/jira-db-$DATE.dump"
HOME_BACKUP="$BACKUP_ROOT/jira-home/$DATE"
LOG_FILE="/var/log/jira-backup.log"
KEEP_DAYS=7

echo "$(date): Starting Jira backup" >> "$LOG_FILE"

# 1. Бэкап базы данных
pg_dump -U jirauser -h localhost -d jiradb -F c -f "$DB_BACKUP"
if [ $? -eq 0 ]; then
    echo "$(date): DB backup OK: $(du -sh $DB_BACKUP | cut -f1)" >> "$LOG_FILE"
else
    echo "$(date): DB backup FAILED!" >> "$LOG_FILE"
    exit 1
fi

# 2. Бэкап home-директории
mkdir -p "$HOME_BACKUP"
rsync -a --exclude='log/' --exclude='tmp/' --exclude='cache/' \
  /var/atlassian/application-data/jira/ "$HOME_BACKUP/"
echo "$(date): Home backup OK: $(du -sh $HOME_BACKUP | cut -f1)" >> "$LOG_FILE"

# 3. Удаляем старые бэкапы
find "$BACKUP_ROOT/jira-db" -name "*.dump" -mtime +$KEEP_DAYS -delete
find "$BACKUP_ROOT/jira-home" -maxdepth 1 -type d -mtime +$KEEP_DAYS -exec rm -rf {} +

echo "$(date): Backup complete" >> "$LOG_FILE"
chmod +x /usr/local/bin/jira-backup.sh

# Запускаем в cron каждый день в 3:00 ночи
crontab -e
# Добавить строку:
0 3 * * * /usr/local/bin/jira-backup.sh

5. Процедура восстановления

Восстановление делается в строгом порядке:

1
Останавливаем Jira
systemctl stop jira
2
Восстанавливаем базу данных
# Дропаем старую базу
sudo -u postgres psql -c "DROP DATABASE jiradb;"
sudo -u postgres psql -c "CREATE DATABASE jiradb WITH ENCODING='UNICODE' LC_COLLATE='C' LC_CTYPE='C' TEMPLATE=template0;"
sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE jiradb TO jirauser;"

# Восстанавливаем из дампа
pg_restore -U jirauser -h localhost -d jiradb /backup/jira-db/jira-db-20260205.dump
echo "DB restore exit code: $?"
3
Восстанавливаем home-директорию
# Бэкапим текущую (на всякий случай)
mv /var/atlassian/application-data/jira /var/atlassian/application-data/jira.old

# Восстанавливаем
rsync -av /backup/jira-home/20260205_030015/ \
  /var/atlassian/application-data/jira/

chown -R jira:jira /var/atlassian/application-data/jira/
4
Запускаем Jira и пересоздаём индекс
systemctl start jira
# Ждём полного запуска, затем:
# Administration → System → Indexing → Re-Index

6. Тестирование DR

Непроверенный бэкап — это не бэкап. Раз в квартал поднимайте тестовую среду из бэкапа и проверяйте:

  • Jira запустилась
  • Можно войти под администратором
  • Открыть несколько задач с вложениями — вложения отображаются
  • Поиск работает (если нет — запустить Re-Index)
  • Зафиксировать время восстановления (RTO)
Зафиксируйте RTO (Recovery Time Objective) — сколько времени заняло восстановление. Сообщите эту цифру руководству. Это важная метрика для бизнеса и мотивация инвестировать в более быстрые решения (например Jira Data Center с hot standby).