Search code examples
mysqldockerdockerfilepercona

Connecting to percona docker from a java docker container


I know there have been many similar questions, but none of them are what I want. I'm following this because I specifically need 5.5, at least for now. My java project (which accesses mysql) is in a container I built with

docker build -t projectname-testing .

The Dockerfile is pretty standard, it just copies over a built tarball and extracts it to a specific folder. The CMD is a shell script run_dev_server.sh that just launches the server with dev configurations rather than production ones.

I created a percona docker container with the command given in the link with

docker run --name projectname-mysql-server -e MYSQL_ROOT_PASSWORD="" -d percona:5.5

So now the way I see it, just need the link the two as mentioned in the link:

docker run -p 3306:3306 --name projectname-local --link projectname-mysql-server projectname-testing

Which gives me

docker: Error response from daemon: Cannot link to a non running container: /projectname-mysql-server AS /projectname-local/projectname-mysql-server. ERRO[0000] error getting events from daemon: net/http: request canceled

Which isn't very helpful and doesn't tell me what happened. Am I understanding this process wrong? What should I be doing?


Solution

  • First of all, I would recommend using the official Percona docker image from Docker Hub, instead of building your own image. The official image has a 5.5 version; https://hub.docker.com/_/percona/ You can either extend this image if you need specific changes (such as a custom configuration), for example;

    FROM percona:5.5
    COPY my-config.cnf /etc/mysql/conf.d/
    

    Important: I notice you are publishing port 3306 (-p 3306:3306). Publishing a port makes it publicly accessible on the host's network-interface. You should only do this if you have external software that needs to connect to the database. If only your application needs access to the database, publishing the port is not needed, because containers can connect with eachother through the docker container-container network, which is "private" and not reachable from outside the host.

    The --link option on the default network is a legacy option that is still around for backward compatibility, but should not be used for most situations. The --link option has a number of limitations;

    • legacy links are not dynamic; it's not possible to replace a linked container without re-creating all containers linked to that container
    • restarting a linked container can break the link, with no option to re-establish a link
    • legacy links are uni-directional
    • environment variables are shared between containers, which can easily lead to leaking (e.g.) credentials to other containers.

    Docker 1.9 introduced custom docker networks, which allows

    A simple example;

    create a network for your application;

    docker network create mynet
    

    create a database container, and attach it to the network; there is no need to publish its ports for other containers to connect to it. (I'm using an nginx image here, just to illustrate the concept);

    docker run -d --name db --network mynet nginx:alpine
    

    create an "application" container and attach it to the same network; doing so allows it to communicate with the db container over that network;

    docker run -dit --name app --network mynet alpine sh
    

    The application container can now connect to the db container, using its name as hostname (db); to illustrate this, open a shell in the app container, install curl and connect to http://db:80;

    docker exec -it app sh
    
    / # apk add --no-cache curl
    fetch http://dl-cdn.alpinelinux.org/alpine/v3.5/main/x86_64/APKINDEX.tar.gz
    fetch http://dl-cdn.alpinelinux.org/alpine/v3.5/community/x86_64/APKINDEX.tar.gz
    (1/4) Installing ca-certificates (20161130-r1)
    (2/4) Installing libssh2 (1.7.0-r2)
    (3/4) Installing libcurl (7.52.1-r3)
    (4/4) Installing curl (7.52.1-r3)
    Executing busybox-1.25.1-r0.trigger
    Executing ca-certificates-20161130-r1.trigger
    OK: 5 MiB in 15 packages    
    
    / # curl http://db:80
    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx!</title>
    

    You can read more about networks (also how to dynamically attach and detach a container from a network) in the []"docker container networking" section of the documentation](https://docs.docker.com/engine/userguide/networking/)