Using Redis and mysql with docker container - mysql

My web application needs both mysql and redis server to function properly. I am able to link mysql container with app using link tag (mysql is name of mysql image set using -name tag)
sudo docker run -link mysql:amq -d -p 13310 hitesh/image node app
Now I am not sure how to attach redis to this container. Should it be done via same mysql image (if yes, how two ports i.e. 3306 & 6379 will be exposed?) or should I make another container for redis and link it to my node.js app (not sure about it is possible or not).

You should have 3 containers
your app
your mysql
your redis
then expose your mysql port and redis port on the relevant containers.
Then when you run your app container just link both mysql and redis containers to your app
so something like
sudo docker run -d -link mysql:mysql -link redis:redis ....
Now your app container will have environment variables for your other two databases
Also, if you want to expose two ports, then in your dockerfile just do EXPOSE port1 port2
e.g. EXPOSE 22 80
Then you'll get environment variables for both exposed ports. But i'd recommend you don't have a container that runs both mysql and redis. Separate your concerns :)

Related

Creating a MySQL cluster, using mysql-server docker containers, on multiple servers

I'm trying to create an MySQL cluster of 3 nodes using mysql-server docker containers.
I have 3 separate cloud instances and docker is setup on all 3 of them. Each server will have only 1 container running on it - to achieve High Availability when in cluster.
I start the containers on all 3 servers, individually, with the command
docker run --name=db -p 3301:3306 -v db:/var/lib/mysql -d mysql/mysql-server
I'm mapping the port 3306 of container to my server's 3301 port. I've also created a new user 'clusteradmin' for remote access.
Next, from mysql-shell, I ran following command - for all 3 servers
dba.configureInstance('clusteradmin#serverIp:3301')
I get similar message for all-
Note that it says 'This instance reports its own address as 39xxxxxxxxxx:3306'.
Next I create a cluster in one of the server successfully. But, when adding the other 2 servers to this cluster, I'm getting the following error
On checking the logs for that particular server, I see the following lines
It says 'peer address a9yyyyyyyyyy:33061 is not valid'. This is because, since the containers are running on different servers, the container-id is not recognised by other containers on other server.
I tried many options but to no avail. One method was to use report-host and report-port options when starting the container, like so
docker run --name=db2 -p 3301:3306 -v db2:/var/lib/mysql -d mysql/mysql-server --report-host=139.59.11.215 --report-port=3301
But, the issue with this approch is that, during dba.configureInstance(), it wants to update the port to default value and throws error like so
Anybody who has managed to create such a cluster of mysql-server containers running on different servers, I would really appreciate pointers in this regard.
I have gone over the documentation and source code but have not found an explanation why listening and advertising different ports is problematic.
I have solved the problem by using --port 3301 when invoking mysql-server:
docker run --name=db2 -p 3301:3301 -v db2:/var/lib/mysql -d mysql/mysql-server --report-host=139.59.11.215 --port 3301

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?
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/)

Connect docker container to local workbench MySQL DB

HI I have my web app running on my local machine and connected to Mysql workbench, I am now trying to dockerize the webapp. I can't seem to get it to connect to the DB on my local dev machine (I am running Docker Desktop for Windows), can anyone tell me how I would go about this? Here is what I have so far.
`docker run -it -e "CATALINA_OPTS=-Dspring.profiles.active=dev -DPARAM1=DEV" -p 8080:8080 -p 8005:8005 -p 8009:8009 -p 3306:3306 --add-host=docker:192.168.1.7 -v C:\myapp\trunk\target\myapp.war:/usr/local/tomcat/webapps/myapp.war --name waitapp tomcat:8.0.38-jre8`
after a few second, I run docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2a1764dd9640 tomcat:8.0.38-jre8 "catalina.sh run" 2 minutes ago Up 2 minutes 0.0.0.0:3306->3306/tcp, 0.0.0.0:8005->8005/tcp, 0.0.0.0:8009->8009/tcp, 0.0.0.0:8080->8080/tcp waitapp
The container seems to be running, but I get a 404 Not found when I try the rest request, this is the same as I do when running from inside spring tool suite using built in tomcat server.
NOTE
I don't want to run a separate mysql container and link the two over a network, I just want to try get my newly created docker app to connect to my local DB MySQL.
As mentioned on this post, you can try 2 things:
Add gateway and use it from containers, like
docker network create -d bridge --subnet 192.168.0.0/24 --gateway 192.168.0.1 dockernet
In addition to your app container, run proxy (ngnix?) container, which will rout the calls to DB when required
This answer also show how can you obtain the host IP inside the docker container.

MySQL in Docker container

Currently I have a Docker container that hosts a webpage (mostly php). Right now the database is stored on a server on AWS. For development purposes I want to create a local database in the Docker container. I did some googling around and it seems like most people recommend creating an entire separate container for hosting the mysql. Since this is only a database for development I am wondering if I can avoid the effort of setting up another container and put MySQL in directly in the container that hosts the webpage. To do this I tried installing MySQL-Server:
sudo apt-get install mysql-server
Mysql installed fine doing this. Then I tried to run the MySQL interactive shell:
mysql -u root -p
When I did this I got the following error ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)
Can I run the mysql in the same Docker container or am I going to need to create a separate one?
There is really no effort in setting up separate MySQL container. Real effort is to install it inside existing container.
I would recommend that you create docker compose file and define application and database containers (make sure you have docker compose installed on your dev environment, in most cases it should be already installed).
Create a file docker-compose.yml (you can create it in the same folder where Dockerfile is for you project, usually project root folder) with following content:
version: '2'
services:
app:
image: your_app_docker_image_name
...more config options depending on your project (volumes, ports, etc)
db:
image: mariadb
volumes:
- './user/db:/var/lib/mysql'
environment:
- MYSQL_ALLOW_EMPTY_PASSWORD=true
To start your project run
docker-compose up
This will lift your app container and separate MySQL container (without root password intentionally since this is for dev purpose).
Now you can access mysql server from your app container like this
mysql -h db -u root
Using docker compose you can setup complex environments easily. And when deploying to production or other test environment you don't need to change your Dockerfile.
There are many pros to have separate containers for each service.
To have php+apache+mysql in the same container you either have to find an image like this https://github.com/tutumcloud/lamp, or build it yourself from a Dockerfile.
But try to imagine one day you decide to switch your db storage engine from Mysql to Percona or Maria, or you would like to start using Memcached/Redis for your application. Either of the above won't be any problem if you have your services as separate containers.

docker.io - Docker linking between application & database containers

I am trying to use my Scala-Akka application with my MySQL database on two separate Docker containers. I found out that Docker allows developers to link their application to their databases with the flag named --link. In my Dockerfiles in which I've used to create my images, I have add in EXPOSE 3306 8080 to it.
And this is how I run the containers:
docker run -d -p 3306:3306 --name mysql centos6mysql
docker run -d -p 8080:8080 --name scalaapp --link mysql:db centos6scala
After running the containers, I used docker ps and I am able to see the active containers. However, It seems like the application container is not using the database from the MySQL container. Anyone know what's wrong?
Linking in Docker allows network connections to be made between containers. Docker will define environmental variables to your linked containers for the URL, IP, port, and protocol. The names of these will be based on the name of your container. For instance:
DB_NAME=/web2/db
DB_PORT=tcp://172.17.0.5:5432
DB_PORT_5432_TCP=tcp://172.17.0.5:5432
DB_PORT_5432_TCP_PROTO=tcp
DB_PORT_5432_TCP_PORT=5432
DB_PORT_5432_TCP_ADDR=172.17.0.5
You can use these environmental variables to set up your Akka app container to connect to your DB container. However, you must manually configure the app container to do so. Docker will not make the connection for you automatically.
So, somewhere in your app, you will need to pass these values to your startup script, something that might look like:
./restcore --Ddb.default.db="jdbc:mysql//${DB_PORT_3306_TCP_ADDR}:${DB_PORT_3306_TCP_PORT"