9

I'm trying to get the IP address of my docker container as an environment variable within the container. Here is what I've tried:

When starting the container

docker run -dPi -e ip=`hostname -i` myDockerImage

When the container is already booted up

docker exec -it myDockerImage bash -c "export ip=`hostname -i`"

The problem with these two methods is that it uses the ip address of the host running the commands, not the docker container it's being run on.

So then I created a script inside the docker container that looks like this:

#!/bin/bash
export ip=`hostname -i`
echo $ip

And then run this with

docker exec -it myDockerImage bash -c ". ipVariableScript.sh"

When I add my_cmd which in my case is bash to the end of the script, it works in that one session of bash. I can't use it later in the files I need it in. I need to set it as an environment variable, not as a variable for one session.

So I already sourced it with the '.'. But it still won't echo when I'm in the container. If I put an echo $ip in the script, it will give me the correct IP address. But can only be used from within the script it's being set in.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Tijn
  • 264
  • 2
  • 10
  • Possible duplicate of [How to set an environment variable in a running docker container](http://stackoverflow.com/questions/27812548/how-to-set-an-environment-variable-in-a-running-docker-container) – vitr Aug 25 '16 at 07:55
  • sorry, but it seems impossible and I believe it's a duplication, correct me if I misread your question – vitr Aug 25 '16 at 07:57
  • The question you set as a duplicate offers a solution for one bash session. I edited the question to explain this. Also I'm not using a set variable, but the IP adress, which has to be called from within the container to have the correct value. – Tijn Aug 25 '16 at 08:02
  • yes, this is the point, docker can't do it, as explained here https://github.com/docker/docker/issues/8838 – vitr Aug 25 '16 at 08:05
  • Ok, I already read that link, but I thought maybe there would be a workaround by now, since most of that thread originated in 2015. I'll look for a workaround with file writing or something. If I find anything I'll post it here. Thanks for your help! – Tijn Aug 25 '16 at 08:07
  • 2
    Why do you have to deal with an ip address in the first place? You should rely on dns names instead (service name). Docker will take care of redirecting or load balancing traffic to the correct container. – Bernard Aug 25 '16 at 15:17
  • I'm running Selenium tests, and the tests need to redirect to the correct location. If it's the IP adress or the dns name is irrelevant, the variable problem stays the same. – Tijn Aug 29 '16 at 06:45

3 Answers3

2

Service names in Docker are more reliable and easier to use. However, here's

How to assign Docker guest IP to environment var inside guest

$ docker run -it ubuntu bash -c 'IP=$(hostname -i); echo ip=$IP'
ip=172.17.0.76
johntellsall
  • 14,394
  • 4
  • 46
  • 40
1

So, this is an old question but I ended up with the same question yesterday and my solution is this: use the docker internal option.

My containers were working fine but at some point the ip changed and I needed to change it on my docker-compose. Of course I can use the "docker network inspect my-container_default" and get my internal IP from that, but this also means changing my docker-compose every time the ip changes (and I'm still not that familiar with docker in order to detect IP changes automatically or make a more sofisticated config). So, I use the "host.docker.internal" flag. Now I no more need to check what's my IP from docker and everything is always connected.

Here an example of a node app which uses elastic search and needs to connect.

version: '3.7'

services:
  api:
    ...configs...
    depends_on:
      - 'elasticsearch'
    volumes:
      - ./:/usr/local/api
    ports:
      - '3000:80'
    links:
      - elasticsearch:els
    environment:
      - PORT=80
      - ELASTIC_NODE=http://host.docker.internal:9200
  elasticsearch:
    container_name: 'els'
    image: docker.elastic.co/elasticsearch/elasticsearch:7.13.4
    ...elastic search container configs...
    ports:
      - '9200:9200'
    expose:
      - 9200
    networks:
      - elastic

networks:
  elastic:
    driver: bridge

Note the "ELASTIC_NODE=http://host.docker.internal:9200" on api environments and the "network" that the elastic search container is using (on bridge mode)

This way you don't need to worry about knowing your IP.

mend3
  • 506
  • 4
  • 15
0

The container name is postgres in this example. It is a bit clumsy, but it delivers.

container_ip=$(docker inspect postgres -f "{{json .NetworkSettings.Networks }}" \
  | awk -v FS=: '{print $9}' \
  | cut -f1 -d\, \
  | echo "${container_ip//\"}")

Make a function out of it:

#!/usr/bin/env bash

set -o errexit
set -o nounset
set -eu -o pipefail
#set -x
#trap read debug
    
#assign container ip address to variable
function get_container_ip () {
    container_ip=$(docker inspect "$1" -f "{{json .NetworkSettings.Networks }}" \
      | awk -v FS=: '{print $9}' \
      | cut -f1 -d\,)

    container_ip=$(echo "${container_ip//\"}")
}

get_container_ip $1
echo "$container_ip"
Arkham Angel
  • 309
  • 1
  • 5
  • 18