api | panic: dial tcp: lookup db-mysql: Try again

c3frrgcw  于 2022-12-22  发布在  Mysql
关注(0)|答案(1)|浏览(165)

I have two containers, one of my api in golang and the other of my mysql database... both go up correctly, but when the api connects to the container, I keep getting this try again error. I had adapted the code to try again and it works, but all the operations I perform give the same problem, so I suppose there is something wrong and I don't know what it could be. Can you help me?
As mentioned above, I adapted the code to keep trying until it works, but as it gives an error in all operations, it is kind of impracticable to adapt it to try until it works in all operations.
Here are my files:

version: '3.3'

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: api
    ports:
      - "8080:8080"
    env_file:
      - .env
    depends_on:
      - db
    command: ["/app/main"]
  db:
    image: mysql:5.7
    container_name: db-mysql
    restart: always
    env_file:
      - .env
    networks:
      - mysql-net
    ports:
      - "3306:3306"
    expose:
      - 3306
    volumes:
      - my-db:/var/lib/mysql
      - ./init:/docker-entrypoint-initdb.d/

networks:
  mysql-net:
    driver:  bridge

volumes:
  my-db:
# Build stage
FROM golang:1.19-alpine3.16 AS builder
WORKDIR /app
COPY . .
RUN go build -o main cmd/server/main.go

# Run stage
FROM alpine:3.16
WORKDIR /app
COPY --from=builder /app/main .
COPY .env .

EXPOSE 8080
CMD [ "/app/main" ]

This is the part I get the error:

err = db.Ping()
    if err != nil {
        panic(err)
    }
y53ybaqx

y53ybaqx1#

Your containers don't have any networks: in common. Your application is on the Compose-provided default network, but the database is on a separate mysql-net network. Since they're not on the same network, they can't talk to each other.
Compose provides a network named default for you and for most application this works fine. The easiest thing to do here is to delete all of the networks: blocks from the entire file.
Once you're doing that cleanup, there are several other things you can simplify. There's a shorter form of build: if you're using the standard Dockerfile name; you don't need to manually specify container_name: or to repeat the image's command: ; the obsolete expose: option does nothing and can be safely removed. This would leave you with:

version: '3.8'

services:
  app:
    build: .
    ports:
      - "8080:8080"
    env_file:
      - .env  # setting MYSQL_HOST=db
    depends_on:
      - db

  db:
    image: mysql:5.7
    restart: always
    env_file:
      - .env
    ports:
      - "3306:3306"
    volumes:
      - my-db:/var/lib/mysql
      - ./init:/docker-entrypoint-initdb.d/

volumes:
  my-db:

I note one further change here. Both the container names and the Compose service names are usable as host names. Normally, though, you can do almost all operations using the Compose service name, and let Compose generate the underlying container name itself. This applies to host names for cross-container calls as well: in your .env file use the Compose service name db as a host name, rather than trying to set container_name: manually.

相关问题