트러블슈팅 1. mailcow 복원이 "Can not read DOCKER_COMPOSE_VERSION variable from mailcow.conf!" 로 멈출 때
춘천 리전에서 돌던 mailcow 를 오사카 리전의 새 노드로 옮기는 중이었습니다. 춘천에서 backup all 로 백업을 떠서 오사카에 풀고, 공식 복원 스크립트를 돌렸더니 복원 지점을 고르기도 전에 끝나 버리더군요.
$ MAILCOW_BACKUP_LOCATION=/opt/backup ./helper-scripts/backup_and_restore.sh restore
Can not read DOCKER_COMPOSE_VERSION variable from mailcow.conf! Is your mailcow up to date? Exiting...
양쪽 다 같은 커밋으로 맞춰 놓았기 때문에 “up to date” 가 문제일 리는 없었습니다. 스크립트를 열어 보니 이 부분입니다.
if [ "${DOCKER_COMPOSE_VERSION}" == "native" ]; then
COMPOSE_COMMAND="docker compose"
elif [ "${DOCKER_COMPOSE_VERSION}" == "standalone" ]; then
COMPOSE_COMMAND="docker-compose"
else
echo -e "\e[31mCan not read DOCKER_COMPOSE_VERSION variable from mailcow.conf! ..."
exit 1
fi
mailcow.conf 의 DOCKER_COMPOSE_VERSION 이 native 나 standalone 이어야 하는데, 춘천에서 가져온 파일에는 이 줄이 DOCKER_COMPOSE_VERSION= 로 비어 있었습니다. 춘천 서버에서는 몇 년 동안 docker compose 를 직접 쳐서 썼으니 아무 문제가 없었던 거고, 이 값을 읽는 복원 스크립트를 처음 돌려 보면서 드러난 겁니다.
새 노드는 compose 플러그인을 쓰니 native 로 채워 주면 됩니다.
sed -i 's/^DOCKER_COMPOSE_VERSION=.*/DOCKER_COMPOSE_VERSION=native/' /opt/mailcow-dockerized/mailcow.conf
복원은 질문을 세 번 합니다. 복원 지점 번호, 무엇을 복원할지(0 이 전부), mysql 을 복원하는 동안 mailcow 를 멈춰도 되느냐. 원격으로 돌릴 거라 미리 답을 넣어서 실행했습니다.
cd /opt/mailcow-dockerized && docker compose up -d
printf '1\n0\nY\n' | MAILCOW_BACKUP_LOCATION=/opt/backup ./helper-scripts/backup_and_restore.sh restore
복원은 잘 끝났는데 웹메일이 502 를 내더군요.
이 노드는 80/443 을 Caddy 하나가 받고 앱들은 web 이라는 도커 네트워크로 붙습니다. 그래서 mailcow 의 nginx 를 그 네트워크에 붙이는 docker-compose.override.yml 을 따로 두었는데, 복원 스크립트가 마지막에 mailcow 를 다시 띄울 때 이렇게 띄웁니다.
${COMPOSE_COMMAND} -f ${COMPOSE_FILE} --env-file ${ENV_FILE} up -d
-f 로 파일을 하나만 지정하면 compose 는 override 파일을 읽지 않습니다. nginx 가 web 네트워크에서 빠져 버렸으니 Caddy 가 찾을 수가 없었던 거죠. 복원이 끝나면 한 번 더 올려 주면 됩니다.
docker compose up -d
override 를 쓰지 않는 설치라면 상관없는 이야기지만, 앞단에 리버스 프록시를 따로 두고 있다면 복원 직후 502 가 나는 이유가 대개 이겁니다.
참고: mailcow 백업과 복원, https://docs.mailcow.email/backup_restore/b_n_r-backup/