Trouble connecting to Redis / setup_remote_docker

Hi everyone,

Apologies for the question that has already been addressed, but I am new to CircleCI and I am having trouble converting 1.0 project to 2.0.

First, here’s my circle.yml :

 It should include any build commands you had along with commands that CircleCI
 inferred from your project structure. We strongly recommend you read all the
 comments in this file to understand the structure of CircleCI 2.0, as the idiom
 for configuration has changed substantially in 2.0 to allow arbitrary jobs rather
 than the prescribed lifecycle of 1.0. In general, we recommend using this generated
 configuration as a reference rather than using it in production, though in most
 cases it should duplicate the execution of your original 1.0 config.
version: 2
jobs:
    build:
        working_directory: ~/pocket-playlab/Juice-Cubes-backend
        parallelism: 1
        shell: /bin/bash --login
        # CircleCI 2.0 does not support environment variables that refer to each other the same way as 1.0 did.
        # If any of these refer to each other, rewrite them so that they don't or see  .
        environment:
          CIRCLE_ARTIFACTS: /tmp/circleci-artifacts
          CIRCLE_TEST_REPORTS: /tmp/circleci-test-results
          CURRENT_IP: $(dig +short myip.opendns.com @resolver1.opendns.com)
          REDIS_URL: "redis://localhost:6379/2"
        # In CircleCI 1.0 we used a pre-configured image with a large number of languages and other packages.
        # In CircleCI 2.0 you can now specify your own image, or use one of our pre-configured images.
        # The following configuration line tells CircleCI to use the specified docker image as the runtime environment for you job.
        # We have selected a pre-built image that mirrors the build environment we use on
        # the 1.0 platform, but we recommend you choose an image more tailored to the needs
        # of each job. For more information on choosing an image (or alternatively using a
        # VM instead of a container) see 
        # To see the list of pre-built images that CircleCI provides for most common languages see
        # 
        docker:
        - image: circleci/build-image:ubuntu-14.04-XXL-upstart-1189-5614f37
          command: /sbin/init
        - image: redis
        steps:
        # Machine Setup
        #   If you break your build into multiple jobs with workflows, you will probably want to do the parts of this that are relevant in each
        # The following `checkout` command checks out your code to your working directory. In 1.0 we did this implicitly. In 2.0 you can choose where in the course of a job your code should be checked out.
        - checkout
        - setup_remote_docker:
            docker_layer_caching: true
        # Prepare for artifact and test results  collection equivalent to how it was done on 1.0.
        # In many cases you can simplify this from what is generated here.
        # 'See docs on artifact collection here 
        - run: mkdir -p $CIRCLE_ARTIFACTS $CIRCLE_TEST_REPORTS
        # This is based on your 1.0 configuration file or project settings
        - run:
            working_directory: ~/pocket-playlab/Juice-Cubes-backend
            command: 'sudo docker info >/dev/null 2>&1 || sudo service docker start; '
        # Checkout
        #   This would typically go in either a build or a build-and-test job when using workflows
        # This is based on your 1.0 configuration file or project settings
        - run: find . -exec touch -t 201401010000 {} \;
        - run: for x in $(git ls-tree --full-tree --name-only -r HEAD); do touch -t $(date -d "$(git log -1 --format=%ci "${x}")" +%y%m%d%H%M.%S) "${x}"; done
        # Dependencies
        #   This would typically go in either a build or a build-and-test job when using workflows
        # Restore the dependency cache
        - run:
            name: Dockerize v0.6.0
            command: |
               wget [removedhttp-new-user]jwilder/dockerize/releases/download/v0.6.0/dockerize-linux-amd64-v0.6.0.tar.gz
               sudo rm -rf /usr/local/bin/dockerize
               sudo tar -C /usr/local/bin -xzvf dockerize-linux-amd64-v0.6.0.tar.gz
               rm dockerize-linux-amd64-v0.6.0.tar.gz
        - run:
            name: Wait for Redis
            command: |
                dockerize -wait [removed-link]localhost:6379 -timeout 2m
        - restore_cache:
            keys:
            # This branch if available
            - v1-dep-{{ .Branch }}-
            # Default branch if not
            - v1-dep-master-
            # Any branch if there are none on the default branch - this should be unnecessary if you have your default branch configured correctly
            - v1-dep-
        # This is based on your 1.0 configuration file or project settings
        - run: sudo pip install awscli
        - run: wget [removed-link]/coreos/etcd/releases/download/v2.3.0/etcd-v2.3.0-linux-amd64.tar.gz
        - run: tar xzvf etcd-v2.3.0-linux-amd64.tar.gz
        - run: sudo cp etcd-v2.3.0-linux-amd64/etcd* /usr/local/bin/
        # This is based on your 1.0 configuration file or project settings
        - run: mkdir -p ~/docker
        - run: if [[ -e ~/docker/juice-cubes-backend.tar ]]; then docker load -i ~/docker/juice-cubes-backend.tar; fi
        - run: docker build -t pocketplaylab/juice-cubes-backend:$CIRCLE_BRANCH .
        - run: docker save "pocketplaylab/juice-cubes-backend:$CIRCLE_BRANCH" > ~/docker/juice-cubes-backend.tar
        # Save dependency cache
        - save_cache:
            key: v1-dep-{{ .Branch }}-{{ epoch }}
            paths:
            # This is a broad list of cache paths to include many possible development environments
            # You can probably delete some of these entries
            - vendor/bundle
            - ~/virtualenvs
            - ~/.m2
            - ~/.ivy2
            - ~/.bundle
            - ~/.go_workspace
            - ~/.gradle
            - ~/.cache/bower
            # These cache paths were specified in the 1.0 config
            - ~/docker
        # This is based on your 1.0 configuration file or project settings
        - run: docker run -e RAILS_ENV=test -e RACK_ENV=test pocketplaylab/juice-cubes-backend:$CIRCLE_BRANCH bundle exec rake db:create db:schema:load --trace
        # Test 
        #   This would typically be a build job when using workflows, possibly combined with build
        # This is based on your 1.0 configuration file or project settings
        - run: etcd --data-dir /tmp/etcd --name test & sleep 2 && docker run -v /usr/local/bin/etcdctl:/usr/local/bin/etcdctl --net=host -e RAILS_ENV=test pocketplaylab/juice-cubes-backend:$CIRCLE_BRANCH bundle exec rspec
        # Deployment
        # Your existing circle.yml file contains deployment steps.
        # The config translation tool does not support translating deployment steps
        # since deployment in CircleCI 2.0 are better handled through workflows.
        # See the documentation for more information [removed-link]/docs/2.0/workflows/
        # Teardown
        #   If you break your build into multiple jobs with workflows, you will probably want to do the parts of this that are relevant in each
        # Save test results
        - store_test_results:
            path: /tmp/circleci-test-results
        # Save artifacts
        - store_artifacts:
            path: /tmp/circleci-artifacts
        - store_artifacts:
            path: /tmp/circleci-test-results
    # deploy step
    deploy_stage:
        machine:
            enabled: true
        steps:
            - run: |
                docker login -e $DOCKER_EMAIL -u $DOCKER_USER -p $DOCKER_PASS
                docker push pocketplaylab/juice-cubes-backend:$CIRCLE_BRANCH
                aws ec2 authorize-security-group-ingress --region=us-east-1 --group-id sg-f05b2b8c --protocol tcp --port 22 --cidr $CURRENT_IP/32; sleep 5
                ./deploy.sh staging :
                    timeout: 600
                aws ec2 revoke-security-group-ingress --region=us-east-1 --group-id sg-f05b2b8c --protocol tcp --port 22 --cidr $CURRENT_IP/32; sleep 5
    deploy_prod:
        machine:
            enabled: true
        steps:
            - run: |
                docker login -e $DOCKER_EMAIL -u $DOCKER_USER -p $DOCKER_PASS
                docker push pocketplaylab/juice-cubes-backend:$CIRCLE_BRANCH
                aws ec2 authorize-security-group-ingress --region=us-east-1 --group-id sg-f05b2b8c --protocol tcp --port 22 --cidr $CURRENT_IP/32; sleep 5
                ./deploy.sh production :
                  timeout: 600
                aws ec2 revoke-security-group-ingress --region=us-east-1 --group-id sg-f05b2b8c --protocol tcp --port 22 --cidr $CURRENT_IP/32; sleep 5
workflows:
  version: 2
  build-deploy:
    jobs:
      - build
      - deploy_stage:
          requires:
            - build
          filters:
            branches:
              only: development
      - deploy_prod:
          requires:
            - build
          filters:
            branches:
             only: master

At first, it wouldn’t connect to [removed-link]localhost:6379

#!/bin/bash --login
dockerize -wait [removed-link]localhost:6379 -timeout 2m
2018/07/12 08:22:32 Waiting for: [removed-link]localhost:6379
2018/07/12 08:22:32 Problem with dial: dial tcp 127.0.0.1:6379: getsockopt: connection refused. Sleeping 1s
2018/07/12 08:22:33 Problem with dial: dial tcp 127.0.0.1:6379: getsockopt: connection refused. Sleeping 1s
2018/07/12 08:22:34 Problem with dial: dial tcp 127.0.0.1:6379: getsockopt: connection refused. Sleeping 1s

I resolved this by adding the redis image under docker and it connects fine :

#!/bin/bash --login
dockerize -wait [removed-link]localhost:6379 -timeout 2m
2018/07/12 08:38:04 Waiting for: [removed-link]localhost:6379
2018/07/12 08:38:04 Connected to [removed-link]localhost:6379

Then I call setup_remote_docker and the build fails because it can’t connect to redis (I am assuming we are now on the remote docker environment)

  1. InfoController#status should render 503 when there is no level data
    Failure/Error: Unable to find matching line from backtrace
    Redis::CannotConnectError:
    Error connecting to Redis on localhost:6379 (ECONNREFUSED)

It fails during bundle exec rspec

Anyone could help a lost soul figuring this out?
Thanks in advance.
Nico

1 Like

Hi @nico , I recently build a CI pipeline which needed to connect to a postgreSQL DB for running some tests.
Things to understand about CircleCI (via circles docs):

  • docker run/build/push commands require the setup_remote_docker key and these commands will run in a different environment (remote) than your primary build image.
  • if you supply additional docker images, like redis/mongo/mysql… these will be made available to the primary build environment (i.e. localhost)
  • services you start yourself with docker run cannot be accessed directly. there is no way of connecting to the published ports from your primary build image shell script or connecting from a started docker container back to the dbs attached to the primary image
  • you cannot directly mount files as a volume to a container but you can use a workaround as described in the docs

so what does that mean now?

  • if you need to run a DB for integration tests or so, dont docker run yourself but use the secondary image option and run your not-containerized-code against it
    OR
    use docker-compose (preinstalled in circleci images) to bring up DB + containerized application altogether on the remote docker host so they can communicate
  • docker build/run/push in remote docker and as a build type use docker with an image that has docker client installed. so you dont need to use machine (slow startup) and/or install docker yourself

I suggest reading the docker-related docs here https://circleci.com/docs/2.0/build/

For my part i.e. what doesnt work:
if you have an iOS application, it requires building in macos type. however, if you need it to run tests or so against a service you dockerized in another build step. it wont work. macos doesnt support running docker.
then the only solution afaik is to deploy the containerized services to a remote integration setup (k8s, swarm…) and then run the test against that external service

4 Likes

Thanks @philicious
As mentioned, not a devops, and my attempts to migrate have been unsuccessful.
So in my case, how would you use the secondary image to run my code against it at this level?

run: etcd --data-dir /tmp/etcd --name test & sleep 2 && docker run -v /usr/local/bin/etcdctl:/usr/local/bin/etcdctl --net=host -e RAILS_ENV=test pocketplaylab/juice-cubes-backend:$CIRCLE_BRANCH bundle exec rspec 
1 Like

OK, we managed to migrate a simpler project to 2.0, thanks to your help. We will continue working on this one and hopefully migrate it successfully by the end of the week!

1 Like

@philicious - great notes, thanks. I’d add to that though that if you use Docker Compose inside a single CircleCI build container, most of those limitations do not apply. You can connect from one container to another as much as you like - it is just more work to set up. You have to pull your own images into place, and maintain a docker-compose.yml config.

I’ve been using DC in CircleCI for about a year, and it’s rock solid - partly also because I use very simple parent images, so features changes in convenience images do not affect me. It also means I can run my integration tests the same on local as I do on CI.

The one limitation that still does apply is attaching on-host directories as on-container volumes. They would have to span multiple machines, and that does not work with ordinary volumes. However, you can attach non-running volume containers.

1 Like

@halfer thanks. and yes you are right, started containers (e.g. by docker-compose) can communicate with each other without problems. I updated my post a bit to point that out

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