I have cross browser tests that I have written with selenium. Since I want to test multiple browsers on multiple platforms I use docker virtualization and selenium grid. I could execute my tests without docker via localhost:4444 with this docker-compose.yml
version: "3"
services:
hub:
image: selenium/hub
ports:
- "4444:4444"
environment:
GRID_MAX_SESSION: 16
GRID_BROWSER_TIMEOUT: 3000
GRID_TIMEOUT: 3000
chrome:
image: selenium/node-chrome
container_name: web-automation_chrome
depends_on:
- hub
environment:
HUB_PORT_4444_TCP_ADDR: hub
HUB_PORT_4444_TCP_PORT: 4444
NODE_MAX_SESSION: 4
NODE_MAX_INSTANCES: 4
volumes:
- /dev/shm:/dev/shm
ports:
- "9001:5900"
firefox:
image: selenium/node-firefox
container_name: web-automation_firefox
depends_on:
- hub
environment:
HUB_PORT_4444_TCP_ADDR: hub
HUB_PORT_4444_TCP_PORT: 4444
NODE_MAX_SESSION: 2
NODE_MAX_INSTANCES: 2
volumes:
- /dev/shm:/dev/shm
ports:
- "9002:5900"
opera:
image: selenium/node-opera
container_name: web-automation_opera
depends_on:
- hub
environment:
HUB_PORT_4444_TCP_ADDR: hub
HUB_PORT_4444_TCP_PORT: 4444
NODE_MAX_SESSION: 2
NODE_MAX_INSTANCES: 2
volumes:
- /dev/shm:/dev/shm
ports:
- "9003:5900"
I just executed my tests with maven and they would succeed. Then I planned to containerize also my browser JUnit tests and created this Dockerfile:
FROM openjdk:11 as build
WORKDIR /workspace/app
COPY .git .git
COPY mvnw .
COPY .mvn .mvn
COPY wait-for-it.sh .
RUN ["chmod", "+x", "wait-for-it.sh"]
COPY pom.xml .
COPY src src
RUN ./wait-for-it.sh hub:4444 -- ./mvnw clean package
FROM openjdk:11
VOLUME /tmp
COPY --from=build /workspace/app/target/*.jar app.jar
Which should work fine as well and added this part to my docker-compose.yml:
app:
build: .
ports:
- "80:8080"
depends_on:
- "hub"
As soon as I run docker-compose up, the maven builds the tests successfully and selenium grid is set up successfully but I receive the following error:
[ERROR] loginUserNotExistentFirefox Time elapsed: 0.033 s <<< ERROR!
org.openqa.selenium.remote.UnreachableBrowserException:
Could not start a new session. Possible causes are invalid address of the remote server or browser start-up failure.
Build info: version: '3.141.59', revision: 'e82be7d358', time: '2018-11-14T08:17:03'
System info: host: '7e67c412b3c0', ip: '172.17.0.2', os.name: 'Linux', os.arch: 'amd64', os.version: '4.19.121-linuxkit', java.version: '11.0.9.1'
Driver info: driver.version: RemoteWebDriver
at org.seleniumtests.frontendtests.tests.TestLogin.loginUserNotExistentFirefox(TestLogin.java:29)
Caused by: java.net.UnknownHostException: hub
at org.seleniumtests.frontendtests.tests.TestLogin.loginUserNotExistentFirefox(TestLogin.java:29)
This is how I plan to reach the service from my app container.
driver = new RemoteWebDriver(new URL("http://hub:4444/wd/hub"),
DesiredCapabilities.operaBlink());
First problem: you can't connect to localhost:4444
There's a bridge (by default in Docker Compose) between your services, and you can access to another service by <service_name>:<service_port>, so you can access hub service by hub:4444.
Second problem, it may be outcome when you solve the first problem
From the official Docker Compose documentation, as you can read here:
You can control the order of service startup and shutdown with the depends_on option. Compose always starts and stops containers in dependency order, where dependencies are determined by depends_on, links, volumes_from, and network_mode: "service:...".
As you did with depends_on, but
However, for startup Compose does not wait until a container is “ready” (whatever that means for your particular application) - only until it’s running. There’s a good reason for this.
Docker Compose official solution
Use a tool such as wait-for-it, dockerize, sh-compatible wait-for, or
RelayAndContainers template. These are small wrapper scripts which you
can include in your application’s image to poll a given host and port
until it’s accepting TCP connections.
They suggest you to act like this:
version: "3"
services:
hub:
image: selenium/hub
ports:
- "4444:4444"
environment:
GRID_MAX_SESSION: 16
GRID_BROWSER_TIMEOUT: 3000
GRID_TIMEOUT: 3000
app:
build: .
ports:
- "80:8080"
depends_on:
- "hub"
command: ["./wait-for-it.sh", "hub:4444", "--", "java", "-jar", "app.jar"]
Related
I am trying to get a .net C# 6 API to remove metrics through to Prometheus, both running inside docker containers.
When I visit http://localhost:9090/targets, it is telling me that "Get "http://myapi:50505/metrics": dial tcp 192.168.65.2:50505: connect: connection refused" (the state is Down).
Within my api container, I did a netstat --tcp --listen --numeric-ports expecting that port 50505 would be being listened to, but it wasn't -- just 5005 (and 35605, which I also tried in the prometheus.ym).
I tried adding "50505:50505" to the ports on myapi.
One Google search suggested my C# 6 code should do this:
var metricServer = new KestrelMetricServer(port: 1234);
metricServer.Start();
So I did that, changed the prometethus.yml to listen for port 1234, still no luck.
I've tried the suggestions out there, including using localhost:50505 in the prometheus.yml, exposing 50505 in my API Dockerfile.
No errors in either the myapi nor prometheus logs.
No luck.
This is my prometheus.yml:
global:
scrape_interval: 15s
scrape_configs:
- job_name: "myapi"
scrape_interval: 5s
static_configs:
- targets: ["myapi:50505"]
This is my docker-compose.yml
version: '3.3'
services:
myapi:
image: myapi
container_name: myapi
ports:
- "7109:5005"
networks:
- mynet
prometheus:
image: prometheus
ports:
- "9090:9090"
depends_on:
- myapi
networks:
- mynet
networks:
mynet:
driver: bridge
I built the prometheus container with this Dockerfile
FROM prom/prometheus
ADD ./prometheus.yml /etc/prometheus/
My API is built with this Dockerfile
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
ARG BUILDCONFIG=RELEASE
ARG VERSION=1.0.0
COPY ["myapi.csproj", "./src/myapi/"]
WORKDIR ./src/myapi/
RUN dotnet publish -c $BUILDCONFIG -o out /p:Version=$VERSION
FROM mcr.microsoft.com/dotnet/aspnet:6.0
WORKDIR /app
COPY --from=build /src/myapi/out ./
EXPOSE 5005/tcp
EXPOSE 50505/tcp
ENTRYPOINT ["dotnet", "myapi.dll", "--urls", "http://+:5005"]
In my Program.cs I have this:
...
app.UseMetricServer(50505, "/prometheus");
app.UseRouting();
app.UseHttpMetrics();
app.Run();
And if it matters, in the endpoint method I have this:
Counter _eventCounter = Metrics.CreateCounter("API_Events", "Entry Attempts", new string[] { "result" });
_eventCounter.WithLabels("test").Inc();
Host OS: Mac M2 Ventura 13.2.1
Docker: Docker version 20.10.22, build 3a2c30b
i have 2 containers, the first container has a microservice called "authentication" and the second has a mongodb database. I'm trying to connect the first container to the second and it doesn't work. the 2 are executed but I cannot connect one with the other. My operating system is Windows 11. I am attaching images of the docker-compose, the dockerfile and the .env of the microservice.
.Docker-compose file (this file is located in a separate folder from the "authentication" microservice)
`
version: "3.9"
services:
authentication:
build: ../authentication
restart: always
depends_on:
- mongodb
ports:
- 8080:8080
environment:
PORT: 8080
MONGODB: mongodb://localhost:27017/emprendamos
mongodb:
image: mongo:6
restart: always
ports:
- 27017:27017
environment:
MONGODB_DATABASE: emprendamos
volumes:
- ./mongo:/data/db
`
.env file of the "authentication" microservice
`
PORT=8080
MONGODB='mongodb://localhost:27017/emprendamos'
`
.Dockerfile of the "authentication" microservice
`
FROM node:18.12.1
WORKDIR /authentication
COPY . .
RUN npm install
RUN npm run build
CMD [ "node","dist/main.js" ]
`
I expect to be able to establish the connection of the container that has the microservice with the container that has mongodb inside
I have tried several possible solutions on Stack Overflow but nothing seems to work for me.
I am developing microservices using RabbitMQ. The solution contains multiple projects and runs without any problem, but as soon as I use docker-compose option to build the project, Visual Studio throws the following exception:
RabbitMQ.Client.Exceptions.BrokerUnreachableException ExtendedSocketException: Connection refused 127.0.0.1:5672
In my solution, I have three projects communicating with each other via RabbitMQ.
Below is the code for my YAML file.
My docker-compose.yaml:
version: '3.4'
services:
rabbitmq:
hostname: webnet
image: rabbitmq:3.7.2-management
ports:
- "15672:15672"
- "5672:5672"
networks:
- webnet
sql-server-db:
container_name: sql-server-db
image: microsoft/mssql-server-linux:2017-latest
ports:
- "1433:1433"
environment:
SA_PASSWORD: "customerdbalten#123"
ACCEPT_EULA: "Y"
networks:
- webnet
myproject.simulation.api:
image: ${DOCKER_REGISTRY-}myprojectsimulationapi
build:
context: .
dockerfile: myproject.Simulation.Api/Dockerfile
links:
- rabbitmq
ports:
- '5000'
networks:
- webnet
myproject.updateservice.api:
image: ${DOCKER_REGISTRY-}myprojectupdateserviceapi
build:
context: .
dockerfile: myproject.updateservice.Api/Dockerfile
links:
- rabbitmq
- sql-server-db
ports:
- '5050'
networks:
- webnet
myproject.web:
image: ${DOCKER_REGISTRY-}myprojectweb
build:
context: .
dockerfile: MyProject.Web/Dockerfile
links:
- rabbitmq
ports:
- '5001'
networks:
- webnet
networks:
webnet:
driver: bridge
My Docker file:
My Dockerfile looks like the following:
FROM microsoft/dotnet:2.2-aspnetcore-runtime AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM microsoft/dotnet:2.2-sdk AS build
WORKDIR /src
COPY
MyProject.UpdateService.Api/MyProject.UpdateService.Api.csproj MyProject.UpdateService.Api/
COPY MyProject.Common/MyProject.Common.csproj MyProject.Common/
RUN dotnet restore MyProject.UpdateService.Api/MyProject.UpdateService.Api.csproj
COPY . .
WORKDIR /src/MyProject.UpdateService.Api
RUN dotnet build MyProject.UpdateService.Api.csproj -c Release -o /app
FROM build AS publish
RUN dotnet publish MyProject.UpdateService.Api.csproj -c Release -o /app
FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "MyProject.UpdateService.Api.dll"]
I've also created another simple solution with nothing but two projects - a sender and receiver - that uses RabbitMQ. This solution throws the same exception while docker-composeing, otherwise, it just runs. The YAML file has nothing but auto-generated code.
From the discussion, we found out that the rabbitMQ container is not running as there is already running rabbitMQ service on the host.
You have two option, stop the host RabbitMQ service and then try to connect with rabbitMQ container.
Hostname: rabbitmq:5672
Or if you want to connect with Host RabbitMQ service then you can use
Hostname: host.docker.internal
#or
Hostname: HOST_IP
I WANT TO CONNECT FROM A CONTAINER TO A SERVICE ON THE HOST
The host has a changing IP address (or none if you have no network
access). From 18.03 onwards our recommendation is to connect to the
special DNS name `host.docker.internal, which resolves to the internal
IP address used by the host. This is for development purpose and will
not work in a production environment outside of Docker Desktop for
Windows.
The gateway is also reachable as gateway.docker.internal.
docker-for-windows-networking
I have created a docker-compose file it has two services with Go and Mysql. It creates container for go and mysql. Now i am running code which try to connect to mysql database which is running as a docker container. but i get error.
docker-compose.yml
version: "2"
services:
app:
container_name: golang
restart: always
build: .
ports:
- "49160:8800"
links:
- "mysql"
depends_on:
- "mysql"
mysql:
image: mysql
container_name: mysql
volumes:
- dbdata:/var/lib/mysql
restart: always
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE=testDB
- MYSQL_USER=root
- MYSQL_PASSWORD=root
ports:
- "3307:3306"
volumes:
dbdata:
Error while connecting to mysql database
golang | 2019/02/28 11:33:05 dial tcp 127.0.0.1:3306: connect: connection refused
golang | 2019/02/28 11:33:05 http: panic serving 172.24.0.1:49066: dial tcp 127.0.0.1:3306: connect: connection refused
golang | goroutine 19 [running]:
Connection with MySql Database
func DB() *gorm.DB {
db, err := gorm.Open("mysql", "root:root#tcp(mysql:3306)/testDB?charset=utf8&parseTime=True&loc=Local")
if err != nil {
log.Panic(err)
}
log.Println("Connection Established")
return db
}
EDIT:Updated docker file
FROM golang:latest
RUN go get -u github.com/gorilla/mux
RUN go get -u github.com/jinzhu/gorm
RUN go get -u github.com/go-sql-driver/mysql
COPY ./wait-for-it.sh .
RUN chmod +x /wait-for-it.sh
WORKDIR /go/src/app
ADD . src
EXPOSE 8800
CMD ["go", "run", "src/main.go"]
I am using gorm package which lets me connet to the database
depends_on is not a verification that MySQL is actually ready to receive connections. It will start the second container once the database container is running regardless it was ready for connections or not which could lead to such an issue with your application as it expects the database to be ready which might not be true.
Quoted from the documentation:
depends_on does not wait for db and redis to be “ready” before starting web - only until they have been started.
There are many tools/scripts that can be used to solve this issue like wait-for which sh compatible in case your image based on Alpine for example (You can use wait-for-it if you have bash in your image)
All you have to do is to add the script to your image through Dockerfile then use this command in docker-compose.yml for the service that you want to make it wait for the database.
What comes after -- is the command that you would normally use to start your application
version: "2"
services:
app:
container_name: golang
...
command: ["./wait-for", "mysql:3306", "--", "go", "run", "myapplication"]
links:
- "mysql"
depends_on:
- "mysql"
mysql:
image: mysql
...
I have removed some parts from the docker-compose for easier readability.
Modify this part go run myapplication with the CMD of your golang image.
See Controlling startup order for more on this problem and strategies for solving it.
Another issue that will rise after you solve the connection issue will be as the following:
Setting MYSQL_USER with root value will cause a failure in MySQL with this error message:
ERROR 1396 (HY000) at line 1: Operation CREATE USER failed for 'root'#'%'
This is because this user already exist in the database and it tries to create another. if you need to use the root user itself you can use only this variable MYSQL_ROOT_PASSWORD or change the value of MYSQL_USER so you can securely use it in your application instead of the root user.
Update: In case you are getting not found and the path was correct, you might need to write the command as below:
command: sh -c "./wait-for mysql:3306 -- go run myapplication"
First, if you are using latest version of docker compose you don't need the link argument in you app service. I quote the docker compose documentation Warning: The --link flag is a legacy feature of Docker. It may eventually be removed. Unless you absolutely need to continue using it, https://docs.docker.com/compose/compose-file/#links
I think the solution is to use the networks argument. This create a docker network and add each service to it.
Try this
version: "2"
services:
app:
container_name: golang
restart: always
build: .
ports:
- "49160:8800"
networks:
- my_network
depends_on:
- "mysql"
mysql:
image: mysql
container_name: mysql
volumes:
- dbdata:/var/lib/mysql
restart: always
networks:
- my_network
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE=testDB
- MYSQL_USER=root
- MYSQL_PASSWORD=root
ports:
- "3307:3306"
volumes:
dbdata:
networks:
my_network:
driver: bridge
By the way, if you only connect to Mysql from your app service you don't need to expose the mysql port. If the containers runs in the same network they can reach all ports inside this network.
If my example doesn't works try this
run the docker compose and next go into the app container using
docker container exec -it CONTAINER_NAME bash
Install ping in order to test connection and then run ping mysql.
I'm currently trying to deploy an application with docker swarm in 3 virtual machines, I'm doing it through docker-compose to create the image, my files are the following:
Dockerfile:
FROM openjdk:8-jdk-alpine
WORKDIR /home
ARG JAR_FILE
ARG PORT
VOLUME /tmp
COPY ${JAR_FILE} /home/app.jar
EXPOSE ${PORT}
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/home/app.jar"]
and my docker-compose is:
version: '3'
services:
service_colpensiones:
build:
context: ./colpensiones-servicio
dockerfile: Dockerfile
args:
JAR_FILE: ColpensionesServicio.jar
PORT: 8082
volumes:
- data:/home
ports:
- 8082:8082
volumes:
data:
I'm using the command docker-compose up -d --build to build the image, I automatically create the container which is deleted later. To use docker swarm I use the 3 machines, one manager and two worker, I have another file to deploy the service with 3 replicas
version: '3'
services:
service_colpensiones:
image: deploy_lyra_colpensiones_service_colpensiones
deploy:
replicas: 5
resources:
limits:
cpus: "0.1"
memory: 50M
restart_policy:
condition: on-failure
volumes:
- data:/home
ports:
- 8082:8082
networks:
- webnet
visualizer:
image: dockersamples/visualizer:stable
ports:
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
deploy:
placement:
constraints: [node.role == manager]
networks:
- webnet
networks:
webnet:
volumes:
data:
So far I think everything is fine because in the console with the command: docker service ls I see the services created, the viewer dockersamples / visualizer: stable, shows me the nodes correctly on port 8080, but when I want to make a request to the url of the services that is in the following way:
curl -4 http://192.168.99.100:8082/colpensiones/msg
the error appears:
curl: (7) Failed to connect to 192.168.99.100 port 8082: Refused connection.
The images from service are:
I am following the docker tutorial: Get Started https://docs.docker.com/get-started/part5/
I hope your help, thanks
I had the same issue but fixed after changing the port number of the spring boot service to
ports:
- "8082:8080"
The actual issue is: tomcat server by default listening on port 8080 not the port mentioned on the compose file. Also i increased the memory limit.
FYI: The internal port of the tasks/container running in the service can be same for other containers as well(:) so mentioning 8080(internal port) for both spring boot container and visualizer container is not a problem.
I also faced the same issue for my application. I rebuilt my app by removing from Dockerfile => -Djava.security.egd=file:/dev/./urandom java cmdline property, and it started working for me.
Please check "docker service logs #containerid#" (to see container ids run command "docker stack ps #servicename#") which served you request at that time, and see if you see any error message.
PS: I recently started on docker, so might not be an expert advice. Just in case if it helps.