Search code examples
dockerdocker-composemockserver

MockServer: Mocking external http/https response refuses connection on 80/443


What I was trying to achieve is mocking the response of google oauth2 endpoint. Here is my setup:

# docker-compose.yml
version: '3.8'

services:
  busybox:
    image: yauritux/busybox-curl:latest
    command: tail -f /dev/null
    networks:
      - our-network

  api-mock:
    image: mockserver/mockserver
    networks:
      our-network:
        aliases:
          - oauth2.googleapis.com
    environment:
      MOCKSERVER_INITIALIZATION_JSON_PATH: /api-mock/expectations_init.json
      MOCKSERVER_WATCH_INITIALIZATION_JSON: 'true'
    volumes:
      - ./api-mock/:/api-mock
    ports:
      - 1080:1080

networks:
  our-network:

Our Mockserver expectations

# ./api-mock/expectations_init.json
[
  {
    "httpRequest": {
      "method": "GET",
      "path": "/token",
      "secure": true
    },
    "httpResponse": {
      "statusCode": 200,
      "body": "Hello World - secure"
    }
  },
  {
    "httpRequest": {
      "method": "GET",
      "path": "/token",
      "secure": false
    },
    "httpResponse": {
      "statusCode": 200,
      "body": "Hello World"
    }
  }
]

my project structure

stackoverflow
    - ./api-mock
        - expectations_init.json
    - docker-compose.yml

To run this minimal example just run

docker-compose up -d

See the dashboard of the mockserver

localhost:1080/mockserver/dashboard

What I expected to work is:

docker exec stackoverflow_busybox_1 curl -k https://oauth2.googleapis.com/token
# curl: (7) Failed connect to oauth2.googleapis.com:443; Connection refused

What worked instead is:

docker exec stackoverflow_busybox_1 curl -k https://oauth2.googleapis.com:1080/token
# Hello World - secure

Same here, expected to work:

docker exec stackoverflow_busybox_1 curl -k http://oauth2.googleapis.com/token
# curl: (7) Failed connect to oauth2.googleapis.com:80; Connection refused

and what worked instead:

docker exec stackoverflow_busybox_1 curl -k http://oauth2.googleapis.com:1080/token
# Hello World

What did I miss to configure to get a response without passing the port, because I have no control about, what URL the vendor code is calling. I can't find any hint for this use case in the documentation of the mockserver to achieve this. Maybe this is an issue of docker/docker-compose?

Best regards


Solution

  • The problem is not in docker-compose but in the mockserver image. Since it's executed without root rights, it cannot use the port 80 but it starts always on the port 1080 (check https://www.mock-server.com/where/docker.html#run_docker_container for more info).

    You can change the port by starting the docker image using this:

    docker run --rm --name mockserver mockserver/mockserver -serverPort 1090
    

    which will let you have the image running on port 1090 (which is not what you want) or you can do force the container to run as root and change the port to 80. e.g.

    docker run --user root --rm --name mockserver mockserver/mockserver -serverPort 80
    

    Anyway there might be good reasons not to use root for this. I've never used this software so I can't really say.

    You can then easily port the command in docker-compose format