Role does not exist

Hi, for some reasons I’m not able to use the postgres DB…

version: 2
jobs:
  build:
    docker:
      - image: docker:18.03.1-ce-git
      - image: circleci/postgres:10.4

    steps:
      - setup_remote_docker
      - checkout

      - run:
          name: Container cleanup
          command: |
            docker stop directory_test || true
            sleep 5
            docker system prune -f

      - run:
          name: Build the image
          command: docker build -t directory .

      - run:
          name: Docker up
          command: >-
            docker container run
            -e DATABASE_URL="postgresql://root:circleci_test@docker.for.mac.localhost:5432/directory?timeout=5000&encoding=utf8&pool=5"
            -e RAILS_ENV=test
            --name directory_test -it -d directory

      - run:
          name: Setup Directory Database
          command: >-
              docker exec
              -e DATABASE_URL="postgresql://root:circleci_test@docker.for.mac.localhost:5432/directory?timeout=5000&encoding=utf8&pool=5"
              -e RAILS_ENV=test
              directory_test bundle exec rake db:create

Error is

Couldn't create database for {"timeout"=>"5000", "encoding"=>"utf8", "pool"=>"5", "adapter"=>"postgresql", "username"=>"root", "password"=>"circleci_test", "port"=>5432, "database"=>"directory_test", "host"=>"docker.for.mac.localhost"}
rake aborted!
ActiveRecord::NoDatabaseError: FATAL:  role "root" does not exist

What am I doing wrong?

1 Like

Hi there! I noticed you’re using rake db:create – could you check that your database.yml has username/password statements set for all environments? Some more discussion available about this here.

It’s supposed to be inside the DATABASE_URL, isn’t it? Here is my database.yml

default: &default
  url: <%= ENV['DATABASE_URL'].gsub('?', ["_", Rails.env, "?"].join) %>

development:
  <<: *default

test:
  <<: *default

production:
  <<: *default

That looks right honestly, works well locally.
My main question is, how I refer to the main container from inside the container that is running the app? Same way I’d use docker.for.mac.localhost

ngw

If I understand you correctly, you are running Docker in Docker, and you want your inner container (app) to reach out to the outer one (CircleCI build container) to connect to a database. I have a similar thing (Docker in VPS) where a Dockerised blog needs to connect to a MySQL instance on the VPS.

To do this:

# Get the host IP address
export DOCKER_HOSTIP=`ifconfig docker0 | grep "inet addr" | cut -d ':' -f 2 | cut -d ' ' -f 1`
echo "Connecting to database on Docker host ${DOCKER_HOSTIP}"

docker run \
    --label $CONTAINER_LABEL \
    --add-host=docker:${DOCKER_HOSTIP} \
    --network dockernet \
    --network-alias myblog \
    --detach \
    --restart always \
    myblog

I can’t remember if network is required for that, but it’s add-host that does the work. Then, inside my container, DOCKER_HOSTIP is available to connect to.

Incidentally, this is not for CircleCI - just general infrastructure - but the principle should be the same for you.

I understand what you’re trying to do, but doesn’t really work for me:

ifconfig: docker0: error fetching interface information: Device not found

When I run ifconfig on CircleCI

ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:AC:16:00:03
          inet addr:172.22.0.3  Bcast:172.22.255.255  Mask:255.255.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:165 errors:0 dropped:0 overruns:0 frame:0
          TX packets:160 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:18715 (18.2 KiB)  TX bytes:22395 (21.8 KiB)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:21 errors:0 dropped:0 overruns:0 frame:0
          TX packets:21 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1
          RX bytes:5645 (5.5 KiB)  TX bytes:5645 (5.5 KiB)

Not sure what the IP I’m searching is, should actually be the IP of the CircleCI/postgres image, isn’t it?

Hmm, that’s odd. By virtue of installing Docker in your CircleCI container, I’d expect to see a docker0 in your networks, since your container has become a Docker host itself.

No, I’ve just spotted how much of a pickle your config is in!

I originally assumed that by virtue of the explicit docker commands, you were running one CircleCI container and inside that running Docker-in-Docker. However, it looks like you are also running a secondary PostgreSQL container.

If this configuration were to work, it would give you two PostgreSQL databases, and I don’t think that is what you want. One would be at the same “Docker level” as your primary build container, and one would be in a Docker system inside your primary build container (which itself is running in Docker, on the build host).

I wonder if your using Docker explicitly is not necessary? I would assume that docker.for.mac.localhost does not resolve (if it does then I don’t know why) and this should be just localhost.

(This is a CircleCI-specific behaviour that merges the networking stacks of all containers into one. It’s slightly messy, but it is pretty convenient (since the address of all services you add can be hardwired in your build config).

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.