저는 docker-compose를 사용하여 일부 DB와 시더가 포함된 API를 설정합니다. 며칠 전까지만 해도 모든 것이 매력적으로 작동했지만 이제는 더 이상 DB를 시드할 수 없습니다.
여기 내 예가 있습니다.docker-compose.yml파일:
version: '3'
services:
api:
image: <API image>
ports: {API_PORT}:5000 //Flask's default port
depends_on:
- db
db:
image: <DB image>
ports: {DB_PORT}:27017 //MongoDB Default port
db-seed:
image: <seeder image>
// pretty classic docker-compose file, nothing fancy
파종기는 다음을 사용합니다.도커 네트워크API 컨테이너에 액세스하려면(http://api:80/) 그리고 씨앗을 뿌리세요. 그러나 Python으로 작성된 시더 스크립트는 이제 API 컨테이너에 연결할 때 오류를 반환합니다.
$> docker-compose up db-seed
<LOT OF ERRORS>...
requests.exceptions.ConnectionError: HTTPConnectionPool(host='api', port=80): Max retries exceeded with url: /ping (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7f65e78a4310>: Failed to establish a new connection: [Errno 111] Connection refused'))
시더 컨테이너가 DB 컨테이너에 접근할 수 없는 것 같습니다. 이 오류의 원인은 무엇입니까? 어떻게 해결할 수 있나요?
여기에도커 네트워크 검사내 네트워크:
[{ "Name": "staging-sensei-api_default", "Id": "b5bd162d27f9a1addaacf1b0f2c09ad799d3ae195cc6e8c9cbb54bfffc27651c", "Created": "2019-07-22T14:18:05.080114521Z", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": null, "Config": [ { "Subnet": "172.26.0.0/16", "Gateway": "172.26.0.1" } ] }, "Internal": false, "Attachable": true, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": { "08672fe92d72b111f1a006a2ff20e885ef395a420525953b696672753cb73ff7": {
"Name": "com.frcyber.sensei.elasticsearch",
"EndpointID": "7ba9a1af1af5635d22c9cbd38fad8be222f351e5c0013f0280e2879cdd6e9e40",
"MacAddress": "02:42:ac:1a:00:03",
"IPv4Address": "172.26.0.3/16",
"IPv6Address": ""
},
"364f873d069e4ecd371cdd99ca952d1469ee875aacbf9ee2227bbf25ab65d841": {
"Name": "com.frcyber.sensei.api",
"EndpointID": "e5a3f4cd2099aff2a04efdeb7a5c5d0a8ade4248b76df048f20a8a75bf85ddba",
"MacAddress": "02:42:ac:1a:00:04",
"IPv4Address": "172.26.0.4/16",
"IPv6Address": ""
},
"f4bfaf323a8c8c6300156d3091ec70f091fc3492175bfa00faa1717e4f83d2a2": {
"Name": "com.frcyber.sensei.mongodb",
"EndpointID": "b5df4e0d3721ffe5cd28ce55f642e6a0bc7f5be1a12cc49bb2eb12a58eb82e7a",
"MacAddress": "02:42:ac:1a:00:02",
"IPv4Address": "172.26.0.2/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {
"com.docker.compose.network": "default",
"com.docker.compose.project": "staging-sensei-api",
"com.docker.compose.version": "1.24.0"
}
}
]
또한 다음과 같은 경우에도 작동한다는 것을 알았습니다.API_PORT5000으로 설정됩니다.
api:
ports: 5000:5000
답변1
특정 경우에 작동한다는 점을 고려하면 다음과 같습니다.
그리고 API_PORT를 5000으로 설정해야 작동하는 것으로 확인했습니다.
api: ports: 5000:5000
문제는 도커 측이 아니라 프로젝트 설정 방법에 있다고 제안합니다. 이 제안은 내 부분의 가정을 기반으로 합니다. 귀하의 db-seeder 컨테이너는 API_PORT
api 컨테이너에 연결하기 위해 포트로 값을 사용합니다(귀하의 게시물에 명확하게 정의되어 있지 않으므로 다음과 같이 가정하겠습니다).
Python 오류가 "api"
호스트로 표시되므로 연결을 시도하고 있으며 DNS 측면에서는 출력에 따라 IP 172.26.0.4와 동일합니다 docker network inspect
. 이 IP에서 컨테이너는 API_PORT
의 값에 관계없이 포트 5000에서 수신 대기합니다(호스트 API_PORT
포트를 항상 컨테이너의 5000에 바인딩하므로 docker-compose에 따라).
이상한 점은 이전에 작동했다고 말씀하셨는데, API_PORT
5000을 사용하는 경우를 제외하고는 그런 일이 발생해서는 안 된다는 것입니다.
다른 포트의 Docker 네트워크 내부에 연결하려면 바인딩할 호스트의 포트뿐만 아니라 빌드 또는 런타임 시 컨테이너의 내용을 변경해야 합니다.
추가: "구성 가능성"의 예
당신의docker-compose
version: '3'
services:
api:
image: <API image>
ports: "80:${API_PORT:-5000}" //Flask's default port
depends_on:
- db
environment:
- DB_PORT=${DB_PORT:-27017}
- API_PORT=${API_PORT:-5000}
db:
image: mongo:latest
command: --port ${DB_PORT:-27017}
db-seed:
image: <seeder image>
environment:
- API_PORT=${API_PORT:5000}
이는 DB 포트를 호스트 외부에 노출시키지 않습니다. 셸 환경(또는 .env 파일)에서 API_PORT 및 DB_PORT 값을 모두 검색하고 다음과 같이 사용해야 합니다.
- 다음을 사용하여 API에 연결합니다.
http(s)://api:$API_PORT
- 다음을 사용하여 몽고에 연결하십시오.
db:$DB_PORT
- API_PORT를 사용하여 프로덕션(예 : API 컨테이너의 스크립트
uwsgi
끝)에서 API에 사용하는 CGI 서버를 시작합니다.ENTRYPOINT
# Some other config / checks / setup at runtime
exec uwsgi --port "$API_PORT" [ OTHER_OPTIONS ... ] path/to/your/application.py