I'm working on a project in Azure DevOps and my basic goal is to run End2End Tests in the CI Pipeline. For that, I try to serve the Backend with docker-compose and also let the backend Deliver the Frontend by serving it from wwwroot as static files.
Here is my docker-compose:
version: "3.8"
volumes:
mongo-data:
services:
mongodb:
image: mongo:latest
container_name: ticket-machine-mongodb
ports:
- "27017:27017"
environment:
- MONGO_INITDB_ROOT_USERNAME=admin
- MONGO_INITDB_ROOT_PASSWORD=password
volumes:
- mongo-data:/data/db
healthcheck:
test: echo 'db.runCommand("ping").ok' | mongosh localhost:27017/test --quiet
interval: 5s
timeout: 1s
retries: 10
backend:
container_name: ticket-machine-backend
build:
context: ./
dockerfile: Dockerfile
environment:
- ASPNETCORE_ENVIRONMENT=Test
- CI=true
depends_on:
mongodb:
condition: service_healthy
ports:
- "5173:5000"
- "5000:5000"
The Dockerfile looks like this:
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
WORKDIR /app
EXPOSE 5000
COPY ./app/ .
ENTRYPOINT ["dotnet", "VHS.TicketMachine.Web.dll"]
Most of this I got from a different project within my company and tried to modify it to work for me as well. When I run my things locally like
dotnet publish --nologo --no-restore --configuration Release --output image/app
Copy-Item -Path "C:\Users\lejm\RiderProjects\VHS-TicketMachine\VHS.TicketMachine.Frontend\dist" -Destination "image\app\wwwroot" -Recurse -Force
docker-compose -f .\image\docker-compose.vhs.yml up -d
It works just fine. It runs on port 5000 and 5173, I can access my frontend content and requests are made to the backend successfully. My End 2 End tests also run when It's running in the container.
Now here's the CI-Pipeline (part of it):
# ... Install Node, npm i, npm run build
- task: DotNetCoreCLI@2
displayName: Publish Backend
inputs:
zipAfterPublish: false
modifyOutputPath: false
command: publish
arguments: >-
--nologo
--no-restore
--configuration Release
--output image/app
- task: CopyFiles@2
displayName: Publish Frontend
inputs:
sourceFolder: $(frontendDir)/dist
targetFolder: image/app/wwwroot
- script: |
docker-compose -f ./image/docker-compose.vhs.yml up -d
displayName: "Run Docker image"
- script: |
export VITE_FRONTEND_URL=http://localhost:5173/
npx playwright install --with-deps chromium
npx playwright test
displayName: Run End 2 End Tests
workingDirectory: $(frontendDir)
The End 2 End Tests respond with this:
Error: page.goto: net::ERR_CONNECTION_REFUSED at http://localhost:5173/question Call log: - navigating to "http://localhost:5173/question", waiting until "load"
And it also failed my curl health checks. I tried with network_mode: "host", but it didn't do anything, apparently it doesn't work in windows pipelines, although I thought I'm on ubuntu anyways, I'm not sure though. Also used a custom bridge network, which gave the same result. (All of these things worked locally btw.) I also tried running on docker.host.internal instead of localhost, but that doesn't work as well. I don't really know what to try anymore and I don't understand what exactly doesn't work here. (I'm not very experienced with docker). I would really appreciate if someone could help me out here, thank you!
In a Dockerized setup, localhost does not refer to the host machine or other containers but to the container itself. When using Docker Compose, services communicate with each other via their service names defined in the docker-compose.yml file. So, instead of:
mongodb://admin:password@localhost:27017
You should use:
mongodb://admin:password@mongodb:27017
Here, mongodb is the service name for your MongoDB container as defined in your docker-compose.yml. Docker's internal networking will resolve this name to the appropriate container. To ensure this configuration only applies in your CI environment, you can set it conditionally through environment variables or CI-specific configuration files. For example, in your .env file for CI:
MONGO_CONNECTION_STRING=mongodb://admin:password@mongodb:27017
Then make sure your application reads this value dynamically.