502 Bad Gateway - nginx/1.14.0 (Ubuntu): 로컬에서 이미지를 찾을 수 없음 + 데몬 오류 응답

최근 Dell 서버를 한 위치에서 다른 위치로 이전했습니다. 메인 OS/VM 매니저는 Proxmox VE 5.3입니다. 여러 다른 VM들을 리버스 프록시하는 Nginx VM이 있으며, 그중 하나가 Discourse VM입니다.

새 라우터를 설정한 후, 일부 VM이 인터넷에 연결되도록 했습니다(SSL 인증서를 갱신할 필요조차 없었죠). 하지만 Discourse의 경우, 브라우저에서 Discourse에 접근하려고 할 때 502 Bad Gateway - nginx/1.14.0 (Ubuntu) 오류를 받고 있습니다.

이전에 이 오류를 받은 적이 있지만, 보통 아래 방법 중 하나로 해결되었습니다:

Discourse VM 재시작

여전히 브라우저에서 502 Bad Gateway - nginx/1.14.0 (Ubuntu) 오류가 발생합니다.

브라우저 쿠키 삭제 및 다른 브라우저 사용

혹시 제 쪽에 문제가 있는 건 아닌지 확인해 보았습니다 … 아닙니다. 여러 브라우저에서 동일한 502 Bad Gateway - nginx/1.14.0 (Ubuntu) 오류가 발생합니다.

Discourse 정리 및 디스크 공간 확인

처음 정리할 때 약 4GB의 데이터가 삭제되었습니다. 매우 놀랐습니다. 어쩌면 이것이 처음부터 문제를 일으킨 원인일까요? 어쨌든, 이제 Discourse를 정리하려고 하면:

> root@forum:/var/discourse# ./launcher cleanup
> WARNING! This will remove all stopped containers.
> Are you sure you want to continue? [y/N] y
> Total reclaimed space: 0B
> WARNING! This will remove all images without at least one container associated to them.
> Are you sure you want to continue? [y/N] y
> Total reclaimed space: 0B

또한 디스크 공간이 부족하지 않다는 점을 다시 강조합니다:

Git Pull

최신 상태입니다.

> root@forum:/var/discourse# git pull
> Already up to date.

Discourse 재시작

여기서 두 가지 오류를 발견했습니다:

> root@forum:/var/discourse# ./launcher restart app
> 
> WARNING: We are about to start downloading the Discourse base image
> This process may take anywhere between a few minutes to an hour, depending on your network speed
> 
> Please be patient
> 
> Unable to find image 'discourse/base:2.0.20191013-2320' locally
> /usr/bin/docker: Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers).
> See '/usr/bin/docker run --help'.
> Your Docker installation is not working correctly
> 
> See: `https://meta.discourse.org/t/docker-error-on-bootstrap/13657/18?u=sam`

제시된 링크를 확인했습니다. Git Pull 실행과 Discourse 재빌드(아래에서 제가 겪는 내용을 확인하실 수 있습니다)를 권장합니다. 또한 Docker “Hello World” 명령 실행을 제안합니다. 작동합니다(다만 일부 문제가 있는 것 같습니다?):

> root@forum:/var/discourse# docker run -it --rm hello-world
> Unable to find image 'hello-world:latest' locally
> latest: Pulling from library/hello-world
> 1b930d010525: Pull complete
> Digest: sha256:c3b4ada4687bbaa170745b3e4dd8ac3f194ca95b2d0518b417fb47e5879d9b5f
> Status: Downloaded newer image for hello-world:latest
> 
> Hello from Docker!
> This message shows that your installation appears to be working correctly.
> 
> To generate this message, Docker took the following steps:
>  1. The Docker client contacted the Docker daemon.
>  2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
>     (amd64)
>  3. The Docker daemon created a new container from that image which runs the
>     executable that produces the output you are currently reading.
>  4. The Docker daemon streamed that output to the Docker client, which sent it
>     to your terminal.
> 
> To try something more ambitious, you can run an Ubuntu container with:
>  $ docker run -it ubuntu bash
> 
> Share images, automate workflows, and more with a free Docker ID:
>  https://hub.docker.com/
> 
> For more examples and ideas, visit:
>  https://docs.docker.com/get-started/
> 
> failed to resize tty, using default size

그럼, 다음으로 Ubuntu Bash를 시도해 보았습니다 … 오류 발생:

> root@forum:/var/discourse# docker run -it ubuntu bash
> Unable to find image 'ubuntu:latest' locally
> docker: Error response from daemon: Get https://registry-1.docker.io/v2/library/ubuntu/manifests/latest: Get https://auth.docker.io/token?scope=repository%3Alibrary%2Fubuntu%3Apull&service=registry.docker.io: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers).
> See 'docker run --help'.

알고 있는 다른 방법들을 시도해 볼 시간입니다:

Discourse 중지 및 시작

재시작 시와 동일한 오류가 발생합니다:

> root@forum:/var/discourse# ./launcher stop app
> 
> WARNING: We are about to start downloading the Discourse base image
> This process may take anywhere between a few minutes to an hour, depending on your network speed
> 
> Please be patient
> 
> Unable to find image 'discourse/base:2.0.20191013-2320' locally
> /usr/bin/docker: Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers).
> See '/usr/bin/docker run --help'.
> Your Docker installation is not working correctly
> 
> See: `https://meta.discourse.org/t/docker-error-on-bootstrap/13657/18?u=sam`
> 
> root@forum:/var/discourse# ./launcher start app
> 
> WARNING: We are about to start downloading the Discourse base image
> This process may take anywhere between a few minutes to an hour, depending on your network speed
> 
> Please be patient
> 
> Unable to find image 'discourse/base:2.0.20191013-2320' locally
> /usr/bin/docker: Error response from daemon: Get https://registry-1.docker.io/v2/discourse/base/manifests/2.0.20191013-2320: Get https://auth.docker.io/token?scope=repository%3Adiscourse%2Fbase%3Apull&service=registry.docker.io: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers).
> See '/usr/bin/docker run --help'.
> Your Docker installation is not working correctly
> 
> See: `https://meta.discourse.org/t/docker-error-on-bootstrap/13657/18?u=sam`

Discourse 재빌드

그리고 다시 동일한 두 가지 오류가 발생합니다.

> root@forum:/var/discourse# ./launcher rebuild app
> 
> WARNING: We are about to start downloading the Discourse base image
> This process may take anywhere between a few minutes to an hour, depending on your network speed
> 
> Please be patient
> 
> Unable to find image 'discourse/base:2.0.20191013-2320' locally
> /usr/bin/docker: Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers).
> See '/usr/bin/docker run --help'.
> Your Docker installation is not working correctly
> 
> See: https://meta.discourse.org/t/docker-error-on-bootstrap/13657/18?u=sam

이전 백업에서 복원

서버를 이전하고 정리(약 4GB의 파일이 정리됨)를 하기 전 시점의 스냅샷이 있습니다. 위에서 언급한 정리를 제외하고, 위의 모든 것을 다시 시도해 보았지만 … 결과는 동일했으며, 브라우저에서는 여전히 502 Bad Gateway - nginx/1.14.0 (Ubuntu) 오류가 발생합니다. 그렇다면 이것은 정리와 아무 관련이 없는 것일까요?

Discourse를 사용하면서 이 두 가지 오류 중 하나도 경험해 본 적이 없습니다. 이러한 오류를 해결하고 브라우저에서 Discourse를 실행할 수 있도록 해 줄 수 있는 제안이 있을까요?

서버가 Docker Hub에 연결하여 대형 이미지를 다운로드할 수 없으며, 작은 hello world 이미지만 성공했습니다.

그렇다면 이 문제를 어떻게 해결해야 할까요? Docker 사용 경험이 많지 않아서 어디서부터 시작해야 할지 모르겠습니다.

제가 아는 Docker 관련 지식은 Discourse 설치에 포함된 명령어들뿐입니다(물론 제 경우 Discourse가 서드파티 클라우드가 아니라 제 서버의 VM에 설치되어 있으므로 수정이 필요합니다).

어떤 Docker 버전을 사용하고 계신가요 (docker info)?

https://registry-1.docker.io/v2/ 로의 연결을 설정하는 데 문제가 없는지 네트워크 스택을 확인해 볼 수 있을까요?

다음은 내 Docker 정보입니다:

root@forum:/var/discourse# docker info
Containers: 1
Running: 1
Paused: 0
Stopped: 0
Images: 3
Server Version: 18.09.5
Storage Driver: overlay2
Backing Filesystem: extfs
Supports d_type: true
Native Overlay Diff: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
Volume: local
Network: bridge host macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: bb71b10fd8f58240ca47fbb579b9d1028eea7c84
runc version: 2b18fe1d885ee5083ef9f0838fee39b62d653e30
init version: fec3683
Security Options:
apparmor
seccomp
Profile: default
Kernel Version: 4.15.0-69-generic
Operating System: Ubuntu 18.04.2 LTS
OSType: linux
Architecture: x86_64
CPUs: 2
Total Memory: 6.805GiB
Name: forum
ID: 2RRX:ZQIT:R5AK:WNPR:VJ6Z:2EBY:PFOL:W5RD:GL3X:RUQM:YLJ4:2L2X
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Registry: https://index.docker.io/v1/
Labels:
Experimental: false
Insecure Registries:
127.0.0.0/8
Live Restore Enabled: false
Product License: Community Engine

WARNING: No swap limit support

질문에 대해 말씀드리자면:

이것을 어떻게 하면 되나요?

@Falco 이 문제를 더 깊이 트러블슈팅해 보았는데, 오히려 더 혼란스러워졌습니다. 좋은 소식과 나쁜 소식이 있습니다:

좋은 소식

여러 번 Discourse Rebuild(./launcher rebuild app)을 수행한 후, 더 이상 Unable to find image 또는 Error response from daemon 오류가 발생하지 않습니다! Discourse를 시작/재시작할 때 오류가 표시되지 않습니다:

> root@forum:/var/discourse# ./launcher start app
> 
> .+ /usr/bin/docker run --shm-size=512m -d --restart=always -e LANG=en_US.UTF-8 -e RAILS_ENV=production -e UNICORN_WORKERS=4 -e UNICORN_SIDEKIQS=1 -e RUBY_GLOBAL_METHOD_CACHE_SIZE=131072 -e RUBY_GC_HEAP_GROWTH_MAX_SLOTS=40000 -e RUBY_GC_HEAP_INIT_SLOTS=400000 -e RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR=1.5 -e DISCOURSE_DB_SOCKET=/var/run/postgresql -e DISCOURSE_DB_HOST= -e DISCOURSE_DB_PORT= -e DISCOURSE_HOSTNAME=discourse.example.com -e DISCOURSE_DEVELOPER_EMAILS=admin@example.com,postmaster@example.com -e DISCOURSE_SMTP_ADDRESS=smtp.sparkpostmail.com -e DISCOURSE_SMTP_PORT=587 -e DISCOURSE_SMTP_USER_NAME=SMTP_Injection -e DISCOURSE_SMTP_PASSWORD=<HIDING-FOR-PRICACY> -e LETSENCRYPT_ACCOUNT_EMAIL=admin@example.com -h forum-app -e DOCKER_HOST_IP=100.17.0.1 --name app -t -p 8080:80 -p 8443:443 -p 2222:22 -v /var/discourse/shared/standalone:/shared -v /var/discourse/shared/standalone/log/var-log:/var/log --mac-address 02:96:f3:e6:e7:14 local_discourse/app /sbin/boot
> cebe89493bc79dab2c1716599629adfe3dc571c8659367e6ffa0d39b0e6d47af
> root@forum:/var/discourse# ./launcher restart app
> .+ /usr/bin/docker stop -t 10 app
> app
> 
> starting up existing container
> .+ /usr/bin/docker start app
> app

Docker도 실행 중입니다:
> root@forum:/var/discourse# systemctl status docker.service
> ● docker.service - Docker Application Container Engine
>    Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
>    Active: active (running) since Thu 2019-11-14 03:00:54 UTC; 17h ago
>      Docs: https://docs.docker.com
>  Main PID: 18721 (dockerd)
>     Tasks: 31
>    CGroup: /system.slice/docker.service
>            ├─ 1375 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 8443 -container-ip 172.17.0.2 -container-port 443
>            ├─ 1387 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 8080 -container-ip 172.17.0.2 -container-port 80
>            ├─ 1399 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 2222 -container-ip 172.17.0.2 -container-port 22
>            └─18721 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
> 
> Nov 14 20:13:26 forum dockerd[18721]: time="2019-11-14T20:13:26.430856242Z" level=info msg="ignoring event" module=libcontainerd namespace=moby topic=/tasks/delete type="*events.TaskDelete"
> Nov 14 20:13:28 forum dockerd[18721]: time="2019-11-14T20:13:28.597999379Z" level=info msg="ignoring event" module=libcontainerd namespace=moby topic=/tasks/delete type="*events.TaskDelete"
> Nov 14 20:13:30 forum dockerd[18721]: time="2019-11-14T20:13:30.862158413Z" level=info msg="ignoring event" module=libcontainerd namespace=moby topic=/tasks/delete type="*events.TaskDelete"
> Nov 14 20:13:32 forum dockerd[18721]: time="2019-11-14T20:13:32.978285148Z" level=info msg="ignoring event" module=libcontainerd namespace=moby topic=/tasks/delete type="*events.TaskDelete"
> Nov 14 20:13:35 forum dockerd[18721]: time="2019-11-14T20:13:35.105130149Z" level=info msg="ignoring event" module=libcontainerd namespace=moby topic=/tasks/delete type="*events.TaskDelete"
> Nov 14 20:13:37 forum dockerd[18721]: time="2019-11-14T20:13:37.151466214Z" level=info msg="ignoring event" module=libcontainerd namespace=moby topic=/tasks/delete type="*events.TaskDelete"
> Nov 14 20:13:39 forum dockerd[18721]: time="2019-11-14T20:13:39.024948159Z" level=info msg="ignoring event" module=libcontainerd namespace=moby topic=/tasks/delete type="*events.TaskDelete"
> Nov 14 20:14:05 forum dockerd[18721]: time="2019-11-14T20:14:05.179759938Z" level=info msg="ignoring event" module=libcontainerd namespace=moby topic=/tasks/delete type="*events.TaskDelete"
> Nov 14 20:14:16 forum dockerd[18721]: time="2019-11-14T20:14:16.078334393Z" level=info msg="Container cebe89493bc79dab2c1716599629adfe3dc571c8659367e6ffa0d39b0e6d47af failed to exit within
> Nov 14 20:14:16 forum dockerd[18721]: time="2019-11-14T20:14:16.281731176Z" level=info msg="ignoring event" module=libcontainerd namespace=moby topic=/tasks/delete type="*events.TaskDelete"

나쁜 소식

여러 브라우저에서 사이트를 열려고 하면 여전히 502 Bad Gateway - nginx/1.14.0 (Ubuntu) 오류가 발생합니다. 혹시 모르아서 캐시를 지우고 여러 브라우저를 시도해 보았지만 소용이 없습니다.

한 가지 발견한 것은 Discourse Cleanup을 시도하면 컨테이너가 꽤 많이 삭제된다는 것입니다:

> root@forum:/var/discourse# ./launcher cleanup
> WARNING! This will remove all stopped containers.
> Are you sure you want to continue? [y/N] y
> Total reclaimed space: 0B
> WARNING! This will remove all images without at least one container associated to them.
> Are you sure you want to continue? [y/N] y
> Deleted Images:
> untagged: hello-world:latest
> untagged: hello-world@sha256:c3b4ada4687bbaa170745b3e4dd8ac3f194ca95b2d0518b417fb47e5879d9b5f
> deleted: sha256:fce289e99eb9bca977dae136fbe2a82b6b7d4c372474c9235adc1741675f587e
> deleted: sha256:af0b15c8625bb1938f1d7b17081031f649fd14e6b233688eea3c5483994a66a3
> untagged: discourse/base:2.0.20191013-2320
> untagged: discourse/base@sha256:77e010342aa5111c8c3b81d80de7d4bdb229793d595bbe373992cdb8f86ef41f
> deleted: sha256:53b44681b65ee5e9a9cadc6bd34c6aa6f6bcbbbe6270e61669c50bcd655c6898
> deleted: sha256:939a3ac6d5627270ae02a9f9ea05c580589cec0afa019b7f296fdd43157dd3a0
> 
> Total reclaimed space: 452.2MB

이제 시작/재시작을 시도할 때마다 … 오류가 다시 나타납니다! Unable to find image 또는 Error response from daemon 오류 메시지가 사라졌던 시점으로 롤백했습니다. 분명히 컨테이너가 재구축되었고, 이미지 컨테이너를 정리하는 것이 문제를 일으키는 것 같습니다.

Docker가 손상된 경우(예: docker run ubuntu 실패) Discourse는 거의 확실히 작동하지 않습니다.

Docker 관련 특정 지원을 받으려면 https://forums.docker.com/ 에 게시글을 남겨보실 수 있습니다.

@Falco 네, 해당 명령을 실행하면 이전과 마찬가지로 Unable to find image locally와 Error response from daemon 오류가 발생합니다.

따라서 제안해 주신 대로 Docker 포럼에 새 주제를 만들었습니다. 아직 답변이 없네요, 아쉽습니다.

조금 더 뉴스를 전합니다:

좋은 소식

다시 /usr/bin/docker: Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers). 에러를 받지 않습니다!

docker run ubuntu 명령도 더 이상 에러를 보고하지 않습니다. @Falco, 제가 보아야 할 출력이 있는 건가요?

root@forum:/var/discourse# docker run ubuntu
root@forum:/var/discourse#

그렇다면 에러를 해결하기 위해 제가 무엇을 했을까요? 이 VM에서 사용하던 네임서버(DNS)를 Google Public DNS 서비스로 교체했습니다:
echo "nameserver 8.8.8.8">/etc/resolv.conf

다만, 위 명령은 VM 재시작 이후에 매번 실행해야 합니다(일시적인 해결책인 것 같습니다). 그렇지 않으면 ./launcher 명령을 실행할 때 두 가지 에러가 발생합니다. 그 후에는 에러가 하나(Unable to find image 'discourse/base:2.0.20191013-2320' locally)만 발생하지만, 명령은 정상적으로 처리되는 것처럼 보입니다:

root@forum:/var/discourse# ./launcher start app

WARNING: We are about to start downloading the Discourse base image
This process may take anywhere between a few minutes to an hour, depending on your network speed

Please be patient

Unable to find image 'discourse/base:2.0.20191013-2320' locally
2.0.20191013-2320: Pulling from discourse/base
Digest: sha256:77e010342aa5111c8c3b81d80de7d4bdb229793d595bbe373992cdb8f86ef41f
Status: Downloaded newer image for discourse/base:2.0.20191013-2320

starting up existing container
+ /usr/bin/docker start app
app

./launcher rebuild app도 에러 없이 실행되기를 바랍니다. 다음은 해당 명령의 출력 마지막 부분입니다(URL과 MAC 주소는 숨김):

+ /usr/bin/docker run --shm-size=512m -d --restart=always -e LANG=en_US.UTF-8 -e RAILS_ENV=production -e UNICORN_WORKERS=4 -e UNICORN_SIDEKIQS=1 -e RUBY_GLOBAL_METHOD_CACHE_SIZE=131072 -e RUBY_GC_HEAP_GROWTH_MAX_SLOTS=40000 -e RUBY_GC_HEAP_INIT_SLOTS=400000 -e RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR=1.5 -e DISCOURSE_DB_SOCKET=/var/run/postgresql -e DISCOURSE_DB_HOST= -e DISCOURSE_DB_PORT= -e DISCOURSE_HOSTNAME=discourse.domain.com -e DISCOURSE_DEVELOPER_EMAILS=admin@domain.com,postmaster@domain.com -e DISCOURSE_SMTP_ADDRESS=smtp.sparkpostmail.com -e DISCOURSE_SMTP_PORT=587 -e DISCOURSE_SMTP_USER_NAME=SMTP_Injection -e DISCOURSE_SMTP_PASSWORD=0d431cd177ce3d35833aa823d498eb57c7c4e99c -e LETSENCRYPT_ACCOUNT_EMAIL=admin@domain.com -h forum-app -e DOCKER_HOST_IP=172.17.0.1 --name app -t -p 8080:80 -p 8443:443 -p 2222:22 -v /var/discourse/shared/standalone:/shared -v /var/discourse/shared/standalone/log/var-log:/var/log --mac-address 00:00:00:00:00:01 local_discourse/app /sbin/boot
abb788d4a6fd301d88f129189a07a19c4a6bfc8554d43c555d3e3cd126374736

나쁜 소식

페이지에 접속을 시도할 때 여전히 502 Bad Gateway - nginx/1.14.0 (Ubuntu) 에러가 발생합니다.

다른 문제는 무엇일 수 있을까요? 조언이 있으신가요?

문제를 해결했습니다! 이제 브라우저에서 Discourse 포럼이 표시됩니다!

더 구체적으로 말씀드리면, Nginx 포럼의 Francis Day님이 제 문제를 해결해 주셨습니다! 결국 Nginx 쪽 문제였네요. 제가 한 작업은 다음과 같습니다:

  1. Nginx VM에 로그인했습니다.
  2. Discourse 설정 파일을 VIM으로 열었습니다: vim /etc/nginx/sites-available/discourse.conf
  3. 제 Discourse 설정 파일의 이전 모습입니다 (물론 평소 사용하는 도메인 이름은 사용하지 않았으며, 192.168.0.101 = Nginx VM, 192.168.0.104 = Discourse VM입니다).
  4. 변경한 부분은 단 하나뿐입니다: proxy_pass http://discourse.domainame.com:8080/;를 proxy_pass 192.168.0.104:8080/;로 변경했습니다. 즉, proxy_pass를 호스트명 대신 Discourse VM의 로컬 IP로 설정한 것입니다.
  5. 설정 파일을 저장한 후 Nginx를 재로드(systemctl reload nginx.service)하고 재시작(systemctl restart nginx.service)했습니다.
  6. 성공! Discourse URL을 새로고침하니 바로 접속되었습니다! Discourse를 재시작하거나 재빌드할 필요조차 없었습니다!

Nginx를 통해 Discourse를 리버스 프록시하는 과정은 꽤 까다로울 수 있으므로, 제가 작성한 내용이 누군가에게 도움이 되기를 바랍니다.