JDBC Communications link failure with mysql docker container - mysql

When my java spring application tries to connect to the database I get the following:
Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
The connection url in the spring application is as follows:
jdbc:mysql://mysqldbserver:3306/supersede_orchestrator_spring?useSSL=false&autoReconnect=true&failOverReadOnly=false&maxReconnects=10
where mysqldbserver is the service name from the docker-compose config:
version : '3'
services:
springappserver:
build:
context: .
dockerfile: web.dockerfile
ports:
- "8081:8080"
networks:
- mt-network
volumes:
- .:/vol/development
depends_on:
- mysqldbserver
mysqldbserver:
build:
context: .
dockerfile: db.dockerfile
ports:
- "13306:3306"
networks:
- mt-network
environment:
MYSQL_DATABASE: supersede_orchestrator_spring
MYSQL_USER: supersede_orch
MYSQL_PASSWORD: ****
MYSQL_ROOT_PASSWORD: ****
container_name: orchestrator_mysqldbserver
networks:
mt-network:
driver: bridge
In the mysql docker container I already adjusted the bind-address to 0.0.0.0. The privileges of the supersede_orch user are set to %.
When I connect to the springappserver docker container, I can reach the database via telnet mysqldbserver 3306 and I can also connect to the database on the command line from the spring docker container: mysql -h mysqldbserver -u supersede_orch -p.
Though the java spring application fails to connect to the DB running on the other docker container.
The web.dockerfile looks as follows:
FROM java:8-jre
VOLUME /tmp
ADD build/libs/feedback_orchestrator-2.0.0.jar app.jar
RUN apt-get update
RUN apt-get install mysql-client -y
RUN apt-get install libmysql-java -y
RUN bash -c 'touch /app.jar'
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom -Djava.net.preferIPv4Stack=true","-jar","/app.jar"]
So, I tried to make sure that java uses IP4 to resolve mysqldbserver (I also used the corresponding IP address for mysqldbserver which also failed).
Finally docker images -a:
42db4e656e6e orchestrator_springappserver "java '-Djava.secu..." 16 minutes ago Up 16 minutes 0.0.0.0:8081->8080/tcp orchestrator_springappserver_1
e2b0b5cc15ac orchestrator_mysqldbserver "docker-entrypoint..." 2 hours ago Up About an hour 0.0.0.0:13306->3306/tcp orchestrator_mysqldbserver
Do you have any idea what the problem could be? Thank you!

The above configuration is correct. I was just stupid enough to forget rebuilding the jar. So, the jdbc url was not updated. It works now perfectly.

I got this error. For me I forgot to start up WAMP, which has the mysql info.

Related

Docker-compose api and database configuration

I have a problem with connecting Api with MySQL database running in containers. I have Dockerfile for Golang Api:
FROM golang:latest
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
WORKDIR /app/bin
EXPOSE 8080
RUN go run ./../cmd/web/
I usually connect with database in the application using database/sql:
dsn = "user1:pass#tcp(wpmysql:3306)/wp?parseTime=true"
db, err := sql.Open("mysql", dsn)
My docker-compose.yml:
version: '3'
services:
db:
image: mysql:5.7
container_name: ${MYSQL_CONTAINER_NAME}
ports:
- 3306:3306
command: --init-file /usr/src/app/init.sql
volumes:
- ./init.sql:/usr/src/app/init.sql
environment:
- MYSQL_USER=${MYSQL_USER}
- MYSQL_PASSWORD=${MYSQL_PASS}
- MYSQL_DATABASE=${MYSQL_DB}
- MYSQL_ROOT_PASSWORD=${DB_PASSWORD}
networks:
- fullstack
web:
container_name: wpapi
build: .
ports:
- 8080:8080
restart: on-failure
volumes:
- .:/usr/src/app/
depends_on:
- db
networks:
- fullstack
networks:
fullstack:
driver: bridge
In the same directory as docker-compose.yml is file .env:
DB_PASSWORD=pass
MYSQL_PORT=3306
MYSQL_USER=user1
MYSQL_PASS=pass
MYSQL_DB=wp
MYSQL_CONTAINER_NAME=wpmysql
After call commends:
$ docker-compose up -d db
$ docker-compose build web
I get error ERROR main.go:46: dial tcp: lookup wpmysql on 37.8.214.2:53: no such host. List of containers looks like:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9fbaf67df5bf 2778fcda2046 "/bin/sh -c 'go run …" 14 seconds ago Up 13 seconds 8080/tcp mystifying_shannon
7f6c76cc9c4f mysql:5.7 "docker-entrypoint.s…" 40 minutes ago Up About a minute 0.0.0.0:3306->3306/tcp, 33060/tcp wpmysql
Moreover when I try to connect in application by dsn = "user1:pass#tcp(localhost:3306)/wp?parseTime=true" or dsn = "root:pass#tcp(localhost:3306)/wp?parseTime=true" I get another error:
dial tcp 127.0.0.1:3306: connect: connection refused although I can go into container (docker exec -it wpmysql bash -l) and sign in with root and user1 credentials
In your docker file you have:
RUN go run ./../cmd/web/
This will attempt to build AND run your executable during the build process. The network fullstack is not available at this time. I think you probably meant to use:
CMD go run ../cmd/web/
This will set the default command run when you start (i.e. docker-compose up) the container to go run ../cmd/web/. Even better would be:
RUN go build ../cmd/web/
CMD ../cmd/web/web
This will build your application as part of the process of building the container and then set the executable produced as the default command. The benefit of doing this is that compile errors become apparent when you build the image (and it means the application is not built every time you start the container).

Django container cannot find its mysql container

I have built my django docker with hostname server_default and with --network=server_default and ran mysql with same network(mysql container has ran before django server) when I check my mysql container everything is ok but when I run my django server it fails with error :
"Can't connect to MySQL server on 'server_default' ([Errno -2] Name or service not known)"
I attached to my server container and I couldn't connect to mysql container.
server_default is a bridge type.
my run commands :
sudo docker run -d -p 8000:8000 --network=server_default scotech-server
sudo docker run -d --network=server_default scotech-db
I couldn't do it with docker individually but with docker-compose.yml and 2 build context I could connect them together : it seems a bad solution :(
version: '3'
services:
scotech-db:
build:
context: ./scotech-mysql-docker
expose:
- 3306
web:
build:
context: ./server
depends_on:
- scotech-db
restart: on-failure
ports:
- "8002:8000"

Symfony; SQLSTATE[HY000] [2002] No such file or directory while using 127.0.0.1 as database_host

The full error is Doctrine\DBAL\Exception\ConnectionException: An exception occurred in driver: SQLSTATE[HY000] [2002] No such file or directory in /app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractMySQLDriver.php on line 113, but that's too long for the title.
I'm trying to set up a Symfony project locally, but I'm struggling to get the database connection to work. My parameters.yml looks as follows
parameters:
database_host: 127.0.0.1
database_port: 3306
database_name: database_name
database_user: username
database_password: password
I've been googling this issue a lot and most people seem to solve the issue by changing database_host from localhost to 127.0.0.1, but this doesn't work for me. The app itself runs via Docker, but I've set up the database connection once via Brew and once with a MySQL server for Mac. In both cases I can connect via the command line and with SequelPro/TablePlus, but whenever I try to access the website through the browser I get the "No such file or directory" error.
I've also tried multiple ways of setting up a Docker MySQL container, but can't get it to work. My docker-compose.yml looks like this;
nginx:
build: nginx
ports:
- "8080:80"
links:
- php
volumes:
- ../:/app
php:
build: php-fpm
volumes:
- ../:/app
working_dir: /app
extra_hosts:
- "site.dev: 172.17.0.1"
services:
db:
image: mysql:5.7
restart: always
environment:
MYSQL_DATABASE: 'database_name'
MYSQL_USER: 'username'
MYSQL_PASSWORD: 'password'
MYSQL_ROOT_PASSWORD: 'password_root'
ports:
- '3306:3306'
expose:
- '3306'
volumes:
- my-db:/var/lib/mysql
But whenever I run docker-compose up -d I get the error Unsupported config option for services: 'db'.
Another attempt was adding
mysql:
image: mysql:latest
volumes:
- mysql_data:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD='password'
- MYSQL_DATABASE='database_name'
- MYSQL_USER='username'
- MYSQL_PASSWORD='password'
To the docker-compose file, and while it does build the mysql image, I can't seem to connect to it with SequelPro/TablePlus. I ran docker-inspect on the container to get the IP (172.17.0.3), but can't seem to get access to it. I can exec into it, login using mysql -u root and create the required user and database, but then I'm still struggling to actually connect to it.
Running docker ps does show the sql container running btw;
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b6de6030791d docker_nginx "nginx -g 'daemon of…" 19 minutes ago Up 14 minutes 0.0.0.0:8080->80/tcp docker_nginx_1
f26b832bb005 docker_php "docker-php-entrypoi…" 19 minutes ago Up 14 minutes 9000/tcp docker_php_1
6c2a9e657435 mysql:latest "docker-entrypoint.s…" 19 minutes ago Up 14 minutes 3306/tcp, 33060/tcp docker_mysql_1
I also thought it might be an issue with changes to the parameters.yml file not properly syncing with the container as I'm using Mac (at my old workplace we had to use docker-sync to make sync changes between our dev environment and the actual container), but when inspecting the container itself using exec I can see the changes in the parameters.yml file.
Could the issue be it trying to connect to a mysql server running outside the Docker container? I'm still very new to Docker so I wouldn't be surprised if that's the mistake. Any tips are appreciated 'cause I'm at a dead end.
Your docker-compose file looks wrong to me, try below docker-compose file.
I removed the links, network is much easier.
version: '3'
services:
nginx:
build: nginx
ports:
- "8080:80"
networks:
- backend
volumes:
- ../:/app
php:
build: php-fpm
volumes:
- ../:/app
working_dir: /app
networks:
- backend
extra_hosts:
- "site.dev: 172.17.0.1"
db:
image: mysql:5.7
restart: always
environment:
MYSQL_DATABASE: 'database_name'
MYSQL_USER: 'username'
MYSQL_PASSWORD: 'password'
MYSQL_ROOT_PASSWORD: 'password_root'
networks:
- backend
ports:
- '3306:3306'
volumes:
- ./my-db:/var/lib/mysql
networks:
backend:
driver: bridge
then use database_host: db in php file.
I would diagnose
Check docker logs in the mysql container => no errors
Login to the mysql container and login to mysql => no errors
Login to mysql from the host (mysql -u username -p since you are mapping to 3306 port of the host)
Make sure mysql.cnf doesn't block connect from outside(check
bind-address in the mysql configuration if it 127.0.0.1 the its only
allow to connect form locally, i would for now make it 0.0.0.0 or
commented that line if exists)
mysqld --verbose --help => you will see all options
mysqld --verbose --help | grep bind-address=> check the bind-address
Make sure the user i tried to login has enough privileges to
connect(SELECT user,host FROM mysql.user;) check your user can
connect from docker network => 172.* or anywhere=> %
I think your issue is with your parameters.yml:
parameters:
database_host: 127.0.0.1
When you run compose, MySQL and PHP will run in their own containers which will have their own IPs: 127.0.0.1 or localhost from the php won't be able to connect to the db container. It's like you deployed PHP on a virtual machine A and MySQL to another virtual machine B, but you try to access MySQL from machine A by using localhost where you should specify machine B IP or hostname.
With Docker Compose the internal DNS will resolve the service name to it's container, so you can use something like:
parameters:
# name of the service in compose should be resolved
database_host: db
The error SQLSTATE[HY000] [2002] No such file or directory may be caused when the client tries to read MySQL socket usually present at /var/lib/mysql/mysql.sock which is probably not present in your PHP container.

Docker MySQL - can't connect from Spring Boot app to MySQL database

What I'm trying to do is, connect from my spring-boot app to mysql database in Docker. Each in their own container.
But I must be having something wrong because I can't do it.
To keep it simple :
application-properties :
# URL for the mysql db
spring.datasource.url=jdbc:mysql://workaround-mysql:3308/workaround?serverTimezone=UTC&max_allowed_packet=15728640
# User name in mysql
spring.datasource.username=springuser
# Password for mysql
spring.datasource.password=admin
#Port at which application runs
server.port=8080
docker-compose for MySQL:
version: '3'
services:
workaround-mysql:
container_name: workaround-mysql
image: mysql
environment:
MYSQL_DATABASE: workaround
MYSQL_USER: springuser
MYSQL_PASSWORD: admin
MYSQL_ROOT_PASSWORD: admin
MYSQL_ROOT_HOST: '%'
ports:
- "3308:3306"
restart: always
So pretty simple right ? Database I start with docker-compose up:
All seems to be working fine so far.
Now that I have db started, to the application, this is its docker-compose.yml:
version: '3'
services:
workaround:
restart: always
# will build ./docker/workaround/Dockerfile
build: ./docker/workaround
working_dir: /workaround
volumes:
- ./:/workaround
- ~/.m2:/root/.m2
expose:
- "8080"
command: "mvn clean spring-boot:run"
For its Dockerfile I use Linux Alpine and Java.
FROM alpine:3.9
....add java...
RUN apk update
RUN apk add dos2unix --update-cache --repository http://dl-3.alpinelinux.org/alpine/edge/community/ --allow-untrusted
RUN apk add bash
RUN apk add maven
Super simple. Now let's start the application :
Unknown host, so let's try the IP then :
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' workaround-mysql
# URL for the mysql db
spring.datasource.url=jdbc:mysql://172.20.0.2:3308/workaround?serverTimezone=UTC&max_allowed_packet=15728640
Now I get timeout:
As you can see I get error. What is wrong with my setup and how to fix
this? Either I have unknown host exception or Refused to connect or connection timeout.
I have tried:
Using ip of a container in my application.properties, didn't work
Different ports for MySQL and application
Different images and versions of MySQL
Having everything in one docker compose with wait
timer for database.
Minimal setup with
https://github.com/hellokoding/hellokoding-courses/tree/master/docker-examples/dockercompose-springboot-mysql-nginx
Also resulted in communication link failure, Site was accessible but I
doubt that db was connected properly.
Notes:
I run this all on one computer I use port 3308 because I have local
MySQL db at 3306.
Here is docker ps -a
#Vusal ANSWER output :
Only thing different from code in answer I did wait for database to be ready 30 seconds
command: /bin/bash -c "sleep 30;mvn clean spring-boot:run;"
Try this docker-compose.yml:
version: '3'
services:
workaround-mysql:
container_name: workaround-mysql
image: mysql
environment:
MYSQL_DATABASE: workaround
MYSQL_USER: springuser
MYSQL_PASSWORD: admin
MYSQL_ROOT_PASSWORD: admin
MYSQL_ROOT_HOST: '%'
ports:
- "3308:3306"
restart: always
workaround:
depends_on:
- workaround-mysql
restart: always
# will build ./docker/workaround/Dockerfile
build: ./docker/workaround
working_dir: /workaround
volumes:
- ./:/workaround
- ~/.m2:/root/.m2
expose:
- "8080"
command: "mvn clean spring-boot:run"
And update your application.properties to use the next JDBC connection url:
spring.datasource.url=jdbc:mysql://workaround-mysql:3306/workaround?serverTimezone=UTC&max_allowed_packet=15728640
It should work when both containers in the same docker-compose file, because docker-compose creates default network for containers, so they can resolve each other by name.
What you haven't tried so far is running both containers on the same Docker network.
First, forget about IP addressing - using it should be avoided by all means.
Second, launch both compose instances with the same Docker network.
Third, do not expose ports - inside bridge network all ports are accessible to running containers.
Create global network
docker network create foo
Modify both compose files so that they use this network instead of creating each one its own:
version: '3.5'
services:
....
networks:
default:
external: true
name: foo
Remove expose directives from compose files - inside one network all ports are exposed by default
Modify connection strings to use default 3306 port instead of 3308
Enjoy
In order for the service to connect with MySql through docker it has to be in same network, look into Docker network
But for better solution I would suggest you to write a single docker compose file for MySql and Spring boot.The reason is it will easily be linked when you do that.No need any other configuration.
version: "3"
services:
mysql-service:
image: mysql
ports:
- "3306:3306"
environment:
- MYSQL_DATABASE=db
- MYSQL_USER=root
- MYSQL_PASSWORD=pass
- MYSQL_ROOT_PASSWORD=pass
spring-service:
image: springservce:latest
ports:
- "8080:8080"
depends_on:
- mysql-service
Before you try to connect to the Docker container you should stop mysql in your computer then go to the application.properties and type:
spring.datasource.url=jdbc:mysql://localhost:3306/NAME_OF_YOUR_DB_HERE?useSSL=false&allowPublicKeyRetrieval=true
Regarding localhost, you should inspect the mysql container and pick the IP address and use it instead. most likely is 172.17.0.2. If it did not work then use localhost.

Django - Mysql Database is not created in Docker

I setup a django project in docker container and every thing is working as expected, except I don't find the project database in mysql image.
Dockerfile
FROM python:3
RUN mkdir /django-website
WORKDIR /django-website
COPY . /django-website
RUN pip install -r requirements.txt
docker-compose.yml
version: '3'
services:
db:
image: mysql:5.7
restart: always
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE=mywebsite
- MYSQL_USER=root
- MYSQL_PASSWORD=root
ports:
- '33060:3306'
volumes:
- /var/lib/mysql
web:
build: .
command: python manage.py runserver 0.0.0.0:8000
volumes:
- .:/django-website
ports:
- '8000:8000'
links:
- db
settings.py
DATABASES = {
'default': {
'ENGINE': "django.db.backends.mysql",
'NAME': "mywebsite",
'USER': "root",
'PASSWORD': "root",
'HOST': 'db',
'PORT': '3306',
}
}
I ran migrate and it worked:
docker-compose run web python manage.py migrate
I createdsuperuser:
docker-compose run web python manage.py createsuperuser
The development server is working docker-compose up and the site is working as expected, the issue when I navigate in mysql image I don't find my project related database which is mywebsite .
can you please tell me what is missing? if the database is not created, where has the migration been applied?
Thanks in advance.
I'm not sure what you mean by "I logged in mysql image shell but didn't find mywebsite database"
You are migrated the DB successfully, which means, the DB connections are valid and working.
In your docker-compose.yml file, the port mapping done like this, '33060:3306', which means the db's port 3306 is mapped to host machine's port 33060. So, this may be the issue (it's not an issue, kind of typo)
How to check the DB contents?
METHOD-1: check through django-shell of web container
1. run docker-compose up
2. open a new terminal in the same path and run docker ps
you'll get something like below
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
795093357f78 django_1_11_web "python manage.py ru…" 34 minutes ago Up 11 minutes 0.0.0.0:8000->8000/tcp django_1_11_web_1
4ae48f291e34 mysql:5.7 "docker-entrypoint.s…" 34 minutes ago Up 12 minutes 0.0.0.0:33060->3306/tcp django_1_11_db_1
3.Get into the web container by docker exec -it 795093357f78 bash command, where 795093357f78 is the respective container id
4. now you're inside the container. Then, run the command python manage.py dbshell. Now you will be in MYSQL shell of mywebsite (Screenshot)
5. run the command show tables;. It will display all the tables inside the mywebsite DB
METHOD-2: check through db container
1. repeat the steps 1 and 2 in above section
2. get into db container by docker exec -it 4ae48f291e34 bash
3. Now you'll be in bash terminal of MYSQL. Run the following commmand mysql -u root -p and enter the password when prompt
4. now you're in MYSQL server. run the command, show databases;. This will show all the databases in the server.
Have you tried defining the database image in the dockerfile? The following link is somewhat related to your problem:
https://medium.com/#lvthillo/customize-your-mysql-database-in-docker-723ffd59d8fb
I supposed that ports value of host container should be 3306 not 33060.
Use docker-compose.yml with value 3306 :
version: '3'
services:
db:
image: mysql:5.7
restart: always
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE=mywebsite
- MYSQL_USER=root
- MYSQL_PASSWORD=root
ports:
- '3306:3306'
volumes:
- /var/lib/mysql
web:
build: .
command: python manage.py runserver 0.0.0.0:8000
volumes:
- .:/django-website
ports:
- '8000:8000'
links:
- db
Hope this works!
You should change the compose specification to version '2'. Take down the container and bring it back up with docker-compose up -d. Or if you intend to stay with version 3, you can instead use the following specification for database environment parameters
```
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: mywebsite
MYSQL_USER: root
MYSQL_PASSWORD: root
```
When you have problems with containers not coming up, docker logs <container-name> --tail 25 -f can give you a lot of information about the cause.