Unable to connect mysql from docker container?

前端 未结 2 1454
野趣味
野趣味 2020-12-06 13:18

I have created a docker-compose file it has two services with Go and Mysql. It creates container for go and mysql. Now i am running code which try

相关标签:
2条回答
  • 2020-12-06 13:37

    First, if you are using latest version of docker compose you don't need the link argument in you app service. I quote the docker compose documentation Warning: The --link flag is a legacy feature of Docker. It may eventually be removed. Unless you absolutely need to continue using it, https://docs.docker.com/compose/compose-file/#links

    I think the solution is to use the networks argument. This create a docker network and add each service to it.

    Try this

    version: "2"
    services:
      app:
        container_name: golang
        restart: always
        build: .
        ports:
          - "49160:8800"
        networks:
         - my_network
        depends_on:
          - "mysql" 
    
      mysql:
        image: mysql
        container_name: mysql
        volumes:
          - dbdata:/var/lib/mysql
        restart: always
        networks:
         - my_network
        environment:
          - MYSQL_ROOT_PASSWORD=root
          - MYSQL_DATABASE=testDB
          - MYSQL_USER=root
          - MYSQL_PASSWORD=root
        ports:
          - "3307:3306"
    volumes:
      dbdata:
    networks:
      my_network:
        driver: bridge
    

    By the way, if you only connect to Mysql from your app service you don't need to expose the mysql port. If the containers runs in the same network they can reach all ports inside this network.

    If my example doesn't works try this run the docker compose and next go into the app container using docker container exec -it CONTAINER_NAME bash Install ping in order to test connection and then run ping mysql.

    0 讨论(0)
  • 2020-12-06 13:45

    depends_on is not a verification that MySQL is actually ready to receive connections. It will start the second container once the database container is running regardless it was ready for connections or not which could lead to such an issue with your application as it expects the database to be ready which might not be true.

    Quoted from the documentation:

    depends_on does not wait for db and redis to be “ready” before starting web - only until they have been started.

    There are many tools/scripts that can be used to solve this issue like wait-for which sh compatible in case your image based on Alpine for example (You can use wait-for-it if you have bash in your image)

    All you have to do is to add the script to your image through Dockerfile then use this command in docker-compose.yml for the service that you want to make it wait for the database.

    What comes after -- is the command that you would normally use to start your application

    version: "2"
    services:
      app:
        container_name: golang
        ...
            command: ["./wait-for", "mysql:3306", "--", "go", "run", "myapplication"]
        links:
          - "mysql"
        depends_on:
          - "mysql" 
    
      mysql:
        image: mysql
      ...
    

    I have removed some parts from the docker-compose for easier readability.

    Modify this part go run myapplication with the CMD of your golang image.

    See Controlling startup order for more on this problem and strategies for solving it.


    Another issue that will rise after you solve the connection issue will be as the following:

    Setting MYSQL_USER with root value will cause a failure in MySQL with this error message:

    ERROR 1396 (HY000) at line 1: Operation CREATE USER failed for 'root'@'%'
    

    This is because this user already exist in the database and it tries to create another. if you need to use the root user itself you can use only this variable MYSQL_ROOT_PASSWORD or change the value of MYSQL_USER so you can securely use it in your application instead of the root user.

    Update: In case you are getting not found and the path was correct, you might need to write the command as below:

    command: sh -c "./wait-for mysql:3306 -- go run myapplication"
    
    0 讨论(0)
提交回复
热议问题