Utilizo Docker-Compose para configurar una API con algunas bases de datos y una sembradora. Todo funcionó a las mil maravillas hasta hace unos días pero ahora ya no puedo sembrar la base de datos.
He aquí un ejemplo de midocker-compose.ymlarchivo:
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
La sembradora utiliza elred acoplablepara acceder al contenedor API (http://api:80/) y sembrarlo. Sin embargo, el script del seeder (escrito en Python) ahora devuelve un error al intentar conectarse al contenedor 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'))
Parece que el contenedor de siembra no puede acceder al contenedor de base de datos. ¿Cuál podría ser la causa de este error? ¿Cómo podría solucionarlo?
Aquí esta lainspeccionar la red acoplablede mi red:
[{ "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"
}
}
]
Además, descubrí que funciona cuandoAPI_PORTse establece en 5000:
api:
ports: 5000:5000
Respuesta1
Considerando que funciona en un caso específico, es decir:
Además, descubrí que funciona cuando API_PORT está configurado en 5000
api: ports: 5000:5000
Sugeriría que el problema no está en el lado de Docker, sino en cómo configura su proyecto. Esta sugerencia se basa en una suposición de mi parte: su contenedor db-seeder usa el valor API_PORT
como puerto para conectarse al contenedor api (no está claramente definido en su publicación, asumiré que así es para lo siguiente).
Dado que su error de Python se muestra "api"
como el host al que está intentando conectarse, en cuanto a DNS, esto sería equivalente a IP 172.26.0.4, según su docker network inspect
resultado. En esta IP, el contenedor escucha en el puerto 5000, independientemente del API_PORT
valor de (según su docker-compose, ya que siempre vincula API_PORT
el puerto de su host al 5000 del contenedor).
Lo extraño es que dijiste que funcionó antes, lo cual no debería haber sido el caso, excepto si tuvieras API_PORT
5000.
Si desea conectarse dentro de la red acoplable en otro puerto, deberá cambiar algo en el contenedor, ya sea durante la compilación o en tiempo de ejecución, no solo el puerto del host al que se vincula.
Adición: ejemplo de "configurabilidad"
De tudocker-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}
Esto no expone su puerto db al exterior de su host. Necesitará recuperar los valores API_PORT y DB_PORT del entorno de su shell (o archivo .env) y usarlos de la siguiente manera:
- conectarse a la API usando
http(s)://api:$API_PORT
- conectarse al mongo usando
db:$DB_PORT
- Inicie el servidor cgi que usa para su API en producción (ejemplo para
uwsgi
) usando API_PORT, por ejemplo al final delENTRYPOINT
script de su contenedor de API:
# Some other config / checks / setup at runtime
exec uwsgi --port "$API_PORT" [ OTHER_OPTIONS ... ] path/to/your/application.py