VivekDev
VivekDev

Reputation: 25517

Does docker compose create port mappings automatically?

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.

Add docker support to visual studio project

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

Answers (2)

VivekDev
VivekDev

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

Fabian Desnoes
Fabian Desnoes

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

Related Questions