microsoft / DockerTools

Tools For Docker, including Visual Studio Provisioning and Publishing
Other
173 stars 26 forks source link

How can I add a custom host to my container at a debug level with Visual Studio? #373

Closed igorrates closed 1 year ago

igorrates commented 1 year ago

I have multiple services running and I'm containerizing them, so I will have numerous docker containers for each one.

Today I can have something like this at the end of my Dockerfile to set a custom host when I use the docker build and docker run commands:

CMD ["/bin/bash", "/add-hosts-and-start-app.sh", "my.host.com"]

And the script looks like this to add the new host to the host file at runtime:

#!/bin/bash

# Get the container's IP address
CONTAINER_IP=$(hostname -i)

# Get the domain name from the first command-line argument
DOMAIN_NAME="$1"

# Append the domain name to the IP address
HOSTS_ENTRY="$CONTAINER_IP    $DOMAIN_NAME"

echo "$HOSTS_ENTRY"

# Add the entry to the /etc/hosts file
echo "$HOSTS_ENTRY" >> /etc/hosts

# Start the application with the LocalHTTPS launch profile
dotnet "my-app.dll" --launch-profile LocalHTTPS

My problem becomes when I need to add that custom host for debugging: I could use the tag on csproj to pass some additional run arguments but I'm afraid I don't know the IP the container would take. <DockerfileRunArguments>-p 5007:5007 --network endor-net --add-host=my.host.com:<The IP></DockerfileRunArguments>

My Dockerfile is a multistaged one and I know that for fast debugging, it will not run the entire docker file when building the image. Is it possible to get the same .sh script to run at debug level and set the custom host I need?

danegsta commented 1 year ago

@igorrates do you have to call the hostname -i command or would using the local loopback IP of 127.0.0.1 allow you to use --ad-host=my.host.com:127.0.0.1 and not have to run the script?

igorrates commented 1 year ago

@igorrates do you have to call the hostname -i command or would using the local loopback IP of 127.0.0.1 allow you to use --ad-host=my.host.com:127.0.0.1 and not have to run the script?

@danegsta I have a multistage dockerfile. Visual Studio has this Fast debugger mode where it only builds the initial stage when I set the tag ContainerDevelopmentMode to Fast, I can set another tag to build until a certain stage which I did to build the first two I have, but I didn't want to set ContainerDevelopmentMode to Regular where it builds the entire dockerfile to create the container. The tag I'm talking about for the stages I want to build is the <DockerfileFastModeStage>debug</DockerfileFastModeStage>

If I set the tag ContainerDevelopmentMode to regular, everything will work just fine, but the container can take some time to build, that's why wanted to find a solution where I could set a custom host for the container in Visual Studio. One of the options I could think of would be to pass additional arguments using the DockerfileRunArguments tag but I realized I don't have a way to fetch the container's IP when I hit F5 in VS.

danegsta commented 1 year ago

@igorrates inside the container, 127.0.0.1 should resolve to the container itself, not the local system, so --add-host=my.host.com:127.0.0.1 would give you a hosts entry with my.host.com that resolves to the application in the container. You may want to test and see if this would work as an alternative to needing the script in the first place, since it would potentially remove the need to know the runtime network IP address when setting your hosts entry.

igorrates commented 1 year ago

@danegsta Am I going to be able to access this host from another container in the same named network? Like doing a request to it? I want to be able to send a request my.host.com/api/my-endpoint from another container

danegsta commented 1 year ago

@igorrates if you goal is to set a hostname by which a container can be accessed from other containers on the network, I'd recommend either using Docker Compose to configure services (which gives you the ability to specify specific DNS names a service should be accessible from) or create a custom Docker bridge network and run your containers using that network instead of the default bridge network (this second option is technically what Docker Compose is doing to manage container networking).

If you don't want to use Compose, the default Docker bridge network doesn't support custom DNS names for containers, which is why you have to setup the hosts entries manually. However, if you create your own network docker network create <network name>, the newly created network will manage DNS record for your containers if you assign them hostnames with some combination of the --hostname and --dnsname arguments (--hostname acts as a prefix to any DNS name specified wth --dnsname). You can attach a container to a custom network by adding --network <network name> to your run settings.

Here's the Docker docs on connecting containers to a custom network: https://docs.docker.com/engine/reference/commandline/run/#network

danegsta commented 1 year ago

@igorrates sorry, I just noticed you're already doing using a custom network; you should be able to get away with just using --hostname my.host.com or --hostname my --dnsname host.com without needing to do any extra work to map container IP addresses.

igorrates commented 1 year ago

@danegsta thank you very much! I haven't see the --dnsname in the docs. I'll try that

igorrates commented 1 year ago

Unfortunately the --dnsname is an unknown flag, but the --hostname flag works perfectly!!!!

image

dbreshears commented 1 year ago

Thanks for confirmation. Closing this