I have two separate projects(as two different repositories on GitHub) as client and server and they are communicating via WebSocket.
the Server is configured on CircleCi with the following docker entries:
installing "server".
docker:
- image: cimg/base:stable
auth:
username: mydockerhub-user
password: $DOCKERHUB_PASSWORD
environment:
CMAKE_BUILD_TYPE: Release
INSTALL: ~/server-install
how can I use the already established Server docker image for my client,
deploying my client and server to the same container?
Related
I have a docker container which is based on a springboot project and generated with this command :
docker run --net=host -d --restart unless-stopped -v /home/ramses/dockerTest:/uploads/deployment --name ramses-bl2 abyster01/ramses-bl2:528
but the container does not access to my database, as you can see in this error :
Caused by: org.springframework.transaction.CannotCreateTransactionException: Could not open JPA EntityManager for transaction; nested exception is org.hibernate.exception.JDBCConnectionException: Unable to acquire JDBC Connection
Caused by: com.mysql.cj.exceptions.CJCommunicationsException: 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.
My container is launched in host mod, and i verified the root (the user i set in my springboot project properties) is set as user in my database as you can see in this screenshots :
Finally i test connection to my database successfully with the same credentials as in my properties.
But i don't know why i'm getting this error.
For what you need it is not necessary to run in host mode. In general you should always avoid doing so.
First of all check the IP address of the host on your local network (not the local interface 127.0.0.1 but something like 192.168.X.X or similar).
Make sure you can access your database from host by connecting to this IP and the correct port. Also check that the user you use can connect also from hosts other than localhost.
Then run the container with the additional flag: --add-host mydatabase:192.168.X.X. Your application inside the container should use mydatabase as the database server name.
I would recommend for you to use a docker-compose.yml file. Add to the file the following:
version: '3'
services:
mysql-standalone:
image: mysql:latest
environment:
- MYSQL_ROOT_PASSWORD=***
- MYSQL_DATABASE=***
- MYSQL_USER=***
- MYSQL_PASSWORD=**
volumes:
- data:/var/lib/mysql
spring-boot:
image: *your-app-name-image*
ports:
[8080:8080]
build:
context: ./
dockerfile: Dockerfile
depends_on:
- mysql-standalone
volumes:
data:
Then in the application.properties have the following configuration
server.port=8080
spring.datasource.url=jdbc:mysql://<container-name>:3306/<db-name>
spring.datasource.username=***
spring.datasource.password=***
Finally, run docker-compose up.
Note that one of the differences between docker run versus docker-compose is that docker-compose reads configuration data from a YAML file instead of having to set your configuration from a cli
I have two containers, one with a Srping app and another with mysql. When I run the Spring app on my local machine, it successfully connects to my MySQL db running in a docker container. Once I spin up the Spring container I get a connection error, the app is unable to communicate with the MySQL container. How do I configure the Spring container to communicate with the db container? I've tried creating a bridge network to no avail. I believe my issue is spring.datasource.url=jdbc:mysql://localhost:3309/library but when I try with the network id the jar fails to build spring.datasource.url=jdbc:mysql://lms-network/library. I've been following this tutorial. docker image.
There are couple of ways we can solve it.
Using docker-compose
Put both the containers in docker-compose file. Example:
version: "3"
services:
spring-boot-service:
build:
context: .
ports:
- 8080:8080
environment:
DB_HOST: mysql-db
DB_NAME: library
DB_USER: <user>
DB_PASSWORD : <pwd>
mysql-db:
image: mysql
ports:
- 3306:3306
environment:
MYSQL_ROOT_PASSWORD: "root"
MYSQL_DATABASE: <db_name>
#... other properties
then in application.properties, use connection string as :
spring.datasource.url=jdbc:mysql://${DB_HOST}:3306/${DB_NAME}
then use docker-compose up to run both containers together. This way they will share network through docker-compose.
Using host.docker.internal
When you run your spring boot app and mysql in separate containers, you can't refer the mysql database from localhost anymore as localhost means pointing to your container. Since mysql is running on your host machine, you can refer it by using host.docker.internal instead of localhost in connection string.
So you connection string should be
spring.datasource.url=jdbc:mysql://host.docker.internal:3309/library
I'm trying to get TeamCity server running using docker-compose. Here's my compose file:
version: '3'
services:
db:
image: mysql
container_name: teamcity-db
restart: unless-stopped
env_file: .env
environment:
- MYSQL_DATABASE=teamcity
volumes:
- mysql:/var/lib/mysql
command: '--default-authentication-plugin=mysql_native_password'
teamcity:
depends_on:
- db
image: jetbrains/teamcity-server
container_name: teamcity
restart: unless-stopped
volumes:
- datadir:/data/teamcity_server/datadir
- logs:/opt/teamcity/logs
ports:
- "8111:8111"
volumes:
mysql:
datadir:
logs:
I've been successful getting wordpress set up using a very similar technique, and I can run phpMyAdmin and link it to the MySQL container and see the database, so its there.
When I browse to the teamcity web address, it shows me the initial setup screen as expected. I tell it to use MySQL and I put in 'root' as teh username and my MySQL root password. Teamcity then shows this:
I'm sure it's something simple but I just can't see what's wrong. Any ideas?
Solved! Here is my solution and some other learnings.
The problem was that I was telling TeamCity to use 'localhost' as the database server URL. This seems intuitive because all the services are on the same machine, but is incorrect. It is as if each container is its own host and so 'localhost' is specific to each container. 'localhost' inside a container refers to the container itself, not the host machine or any other container. So 'localhost' on the teamcity service refers to the teamcity server, not the database server, and that's why it couldn't connect.
The correct address for the database server based on my docker-compose.yml file is db (the service name of the database container). The service name becomes the host name for that container and docker resolves these as DNS names correctly within the composed group.
Also note: the default virtual network is created implicitly by docker-compose and allows all of the containers in the composed group to communicate with each other. The name of this network derives from the folder where the docker-compose.yml file is located (in my case ~/projects/teamcity) so I get a network called teamcity_default. All servers on this private vitual network are visible to each other with no further configuration needed.
The teamcity server container explicitly exposes port 8111 on the host's network interface, so it is the only container visible to the outside world. You do not need to (and probably should not) expose ports if you only need the servers to talk to each other. For example, the database server does not need to have a ports entry because it is automatically exposed on the private inter-container network. This is great for security because all the back-end services are hidden from the physical LAN and therefore the Internet.
I'm trying to dockerize my Django app with Docker, but having some trouble connecting with the mysql database since i'm not really experienced with Docker. I have a couple questions:
I have installed mysql and set up the database locally on my computer, do i have to use a mysql image and create a db service in my docker-compose too ? Shouldn't Django connect to mysql normally like it did when it wasn't dockerized ?
If a database is hosted on a server then is mysql installed on that server ? Do i have to use a mysql image to connect to the database ?
Here is my docker-compose.yml:
version: '3.7'
services:
web:
build: ./appchat
command: python appchat/manage.py runserver
ports:
- 8000:8000
- "3306"
network_mode: "host"
And here is the database settings in settings.py:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'USER': 'root',
'PASSWORD': 'root',
'NAME': 'company',
'PORT': '3306',
}
}
Here is the error when i ran docker-compose file:
django.db.utils.OperationalError: (2002, "Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)")
Any help would be appreciated. Thank you.
The application and its database could be running on the same host or different hosts, and in Docker or not.
If the application and its database are running on different hosts, there is nothing unusual about setting this up in Docker. Configure your application with the DNS name of the database server. (I would recommend passing this via environment variables rather than modifying the settings.py file.)
Docker Compose syntax:
environment:
MYSQL_HOST: mysql.example.com
If both are running in the same Docker setup, then Docker provides an internal DNS setup for one to reach the other. In Docker Compose, you can use the services: key as a host name; in plain Docker, you need to manually docker network create but then this trick works.
Plain Docker example:
docker network create app
docker run --net app --name mysql -v $PWD/mysql:/var/lib/mysql/data mysql
docker run --net app --name app -e MYSQL_HOST=mysql myapp
If the database is running on the same host as the application, but outside Docker, and the host is a Mac or Windows system running the Docker Desktop application, then there is a special host.docker.internal hostname
docker run -e MYSQL_HOST=host.docker.internal myapp
For a native-Linux host this shortcut doesn't exist and you need to find out the host's IP address, but then you can treat this like the first case.
How can I get my Spring App host in docker to access the mysql host on my host mechine(mac) or access a cloud mysql service?
I know if the mysql is another docker container, I can use link in docker. But this situation is not.
version: '3'
I tried the host mode, seems still get the connection refused.
Dockerfile
FROM openjdk:8-jdk-alpine
VOLUME /tmp
ADD ./build/libs/app.jar app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","-Dspring.profiles.active=dev","/app.jar"]
docker-compose.yml
services:
web:
build: .
network_mode: "host"
ports:
- "8080:8080"
PS: 'java -jar -Dspring.profiles.active=dev app.jar' on my host machine works fine.
Can anyone help me?
For latest mac docker, I can use docker.for.mac.localhost as hostname
spring.datasource.url=jdbc:mysql://docker.for.mac.localhost:3306/a_shares...
And some dark magic has been discussed in here Accessing host machine from within docker container