8
respostas

[Bug] NÃO CONSIGO CONECTAR AO BANCO DE DADOS.

NÃO CONSIGO RODA MINHA IMAGEM ESTA DANDO ERRO NO BANCO DE DADOS

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

AGORA O CODIGO DE MEU DB.GO E DOCKERFILE E DOCKER COMPOSE: Insira aqui a descrição dessa imagem para ajudar na acessibilidade

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

8 respostas

Quem poder ajudar agradeço.

Olá, Levi. Tudo bem?

Para resolver esse problema, siga os passos:

  1. Primeiro baixe o arquivo wait-for-it.sh que eu disponibilizei em meu repositório do Github: wait-for-it.sh - Download direto

  2. Coloque esse arquivo na raiz do projeto na mesma pasta do arquivo docker-compose.yml:

Print do VSCode com o projeto aberto destacando o arquivo wait-for-it.sh

  1. Cole esse código no final do arquivo Dockerfile, lembrando que vai substituir a linha do CMD:

    COPY ./wait-for-it.sh /app/wait-for-it.sh
    RUN chmod +x /app/wait-for-it.sh
    
    # Muda o CMD para esperar o banco estar pronto
    CMD ["./wait-for-it.sh", "postgres:5432", "--", "go", "run", "main.go"]
    
    • O código completo do arquivo Dockerfile vai ficar assim:
      FROM golang:1.22
      
      EXPOSE 8080
      
      WORKDIR /app
      
      ENV PORT 8080
      ENV DB_HOST postgres
      ENV DB_USER root
      ENV DB_PASSWORD root
      ENV DB_NAME root
      ENV DB_PORT 5432
      
      COPY ./assets/ /app/assets/
      COPY ./controllers/ /app/controllers/
      COPY ./database/ /app/database/
      COPY ./models/ /app/models/
      COPY ./routes/ /app/routes/
      COPY ./templates/ /app/templates/
      COPY ./main.go /app/main.go
      COPY ./go.mod /app/go.mod
      COPY ./go.sum /app/go.sum
      
      COPY ./wait-for-it.sh /app/wait-for-it.sh
      RUN chmod +x /app/wait-for-it.sh
      
      # Muda o CMD para esperar o banco estar pronto
      CMD ["./wait-for-it.sh", "postgres:5432", "--", "go", "run", "main.go"]
      
  2. Rode o comando novamente:

    docker compose up --build
    
  • Dessa forma o serviço do App-1 vai esperar o banco, e conseguir conectar.

Espero ter ajudado. 

Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓.Bons Estudos!

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

AINDA NAO FUNCIONA MAN

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

Olá, Levi.

Tenta derrubar e subir de novo.

  • Derrubar com o comando:
    docker compose down
    
  • Em seguida subir novamente com o comando:
    docker compose up --build
    

Fala meu amigo tentei aqui e não deu certo irei te manda o repositorio dessa atividade que criei:

Talvez fique melhor de vc ver

https://github.com/andrezin123123/aula-docker-erro

Meu repositorio ai

Esta do mesmo jeito do meu localmente em minha pasta no pc

Algueeeemmmm?????

Opa Levi Lima Santana, tudo bem?

Revisei seu código, as dicas anteriores dadas aqui, e vi uma série de ajustes a serem feitos. Fiz um Pull Request no repositório que você disponibilizou aplicando as correções.

Mas mesmo fazendo isso, vou explicar aqui as mudanças que foram feitas, melhorias aplicadas, e outros ajustes feitos para que esse problema não exista, está bem?

Problema (Original)

O seu problema no inicio, não era por o postgres não estar rodando. O problema na verdade é por as variáveis de ambiente estarem na stage de build, ao invés de estarem na stage de production. As variáveis de ambiente são injetadas diretamente dentro da imagem de container, e cada stage é uma nova imagem. Essas variáveis não são herdadas. Sendo assim, para resolver seu problema de fato, bastava mover da linha 7 até a linha 11 do Dockerfile da última captura de tela enviada na postagem (não nas respostas, na postagem mesmo) para dentro do stage de production, que o problema já resolveria para execução usando o docker-compose e docker.

Uso de wait-for-it.sh

Quando iniciamos um container, e colocamos o depends_on no container seguinte, estamos definindo de forma explicita que queremos uma ordem de subida dos containers. Entretanto, um container é apenas um isolamento. Usar o depends_on passando uma lista de services, apenas garante que o container seja iniciado em uma ordem, e que ele não inicie caso o container ao qual ele depende tenha falhado.

A proposta do wait-for-it.sh é boa para validar se a aplicação dentro do container alvo iniciou (pode ser que o container inicie, mas a aplicação ainda não). Entretanto, ela é custosa, pois você está fazendo uma validação externa a ele, o que não informa de fato se o problema está na aplicação dentro do container que não iniciou, ou se está dentro da rede overlay que o docker criou, por exemplo. Para esse tipo de validação, é preferível usar soluções que ficam o mais próximo possível da aplicação. No caso das versões mais recentes do docker-compose, após a unificação dos esquemas das versões 2.x e 3.x, agora sob o COMPOSE_SPEC, podemos definir os healthchecks nos documentos do docker-compose, bem como enriquecer o depends_on para aguardar a aplicação estar healthy.

No caso específico, existe um binário dentro da imagem do postgres que permite usarmos para esse tipo de validação. O código final do postgres ficou assim:

services:
  postgres:
    image: "postgres"
    environment:
      - POSTGRES_USER=root
      - POSTGRES_PASSWORD=root
      - POSTGRES_DB=root
    ports:
      - 5432:5432
    volumes:
      - ./postgres-data:/var/lib/postgresql/data
    healthcheck:
      test: /usr/bin/pg_isready
      interval: 10s
      timeout: 5s
      retries: 5

Além disso, precisamos enriquecer o depends_on da aplicação, informando que o postgres precisa estar healthy antes de iniciar a subida de container. O código final do app ficou assim:

  app:
    build: 
        context: .
        target: production
    ports:
      - 8080:8080
    depends_on:
      postgres:
        condition: service_healthy

Caso queira ver outras opções, tem mais informações sobre na documentação do docker.

Erro no stage production

Sobre o último erro que aconteceu, é decorrente da modificação do Dockerfile, com base em uma das sugestões dadas anteriormente. O target é usado em casos que temos um Dockerfile com multi-stage build, para definirmos qual das labels queremos usar como imagem final, já que estamos criando mais de uma imagem usando um arquivo apenas. Quando não existe essa label definida no FROM, e você usa a chave de target com valor production dentro do build, ele dá esse erro por não encontrar qual daquelas etapas vai gerar a imagem final para ele executar.

Outros erros

Olhando para o seu repositório git, e vendo a parte de CI, notei que você faz um teste que reproduz um erro parecido ao realizar ele em sua máquina. A etapa que falha na action é a etapa de Test: Link da Execução da Action

Entretanto, o erro aqui, é referente as secrets não terem sido criadas com os valores de host, user, password, port e database, do banco de dados iniciado na etapa anterior. Para que a etapa do CI funcione corretamente, ela precisa ter essas variáveis de ambiente definidas via secrets.

Caso queira aprender mais sobre secrets, tem mais explicações na documentaço do Github.

Espero ter ajudado :)

Fala meu amigo deu certo aqui porem na minha pipeline de integração ocorre um erro que vc me falo dos secrets eu ja coloquei porem ainda da erro

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

E a senha e o nome e o mesmo das variaveis de ambiente.

Insira aqui a descrição dessa imagem para ajudar na acessibilidade