도커를 이용해서 친구랑 같이 mysql과 django를 compose 해 보다가 한 가지 문제가 발생하였습니다. depends on mysql을 이용해서 web을 띄웠는데도 불구하고 간헐적으로 오류가 나는 현상이 나타났던 것입니다. 로그를 보던 도중에, 완전히 디비가 초기화 되지 않았는데도, web에 관한 로그가 생성되었고 제가 테스트용으로 넣어둔 db 접속 테스트가 fail이 뜨면서 exception이 떨어졌습니다. x before y 문제에 걸린 것인데요.

 

 이는, depends on이 'ready' 상태가 될 때 까지 기다리지 않기 때문입니다. 이는 공식 문서에서도 잘 설명이 되어 있었습니다.

 

 그래서 저는 compose file에 command 부분에 따로 shell file을 넣어서, 쉘 파일 내에 있는 것을 실행하게끔 했어요.

 

 

 당연하게도, manage.py가 실행되기 전에, db_init_check.py로 실제 내가 사용할 db 테이블들이 초기화가 잘 되어 있는지 확인하였습니다. 만약에 접속에 실패했거나, 아직 테이블이 생성되지 않았다면 retry를 최대 n번까지 수행하도록 하였습니다. 이 방법이 나쁘지는 않은 듯 합니다. 그런데, 다른 방법이 없나 해서 공식 문서를 조금 더 읽어보게 되었고, wait-for-it과 같은 것을 찾게 되었습니다. 물론 톡방 내부에서도 이것을 많이 추천해 주시기도 했고요. 해당 레포는 링크에서 보실 수 있습니다.

 


 git clone을 하신 다음에, 클론된 repo의 root에 들어오게 되시면, 위와 같은 파일들이 있어요. 여기서 따로 볼 것은 wait-for-it.sh인데요.

 

 

 이것만 쳐 보니, 딱히 옵션이 많이는 없습니다. host와 port가 있고, timeout 옵션이 있어요. retry 옵션이 있는지 없는지는 잘 모르겠네요. 이건 조금만 변형하면 되지 않을까 싶기도 합니다. 하여튼, host:port로 접속을 시도하는데요. 접속이 되면, 종료가 되는 shell 파일인 듯 합니다.

 

 

 예를 들자면, localhost:5000에 접속하려고 합니다. 이 shell 스크립트는 디폴트 timeout이 15초이니, 타임아웃 파라미터가 없으면 15초까지 대기해요. 만약에 15초를 넘어가면 timeout이 걸리고 종료될 겁니다.

 


 timeout 옵션을 길게 주면 조금 더 오랫동안 대기하게 됩니다.

 

 

 systemctl 명령어로 본, mysql 서비스는 현재 inactive 상태입니다.

 

 

 localhost:3306에 대해서 30초의 timeout을 줘 보겠습니다. mysql server의 포트를 바꾸지 않았다면 3306을 쓸 겁니다.

 

 

 20여초 뒤에 systemctl start mysql로 mysql 서비스를 다시 실행시켜 보겠습니다. 그리고 상태를 확인해 보면, active가 뜨게 되는데요.

 

 

 wait-for-it.sh를 띄워놓은 쉘에서 확인해 보니, localhost:3306이 21초 후에 available 상태가 되었다는 메세지를 볼 수 있습니다. 대충 30초에서 60초 정도 유예 시간을 걸어놓고, 해당 포트를 사용할 수 없으면, 바로 종료시키면 될 듯 합니다.