DEV Community

Cover image for Learn Docker - from the beginning, part III databases and linking

Learn Docker - from the beginning, part III databases and linking

Chris Noring on February 15, 2019

Follow me on Twitter, happy to take your suggestions on topics or improvements /Chris TLDR; this is somewhat of a long read but there is mic drop...
Collapse
 
moinuddin14 profile image
Khaja Moinuddin Mohammed

Hi @chris can you add this line before "Let’s try to run our node app.js command again and this time we get this: node app.js",

create table with the name Customer before running node app.js with below command

CREATE DATABASE Customers;

without creating the db, i was getting error, but after creating the db it resolved.

I ain't sure if this is how it needs to be done, as am no expert with sql dbs. Please correct me if am wrong.

Collapse
 
bijoy26 profile image
Anjum Rashid

Fell into the same trap as well. Thanks for pointing it out.

Collapse
 
dragane profile image
Dragane • Edited

That is correct. We created the Customers database on the host mysql server but we left the container database untouched. Manual creation of the Customers database is required on the container.

Collapse
 
bijoy26 profile image
Anjum Rashid • Edited

If you're doing this module on Windows host with Git Bash, mysql server can be set up manually the following way:

  • Download & extract the MySQL Community Server zip archive on a persistant storage
  • Add path-to-mysql-directory/bin to PATH variable
  • Create a data directory under mysql directory
  • Start the server for the first time with mysqld --initialize --console

Now you're good to follow along the rest!

Collapse
 
jayywalker profile image
Jordan Walker

Hey, nice work!

Just one thing, I'm stuck on where we setup the network. I've created my network with

docker network create --driver bridge isolated

and then ran my containers with

docker run -d -p 8000:3000 --net isolated --name jayy jayywalker/node


docker run -p 8001:3306 --net isolated --name db -e MYSQL_ROOT_PASSWORD=dddd -d mysql

Of course since I've ran the app container before the mysql it won't find it, but even after restarting the app container I receive the following error:

/app/app.js:13
    throw err
    ^

Error: connect ETIMEDOUT
    at Connection._handleConnectTimeout (/app/node_modules/mysql/lib/Connection.js:412:13)
    at Object.onceWrapper (events.js:281:20)
    at Socket.emit (events.js:193:13)
    at Socket._onTimeout (net.js:450:8)
    at listOnTimeout (internal/timers.js:535:17)
    at processTimers (internal/timers.js:479:7)
    --------------------
    at Protocol._enqueue (/app/node_modules/mysql/lib/protocol/Protocol.js:144:48)
    at Protocol.handshake (/app/node_modules/mysql/lib/protocol/Protocol.js:51:23)
    at Connection.connect (/app/node_modules/mysql/lib/Connection.js:119:18)
    at Object.<anonymous> (/app/app.js:11:5)
    at Module._compile (internal/modules/cjs/loader.js:816:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:827:10)
    at Module.load (internal/modules/cjs/loader.js:685:32)
    at Function.Module._load (internal/modules/cjs/loader.js:620:12)
    at Function.Module.runMain (internal/modules/cjs/loader.js:877:12)
    at internal/main/run_main_module.js:21:11
Enter fullscreen mode Exit fullscreen mode

It worked fine using link.

Collapse
 
mitch921 profile image
Michele delle Noci

What string are you using as host in the node app? I've noticed that when you use networks instead of links you have to reference to other containers inside the networks by their names.

Collapse
 
jplindstrom profile image
Johan Lindstrom

This needs mentioning in the article, at the end of the "Expand our knowledge on linking — there is another way" section.

Thread Thread
 
softchris profile image
Chris Noring

thanks for the feedback Johan.. Haven't had time to update... But yes will look into improving this section

Collapse
 
softchris profile image
Chris Noring • Edited

hi Jordan. Thanks for your comment. Let me get back to you in a couple of days

Collapse
 
softchris profile image
Chris Noring

you should be using the name of the mysql container as host property

Thread Thread
 
mayankgupta804 profile image
Mayank Gupta

I am getting the same error even after I have set the host property as "mysql". Could you please point where I am going wrong?

Thread Thread
 
softchris profile image
Chris Noring

Thanks for reaching out Mayank. Let m get back to you shortly

Collapse
 
artoodeeto profile image
aRtoo
docker run -d -p 8000:3000 --net isolated_network --name my-container chrisnoring-node
docker run -p 8000:3306 --net isolated_network --name mysql-db -e MYSQL_ROOT_PASSWORD=complexpassword -d mysql

both have the same exposed port. this isn't allowed right? or am i doing it wrong? i have an error

Bind for 0.0.0.0:8000 failed: port is already allocated.
Collapse
 
softchris profile image
Chris Noring

hi. Yes, you are correct. Should 8001 for the database, or at least not 8000. Thanks for noticing :)

Collapse
 
aymdev profile image
AymDev

There are things I did not get when we used --net. How do the containers communicate ?

Mine could not find the MySQL container with the previous "mysql" alias. After running docker inspect mysql-db I used the IP stated from the output at NetworkSettings.Networks.isolated_network.Gateway as the mysql host parameter.
I doubt that this is a reliable solution, how should I proceed to make it easier ?

Collapse
 
seagerjs profile image
Scott Seager

Great article (and series), Chris!

I’ve got a quick question about persistence with the MySQL container. I might have missed it somewhere, but was wondering where the actual MySQL data winds up so that it isn’t lost when the container is restarted later.

Ie. On a native Linux installation these would wind up in /var/lib/mysql on the host machine. Where does the dockerized MySQL container put them? Does it implicitly mount a host file system volume in the same location?

Collapse
 
neskhodovskiy profile image
Serhiy Neskhodovskiy • Edited

You actually bring up an important issue Scott. The whole point about containers is that they are disposable. A good architecture assumes that any container may be destroyed and re-created (from a Dockerfile) at any later moment. But if we destroy the MySQL container we will eventually lose the database. Not a big deal for development, but sounds scary in production, right? One particular consequence, we have to stick to mysql image once downloaded and we won't be able to update to a newer image or to make changes to the image, without destroying the container and losing all data.

The solution? Separate data (mysql database) from the application (mysql container). That's what volumes are for - theoretically. The first idea coming to mind, let's put /var/lib/mysql (or whatever directory MySQL uses as storage) into a volume and mount it into the container, right? Not sure about you, but I had a bunch of low-level issues trying to port this directory from a Windows to a Linux host. The problem turned out to be the difference in how MySQL reads and writes to disk on different platforms.

I don't have a viable solution for this yet, and I'll be happy to hear one.

Collapse
 
sygyzmundovych profile image
Vitaliy Rudnytskiy

Hi Scott. Great question! I've been asking it myself as well :)

I am using Docker Desktop on Mac, so in my case Docker is using a disk image named Docker.raw located in ~/Library/Containers/com.docker.docker/Data/vms/0. And this is where it stores all containers and images. So, you won't see exact the same structure of folders and files on a host as you see in the container.

Regards,
-Vitaliy

Collapse
 
mhussajn profile image
mhussajn

Great content!

Small nitpick - after creating a network, you won't be able to run database container with the command in the article, because port 8000 will already be allocated by first container :)

Collapse
 
softchris profile image
Chris Noring

you've got sharp eyes, thanks for noticing this :)

Collapse
 
cmelgarejo profile image
Christian Melgarejo

Awesome series Chris, I think there's a typo: In the linking example you're using postgres instead of the MySQL db one 😜

Collapse
 
juststarnew profile image
justStarNew

Thanks

Collapse
 
bmassioui profile image
Bouchaib MASSIOUI

Great job :)