Reputation: 25517
I created a simple asp.net core app in Visual Studio 2019 and added docker support.
Dockerfile, .dockerignore, and docker-compose file are all created.
In a command prompt I navigate to the folder docker-compose.yml file is present and then run the command
docker-compose up
I see that the containers are created and port mappings happen so that I can browse the web app in the browser.
So when I run the following inspect command on the container
docker inspect --format="{{ .NetworkSettings.Ports}}" ContainerId
I get something like this
map[80/tcp:[{0.0.0.0 32782}]]
So now I can browse the app with http://localhost:32782/index.html
Next if I tear down the containers with
docker-compose down
the containers are stopped and deleted. Created image remains.
Now when I do a docker run against that image to start a container
docker run -it --rm ae39
a new container is created but I am not able to browse the app because there is no port mapping from container to host. I have to explicitly specify this when I use the run command. Only then I am able to browse the app running inside of the container form the host.
But when I use docker compose I dont have to specify the port mapping. Something magical happens and the ports mappings are created for me. Note that the docker-compose.yml file is plane vanilla and does not contain any port mappings. So also the Dockerfile. They are included below for reference.
My question is does docker compose automatically create port mappings? If so how? Of is that is to do something with Visual Studio 2019
version: '3.4'
services:
generator31:
image: ${DOCKER_REGISTRY-}generator31
build:
context: .
dockerfile: generator31/Dockerfile
And the dockerfile is here.
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
WORKDIR /src
COPY ["generator31/generator31.csproj", "generator31/"]
RUN dotnet restore "generator31/generator31.csproj"
COPY . .
WORKDIR "/src/generator31"
RUN dotnet build "generator31.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "generator31.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "generator31.dll"]
Upvotes: 3
Views: 3866
Reputation: 25517
I think I found the answer.
The key is the config command
docker-compose config
After I run that command, I see the following.
services:
generator31:
build:
context: D:\Trials\Docker\aspnetcore311\generator31
dockerfile: generator31/Dockerfile
environment:
ASPNETCORE_ENVIRONMENT: Development
image: generator31
ports:
- target: 80
version: '3.4'
I see ports, and also environment. In the docker compose file I pasted in the question, they are not present. So where did they come from?
I open the folder in file explorer, and I see docker-compose.override.yml file sitting quietly next to docker-compose.yml file. Open that file and I get the answer. ports is defined there. Docker compose command picks up the configuration from multiple files, docker-compose.override.yml is one such file. And now this so ans should help as Fabian-Desnoes suggsted.
Upvotes: 2
Reputation: 21
By having the EXPOSE tag in your dockerfile, it tells the platform that you are using that you need that port to be mapped. When using docker-compose, it will see this and automatically map this to a random open port. The EXPOSE keyword doesn't however expose any ports. It is just used to say to the platform you are using "Could you expose this port for me" and relies on the platform to do it for you.
If you want the ports to be mapped to a specific port every time on your host machine then you can add 'ports' to the service in you docker-compose.yml (host_machine_port:container_port)
Upvotes: 2