오늘은 근래 종종 발행하는 Nginx 웹서버 구동 실패 원인, 98: Address already in use을 살펴보고 Nginx 웹서버에서의 서버 이슈 해결 방법에 대해서 살펴보도록 하겠습니다.
근래들어 nginx 웹서버 시작 시 에러가 나면서 구동에 실패하는 경우가 많아졌습니다. 대부분 원인은 nginx 웹서버가 사용하려는 80포트가 이미 사용중이기 때문이라고 합니다.
더 정확한 에러 메세지는 nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)인데요.
여기에서는 왜 이런 상황이 발생하면서 nginx 작동 시작을 실패하는지 살펴보면서 문제 해결 방법엔 무엇이 있는지 살펴보도록 하겠습니다.
Nginx 웹서버 작동 실패 메세지
아래는 오늘 제 서버가 작동이 되지 않아 systemctl status nginx.service 명령으로 확인하니 아래와 같은 메세지가 뜹니다.
:~# systemctl status nginx.service
● nginx.service - nginx - high performance web server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
Active:<strong> failed</strong> (Result: exit-code) since Mon 2020-07-27 18:58:53 KST; 11s ago
Docs: http://nginx.org/en/docs/
Process: 34135 ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf (code=exited, status=1/FAILURE)
Jul 27 18:58:51 happist.com systemd[1]: Starting nginx - high performance web server…
Jul 27 18:58:51 happist.com nginx[34135]: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
Jul 27 18:58:51 happist.com nginx[34135]: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
Jul 27 18:58:52 happist.com nginx[34135]: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
Jul 27 18:58:52 happist.com nginx[34135]: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
Jul 27 18:58:53 happist.com nginx[34135]: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
Jul 27 18:58:53 happist.com nginx[34135]: nginx: [emerg] still could not bind()
Jul 27 18:58:53 happist.com systemd[1]: nginx.service: Control process exited, code=exited, status=1/FAILURE
Jul 27 18:58:53 happist.com systemd[1]: <strong><span style="color: #fcb900;" class="ugb-highlight">nginx.service: Failed with result 'exit-code'.</span></strong>
Jul 27 18:58:53 happist.com systemd[1]: <strong><span style="color: #cf2e2e;" class="ugb-highlight">Failed to start nginx - high performance web server.</span></strong>
Code language: PHP (php)
이러한 현상은 주로 서버를 다시 부팅 시키는 경우 종종 나타납니다. 한번 구동에 성공한 경우엔 service nginx restart와 같이 nginx를 다시 구동시키는 경우 아직 문제를 발견하지는 못했습니다.
이러한 현상은 예전 우분투 18.04를 사용하던 시절에는 거의 나타나지 않았지만 우분투 20.04로 업그레이드 한후에 종종 나타나는 현상인 것을 보니 우부투 20.04의 일시적인 현상으로 추정합니다.
단기 해결 방안
이렇게 서버를 재구동시킬시 80 포트르 다른 어플리케이션이 선점하는 문제는 아래와 같은 apache2 사용 중지시킴으로써 대부분 해결 가능했습니다.
즉 아래와 같은 명령을 활용합니다.
sudo /etc/init.d/apache2 stop
sudo service nginx restart
Code language: PHP (php)
이렇게 apache2 stop 명령으로 대부분 문제는 해결됩니다.
장기적이고 근원적인 문제
이렇게 서버가 새롭게 부팅 문제가 발생 확률이 높아지면 서버 운영 시 위험도가 크게 높아집니다.
서버 운영 시 서버를 자동으로 리부팅 시키는 경우가 있을 수 밖에 없습니다. 예를들어 중요한 보안 업그레이드가 발생 시 보안 업데이트가 적용되기 위해서는 서버 리부팅이 필수적입니다.
그런데 서버 리부팅 시 웹서버를 구동시킬 수 없는 문제가 발생한다면 서버 운영에 큰 지장을 받을 수 있고 안정적인 서버 운영에 어려워집니다.
그러면 왜 이런 문제가 발생하는 것일까요?
구글링을 통해서 왜 이런 문제가 발생하는지 그 원을 찾아 보았지만 뚜렸한 답을 찾을 수는 없었습니다. 다만 아래와 같은 몇가지 요인을 추정할 수는 있습니다.
- 80 포트를 다른 어플리케이션이 선점하는 문제는 apache2와 연관이 깊다.
이렇게 판단하는 이유는 apsche2 stop 명령어로 대부분 문제가 해결되기 때문이다. - 예전엔 이런 문제가 많지 않았지만 근래 Certbot이 업그레이드되면서 이런 문제 발생이 증가했다고 이야기 있다.
Certbot 설치하면서 알게 모르게 apache2를 구동시키는 경우가 있는 게 아닐까하는 합리적인 의심을 가져 본다.
결국 Nginx 웹서버를 사용하고는 있지만 기본적으로 apache2를 설치되어 있고, 어떤 연유에서인지 모르지만 apache2가 먼저 구동되면서 80포트를 차지하는 것이 아닐까 싶습니다.
그러면 이 apache2를 어떻게 해야할까요? 여기에는 2가지 방법이 있다고 보여집니다.
apache2 포트를 80이 아닌 다른 것으로 변경
첫번째 방법으로 apache2가 사용하는 port를 80아 아닌 다른 포트로 변경하는 것입니다.
어째피 Nginx 웹서버에서는 apache2를 사용할 일이 거의 없고 apache2와 nginx가 포트를 공유할 수 없도록 apache2 포트를 변경해주면 될 듯 합니다.
apache2 포트 설정은 /etc/apache2 폴더에 있는 ports.conf 파일에서 정의하고 있습니다.
# If you just change the port or add more ports here, you will likely also
# have to change the VirtualHost statement in
# /etc/apache2/sites-enabled/000-default.conf
Listen 70 # 80에서 70으로 변경
<IfModule ssl_module>
Listen 443
</IfModule>
<IfModule mod_gnutls.c>
Listen 443
</IfModule>
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
Code language: PHP (php)
apache2를 삭제, 온전히 nginx만으로 운영
아니면 nginx 웹서버에서 apache2는 거의 사용하지 않기 때문에 이를 삭제하는 것입니다.
이는 아래와 같은 명령어를 사용합니다.
sudo apt-get --purge autoremove apache2
Code language: PHP (php)
그러면 아래와 같이 apache2와 관련된 패키지들이 삭제되며 73메가 정도 용량을 확보할 수 있다는 메세지를 내면서 계속할지 질문을 합니다.
~# sudo apt-get --purge autoremove apache2
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following packages will be REMOVED:
apache2* apache2-data* apache2-utils* libllvm9* lockfile-progs* sendmail-base* sendmail-cf* sensible-mda*
0 upgraded, 0 newly installed, 8 to remove and 1 not upgraded.
After this operation, 73.0 MB disk space will be freed.
Do you want to continue? [Y/n]
Code language: PHP (php)
계속한다는 의미에서 Y를 누르면 삭제 작업이 진행됩니다.
(Reading database ... 145477 files and directories currently installed.)
Removing apache2 (2.4.41-4ubuntu3) ...
Removing apache2-data (2.4.41-4ubuntu3) ...
Removing apache2-utils (2.4.41-4ubuntu3) ...
Removing libllvm9:amd64 (1:9.0.1-12) ...
Removing sendmail-base (8.15.2-18) ...
Cleaning up the queues...done.
Removing lockfile-progs (0.1.18) ...
Removing sendmail-cf (8.15.2-18) ...
Removing sensible-mda (8.15.2-18) ...
Processing triggers for man-db (2.9.1-1) ...
Processing triggers for libc-bin (2.31-0ubuntu9) ...
(Reading database ... 144728 files and directories currently installed.)
Purging configuration files for sendmail-cf (8.15.2-18) ...
Purging configuration files for apache2 (2.4.41-4ubuntu3) ...
Purging configuration files for sendmail-base (8.15.2-18) ...
Processing triggers for systemd (245.4-4ubuntu3.2) ...
Code language: PHP (php)
이렇게 apache2가 모두 삭제되면 nginx를 다시 구동합니다.
sudo service nginx restart
Code language: PHP (php)
마치며
그러나 이렇게 apache2를 삭제하고도 이런 문제가 몇번 더 발생했기 때문에 위에서 제시한 apache2 삭제는 해결책은 아닌 것으로 판단하고 있습니다.
또한 아래와 같이 apache2 실행을 중단 시키는 것도 먹히지 않는 경우를 만났기 때문에 완전한 해결책도 아닌 것으로 판단 합니다.
sudo /etc/init.d/apache2 stop
sudo service nginx restart
Code language: PHP (php)
그래서 최종적으로는 fuser 명령어로 80포트 사용된 메모리를 전부 죽여버리고 다시 nginx를 실행하는 방법을 사용하기로 했습니다.
fuser -k 80/tcp
/etc/init.d/nginx start
Code language: PHP (php)