인턴에서 프로젝트를 진행하며 DB를 Docker 컨테이너로 만들어 서버에 올리는 방식으로 사용했다. 크롤링 서버이기에 크롤링 특성상 한 번에 많은 데이터가 수집되는 경우가 있어 서버 과부화로 인해 자주 서버가 다운되는 일이 많았다. 이로 인해 Docker 컨테이너에 대해 서버가 재부팅될 때마다 자동으로 재시작하도록 정책을 업데이트 하였다.
Docker를 서버 부팅 시마다 자동으로 재시작하는 방법
이미 서버에 올려진 Docker 컨테이너를 서버 재부팅 때마다 자동실행하고자 하여 다음과 같이 restart 정책을 설정해주었다.
docker update --restart always crawling_db
이렇게 설정해둔 후 열심히 프로젝트 작업을 하고 있었으나... 서버가 재부팅되었음에도 불구하고 Docker가 자동실행되지 않았으면서 이미 실행되어 사용 중인 Docker라는 에러가 발생하였다.
Error response from daemon: Cannot restart container crawling_db: driver failed programming external connectivity on endpoint crawling_db (): Error starting userland proxy: listen tcp4 0.0.0.0:####: bind: address already in use
위의 에러 메시지가 나타났고 구글링을 통해 파악해보니 Docker에서 발생한 "blind: address already in use" 에러였다. 이 에러는 문자 그대로 사용 중인 포트가 이미 다른 프로세스에 의해 사용 중이라는 것을 의미하였다. 이는 주로 다음 두 가지 상황에 의해서 발생된다.
1. 다른 MySQL/MariaDB 인스턴스가 실행 중인 경우: 이미 시스템에서 MySQL 또는 MariaDB 서버가 실행되고 있는 경우
2. Docker 컨테이너가 중지된 상태로 포트를 점유하고 있는 경우: 이전에 실행 중이던 Docker 컨테이너가 종료되었지만 포트를 해제하지 않는 경우
해당 상황 중 2번째 경우가 원인이었다!
docker ps
명령어를 사용하여 현재 실행 중인 Docker 상태를 확인했지만 실행 중인 Docker 컨테이너는 없었고
docker restart crawling_db
명령어를 사용하여 Docker를 재시작하였을 때 위 에러 메시지가 출력되었다. 해결방법은 다음과 같다.
docker ps # 현재 실행 중인 도커 확인
- Docker 확인 결과 실행 중인 Docker가 없음에도 이미 사용 중인 Docker라는 에러 메시지가 나타난다면
sudo lsof -i :3306 # 포트를 점유하고 있는 프로세스 찾기(ex. port=3306) sudo kill -9 <PID> # 포트를 사용 중인 프로세스에서 pid를 찾아 kill
docker restart crawling_db : 도커 재실행!
처음 해당 에러를 마주했을 때 정말 당황했던 기억이 있다. 특히 DB를 날린 것이 아닌가 많이 당황했지만 자동실행으로 정상 종료가 되지 않아 발생하는 에러임을 확인하고 그 후에는 동일한 에러가 발생했을 때 익숙하게 여기고 진행했었다! 이제 Docker 에러는 그만!!!