Tengo un servidor web creado con golang. Funciona con éxito cuando lo pruebo localmente.
Sin embargo, cuando construyo una imagen acoplable para mi servidor web, no puede conectarse a un contenedor de Postgres en ejecución.
Aquí está mi docker-compose.yml
:
version: '2' services: go: image: golang:1.7 volumes: - ./:/server/http ports: - "80:8080" links: - postgres - mongodb - redis environment: DEBUG: 'true' PORT: '8080' postgres: image: onjin/alpine-postgres:9.5 restart: unless-stopped ports: - "5432:5432" environment: LC_ALL: C.UTF-8 POSTGRES_USER: user POSTGRES_PASSWORD: pass POSTGRES_DB: mydb mongodb: image: mvertes/alpine-mongo:3.2.3 restart: unless-stopped ports: - "27017:27017" redis: image: sickp/alpine-redis:3.2.2 restart: unless-stopped ports: - "6379:6379"
Mi Dockerfile
:
FROM golang:1.7 RUN mkdir -p /home/app WORKDIR /home/app COPY . /home/app RUN make deps && make ENTRYPOINT ["./bin/api-test"] EXPOSE 8080
La cadena de conexión de Postgres que estoy usando:
postgresql://user:pass@host/mydb?sslmode=disable
Para host, probé localhost
y devuelve el siguiente error:
dial tcp [::1]:5432: getsockopt: connection refused
Intenté postgres
y me devuelve lo siguiente:
dial tcp 202.71.99.194:5432: getsockopt: connection refused
Probé la dirección IP que obtengo al ejecutar este comando que devuelve 172.19.0.3
:
docker inspect apitest_postgres_1 | grep IPAddress
donde apitest_postgres_1
es el nombre del contenedor de Postgres. También devolvió este error:
dial tcp 172.19.0.3:5432: getsockopt: connection timed out
¿Puedes decirme lo que me estoy perdiendo aquí? No tengo experiencia con la ventana acoplable y esto llevó mucho tiempo investigando para encontrar una solución.
Editar: ejecuto mi ventana acoplable golang usando este comando:
docker run --env-file ./example.env --rm -it -p 8080:8080 api-test
example.env
es el archivo que contiene mi entorno vars.
Edición 2: cambié la cadena de conexión a lo siguiente:
postgresql://user:pass@postgres:5432?sslmode=disable
Devuelve el siguiente error:
dial tcp: lookup postgres on 192.168.65.1:53: no such host
Tengo la idea de que mi mac es el problema aquí. Mi DNS predeterminado es 8.8.8.8
, lo que no debería ser un problema.
Parece que estás tirando de la imagen en lugar de construir tu propia imagen.
En lugar de image: golang:1.7
, reemplácelo con build: .
para construir y usar su Dockerfile
.
También es posible que deba pasar las variables de entorno de postgres DB_HOST
, DB_USER
, DB_PASS
, etc. Puede lograrlo pero creando, por ejemplo, un archivo docker.env
y luego agregue env_file
en su archivo go app docker-compose.yml
:
Ejemplo docker.env:
DB_HOST=postgres DB_USER=user DB_PASS=pass DB_NAME=mydb
Docker-compose.yml corregido:
version: '2' services: app: build: . volumes: - ./:/server/http ports: - "80:8080" links: - postgres - mongodb - redis environment: DEBUG: 'true' PORT: '8080' env_file: - docker.env postgres: image: onjin/alpine-postgres:9.5 restart: unless-stopped ports: - "5432:5432" environment: LC_ALL: C.UTF-8 POSTGRES_USER: user POSTGRES_PASSWORD: pass POSTGRES_DB: mydb mongodb: image: mvertes/alpine-mongo:3.2.3 restart: unless-stopped ports: - "27017:27017" redis: image: sickp/alpine-redis:3.2.2 restart: unless-stopped ports: - "6379:6379"
Para establecer una conexión con postgres en docker compose, debe reemplazar localhost o 127.0.0.1 o postgres en su cadena de conexión con el nombre del contenedor que se menciona en su archivo de composición de docker.
Por ejemplo, en su archivo docker-compose.yaml cree una base de datos como esta:
db: container_name: composepostgres image: postgres environment:
y luego, en su código al crear su cadena de conexión, evite usar 127.0.0.1
o localhost
o postgres
, y en su lugar use composepostgres
en su lugar.
Si no lo hace, se enfrentará a dial tcp 127.0.0.1:5432: connect: connection refused
.
Eche un vistazo a esta documentación: https://docs.docker.com/engine/userguide/networking/default_network/configure-dns/
Luego, con respecto a los enlaces en su archivo docker-compose, reemplace "host" por "postgres" en su cadena de conexión:
postgresql://user:pass@postgres/mydb?sslmode=disable
Deje que el servidor DNS incorporado haga el trabajo de mapeo porque la dirección IP puede cambiar cada vez que vuelva a crear el contenedor.
Además, asegúrese de que Postgres permita la conexión (tal vez limitada a localhost)