Reputation: 12255
I want to get the IP address of a container so that I can set that IP address as an environmental variable.
docker-compose.yml
django:
build: .
command: python /app/project/manage.py test --liveserver=172.18.0.4:8081 //hard coded - trying to avoid this
ports:
- "8000:8000"
- "8081:8081"
selenium:
container_name: selenium
image: selenium/standalone-firefox-debug:2.52.0
ports:
- "4444:4444"
- "5900:5900"
The problem is that in order to run correctly django needs either:
A. set --liveserver
python /app/manage.py test --liveserver=django-appnet-ip:port
B. or I set environmental variable:
DJANGO_LIVE_TEST_SERVER_ADDRESS=django-appnet-ip:port
Problem is that the ip address for the docker container isn't set until the container is created. So how can I pass the IP address to django?
What I have tried so far...
A. Creating a django management command that calls the script that then calls a management command:
class Command(BaseCommand):
def add_arguments(self, parser):
// I would have to redefine all the arguments because
//I can't call super on django/core/management/commands/test.py
...
B. Referring to the app itself in DJANGO_LIVE_TEST_SERVER_ADDRESS 'django:8081' only works if in docker-compose with this configuration:
django:
build: .
net: appnet
command: python /app/project/manage.py test
ports:
- "8000:8000"
- "8081:8081"
environment:
- DJANGO_LIVE_TEST_SERVER_ADDRESS=django:8081 # where django is the name of the app
If I set the command to blank, then from the command line run:
docker-compose run django python /app/project/manage.py test
I get
======================================================================
ERROR: setUpClass (django_behave.runner.DjangoBehaveTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/usr/local/lib/python2.7/site-packages/django/test/testcases.py", line 1354, in setUpClass
raise cls.server_thread.error
error: [Errno 99] Cannot assign requested address
----------------------------------------------------------------------
The Question
How can I pass a container's ip address it a network to the container so that the command the container runs gets the IP address?
Or maybe there is a completely different approach to this problem?
Upvotes: 1
Views: 4163
Reputation: 12255
I made a bash script to get the docker container id, then use that id to get the ip address for that container id from the container's /etc/hosts.
In django Dockerfile
ENTRYPOINT ["/entrypoint.sh"]
entrypoint.sh
#!/bin/bash
set -e
# Now we need to get the ip address of this container so we can supply it as an environmental
# variable for django so that selenium knows what url the test server is on
# only add if 'manage.py test' in the args
if [[ "'$*'" == *"manage.py test"* ]]
then
# get the container id
THIS_CONTAINER_ID_LONG=`cat /proc/self/cgroup | grep 'docker' | sed 's/^.*\///' | tail -n1`
# take the first 12 characters - that is the format used in /etc/hosts
THIS_CONTAINER_ID_SHORT=${THIS_CONTAINER_ID_LONG:0:12}
# search /etc/hosts for the line with the ip address which will look like this:
# 172.18.0.4 8886629d38e6
THIS_DOCKER_CONTAINER_IP_LINE=`cat /etc/hosts | grep $THIS_CONTAINER_ID_SHORT`
# take the ip address from this
THIS_DOCKER_CONTAINER_IP=`(echo $THIS_DOCKER_CONTAINER_IP_LINE | grep -o '[0-9]\+[.][0-9]\+[.][0-9]\+[.][0-9]\+')`
# add the port you want on the end
# Issues here include: django changing port if in use (I think)
# and parallel tests needing multiple ports etc.
THIS_DOCKER_CONTAINER_TEST_SERVER="$THIS_DOCKER_CONTAINER_IP:8081"
export DJANGO_LIVE_TEST_SERVER_ADDRESS=$THIS_DOCKER_CONTAINER_TEST_SERVER
fi
eval "$@"
alternatively you could have used something like
"$@ --liveserver=$THIS_DOCKER_CONTAINER_TEST_SERVER"
Probably better to set the environmental variable so you can use it in other places.
Upvotes: 4
Reputation: 57056
Is this a container dependency issue? Are you running selenium in a container? docker-compose
suggests 2 or more docker containers, but you only referred to Django container. If this is a container dependency issue, then sadly it's not possible at the moment to use docker-compose
to start one container first before another. You could however use the...
docker wait
...command within a bash script and then use...
docker inspect containerName
...to get the IP address and pass that IP to docker compose.
docker-compose
DOES support use of variables.
Upvotes: 0