How to get Docker host IP on Travis CI?

2019-06-24 08:02发布

问题:

I have a Rails repo on Travis. It has a docker-compose.yml file:

postgres:
  image: postgres
  ports:
    - "5433:5432"
  environment:
    - POSTGRES_USER=calories
    - POSTGRES_PASSWORD=secretpassword

(I had to use 5433 as the host port because 5432 gave me an error: Error starting userland proxy: listen tcp 0.0.0.0:5432: bind: address already in use)

And a travis.yml:

sudo: required

services:
  - docker
language: ruby
cache: bundler
before_install:
  # Install docker-compose
  - curl -L https://github.com/docker/compose/releases/download/1.4.0/docker-compose-`uname -s`-`uname -m` > docker-compose
  - chmod +x docker-compose
  - sudo mv docker-compose /usr/local/bin
  # TODO: Remove this temporary fix when it's safe to:
  # https://github.com/travis-ci/travis-ci/issues/4778
  - sudo iptables -N DOCKER || true
  - sleep 10
  - docker-compose up -d
before_script:
  - bundle exec rake db:setup
script:
  - bundle exec rspec spec
after_script:
  - docker-compose stop
  - docker-compose rm -f

I am trying to figure out what to put in my database.yml so my tests can run on Travis CI. In my other environments, I can do:

adapter: postgresql
encoding: unicode
host:  <%= `docker-machine ip default` %>
port: 5433
username: calories
password: secretpassword
# For details on connection pooling, see rails configuration guide
# http://guides.rubyonrails.org/configuring.html#database-pooling
pool: 5

But unfortunately this doesn't work on Travis because there is no docker-machine on Travis. I get an error: docker-machine: command not found

How can I get the Docker host's IP on Travis?

回答1:

I think what you want is actually the container IP, not the docker engine IP. On your desktop you had to query docker-machine for the IP because the VM docker-machine created wasn't forwarding the port.

Since you're exposing a host port, you can actually use localhost for the host value.

There are two other options as well:

  • run the tests in a container and link to the database container, so you can just use postgres as the host value.
  • if you don't want to use a host port, you can use https://github.com/swipely/docker-api (or some other ruby client) to query the docker API for the container IP, and use that for the host value. Look for the inspect or inspect container API call.


回答2:

For others coming across this, you should be able to get the host IP by running

export HOST_IP_ADDRESS="$(/sbin/ip route|awk '/default/ { print $3 }')"

from within the container. You can then edit your database configuration via a script to insert this in - it'll be in the $HOST_IP_ADDRESS variable.

However like dnephin said, I'm not sure this is what you want. This would probably work if you were running Travis' Postgres service and needed to access it from within a container (depending on which IP address they bind it to).

But, it appears you're running it the opposite way to this, in which case I'm fairly sure localhost should get you there. You might need to try some other debugging steps to make sure the container has started and is ready, etc.

EDIT: If localhost definitely isn't working, have you tried 127.0.0.1?