无法从同一网络上的容器获取响应,Docker Compose,Mountebank。

huangapple go评论137阅读模式
英文:

Unable to get a response from a container on the same network, Docker compose, Mountebank

问题

我有一个Go应用程序和三个Docker容器,用于应用程序、数据库和Mountebank来模拟/存根HTTP响应。

我希望我的Mountebank容器在test_api(应用程序容器)发出请求时返回适当的响应。

当我使用Postman调用端点时,Mountebank容器返回正确的响应。

然而,当我的test_api容器内的代码发送如下的GET请求时,它总是收到以下错误信息:
> dial tcp 127.0.0.1:3000: connect: connection refused

以下是test_api发送请求给Mountebank容器的代码:

  1. func getSuper(id string) (*float64, error) {
  2. var url = "http://localhost:3000/ato/employee/?/balance"
  3. url = strings.Replace(url, "?", id, 1)
  4. log.Println("Sending request to this url: ", url)
  5. resp, err := http.Get(url)
  6. if err != nil {
  7. return nil, &errorhandling.RequestError{Context: "getSuper calling ato api", Code: errorhandling.Internal, Message: err.Error()}
  8. }
  9. body, err := resposeToByte(resp)
  10. if err != nil {
  11. log.Println("err in coverting response to byte[]:", err)
  12. return nil, &errorhandling.RequestError{Context: "getsuper resposeToByte", Code: errorhandling.Internal, Message: err.Error()}
  13. }
  14. superData, err := UnmarshalSuperDetails(body)
  15. if err != nil {
  16. return nil, &errorhandling.RequestError{Context: "UnmarshalSuperDetails())", Code: errorhandling.Internal, Message: err.Error()}
  17. }
  18. log.Println("super details ", superData)
  19. return &superData.SuperBalance, nil
  20. }

以下是我的docker-compose文件:

  1. version: '3.7'
  2. services:
  3. db:
  4. container_name: "test_db"
  5. platform: linux/x86_64
  6. build:
  7. context: .
  8. dockerfile: db.Dockerfile
  9. networks:
  10. - default
  11. restart: always
  12. ports:
  13. - "3306:3306"
  14. environment:
  15. MYSQL_RANDOM_ROOT_PASSWORD: "secret"
  16. MYSQL_DATABASE: "IGD"
  17. MYSQL_USER: "tester"
  18. MYSQL_PASSWORD: "secret"
  19. volumes:
  20. - mysql_data:/var/lib/mysql
  21. command: --default-authentication-plugin=mysql_native_password
  22. api:
  23. container_name: "test_api"
  24. build:
  25. context: .
  26. dockerfile: api.Dockerfile
  27. ports:
  28. - "8080:8080"
  29. depends_on:
  30. - db
  31. volumes:
  32. - .:/app/
  33. mountebank:
  34. container_name: mountebank
  35. image: jkris/mountebank:latest
  36. build:
  37. context: .
  38. dockerfile: mb.Dockerfile
  39. volumes:
  40. - ./imposters:/imposters
  41. ports:
  42. - 2525:2525
  43. - 3000:3000
  44. command: --configfile /imposters/imposter.json --allowInjection
  45. networks:
  46. - default
  47. networks:
  48. default:
  49. volumes:
  50. mysql_data:

我的imposter配置如下:

  1. {
  2. "port": 3000,
  3. "protocol": "http",
  4. "stubs": [
  5. {
  6. "predicates": [
  7. {
  8. "equals": {"path":"/ato/employee/a/balance"}
  9. }
  10. ],
  11. "responses": [
  12. {
  13. "is": {
  14. "statusCode": 404,
  15. "headers": {
  16. "Content-Type": "application/json"
  17. },
  18. "body": {"error": "value not available"}
  19. }
  20. }
  21. ]
  22. },
  23. {
  24. "predicates": [
  25. {
  26. "equals": {"path":"/ato/employee/58957fc7-4e24-44e5-9eb1-a7fa0297613b/balance"}
  27. }
  28. ],
  29. "responses": [
  30. {
  31. "is": {
  32. "statusCode": 200,
  33. "headers": {
  34. "Content-Type": "application/json"
  35. },
  36. "body": { "employeeId":"50ccf5d6-2056-4e0c-a160-4e51638410c7",
  37. "superBalance":1050.0}
  38. }
  39. },
  40. continues...

以下是我的Mountebank的Dockerfile:

  1. FROM alpine:3.14
  2. ENV MOUNTEBANK_VERSION=2.4.0
  3. RUN apk add --update nodejs-lts && \
  4. apk add --update npm
  5. RUN npm install -g mountebank@${MOUNTEBANK_VERSION} --production
  6. EXPOSE 2525
  7. ENTRYPOINT ["mb"]
  8. CMD ["start"]

我应该如何更改我的代码,以便使test_api从Mountebank接收到正确的响应?

英文:

I have a Go application and three docker containers for the app, database and mountebank to mock/stub HTTP response.

I would like my mountebank container to return an appropriate response when the test_api (app container) makes a request.

The mountebank container returns a proper response when I call the endpoint using Postman.

However, when my code inside the test_api container send GET request like the code below It always receives
> dial tcp 127.0.0.1:3000: connect: connection refused

Here is how test_api send a request to mountebank container

  1. func getSuper(id string) (*float64, error) {
  2. var url = "http://localhost:3000/ato/employee/?/balance"
  3. url = strings.Replace(url, "?", id, 1)
  4. log.Println("Sending request to this url: ", url)
  5. resp, err := http.Get(url)
  6. if err != nil {
  7. return nil, &errorhandling.RequestError{Context: "getSuper calling ato api", Code: errorhandling.Internal, Message: err.Error()}
  8. }
  9. body, err := resposeToByte(resp)
  10. if err != nil {
  11. log.Println("err in coverting response to byte[]:", err)
  12. return nil, &errorhandling.RequestError{Context: "getsuper resposeToByte", Code: errorhandling.Internal, Message: err.Error()}
  13. }
  14. superData, err := UnmarshalSuperDetails(body)
  15. if err != nil {
  16. return nil, &errorhandling.RequestError{Context: "UnmarshalSuperDetails())", Code: errorhandling.Internal, Message: err.Error()}
  17. }
  18. log.Println("super details ", superData)
  19. return &superData.SuperBalance, nil
  20. }

here is my docker-compose

  1. version: '3.7'
  2. services:
  3. db:
  4. container_name: "test_db"
  5. platform: linux/x86_64
  6. build:
  7. context: .
  8. dockerfile: db.Dockerfile
  9. networks:
  10. - default
  11. restart: always
  12. ports:
  13. # <Port exposed> : < MySQL Port running inside container>
  14. - "3306:3306"
  15. # setting some env vars to create the DB
  16. environment:
  17. MYSQL_RANDOM_ROOT_PASSWORD: "secret"
  18. MYSQL_DATABASE: "IGD"
  19. MYSQL_USER: "tester"
  20. MYSQL_PASSWORD: "secret"
  21. # OR if you want to use "root" as the user, just these two lines
  22. # MYSQL_ROOT_PASSWORD: ${DATABASE_PASSWORD}
  23. # MYSQL_DATABASE: ${DATABASE_NAME}
  24. # we mount a data volume to make sure we don't lose data
  25. volumes:
  26. - mysql_data:/var/lib/mysql
  27. command: --default-authentication-plugin=mysql_native_password
  28. api:
  29. container_name: "test_api"
  30. # we want to use the image which is build from our Dockerfile
  31. build:
  32. context: .
  33. dockerfile: api.Dockerfile
  34. ports:
  35. - "8080:8080"
  36. # we are depending on the mysql backend
  37. depends_on:
  38. - db
  39. # We mount the working dir into the container, handy for development
  40. # This is what makes the hot reloading work inside of a Docker container
  41. volumes:
  42. - .:/app/
  43. mountebank:
  44. container_name: mountebank
  45. image: jkris/mountebank:latest
  46. build:
  47. context: .
  48. dockerfile: mb.Dockerfile
  49. volumes:
  50. - ./imposters:/imposters
  51. ports:
  52. - 2525:2525
  53. - 3000:3000
  54. #- 8090:8090
  55. command: --configfile /imposters/imposter.json --allowInjection
  56. networks:
  57. - default
  58. networks:
  59. default:
  60. volumes:
  61. mysql_data:

my imposter:

  1. { "port": 3000,
  2. "protocol": "http",
  3. "stubs": [
  4. {
  5. "predicates": [
  6. {
  7. "equals": {"path":"/ato/employee/a/balance"}
  8. }
  9. ],
  10. "responses": [
  11. {
  12. "is": {
  13. "statusCode": 404,
  14. "headers": {
  15. "Content-Type": "application/json"
  16. },
  17. "body": {"error": "value not available"}
  18. }
  19. }
  20. ]
  21. },
  22. {
  23. "predicates": [
  24. {
  25. "equals": {"path":"/ato/employee/58957fc7-4e24-44e5-9eb1-a7fa0297613b/balance"}
  26. }
  27. ],
  28. "responses": [
  29. {
  30. "is": {
  31. "statusCode": 200,
  32. "headers": {
  33. "Content-Type": "application/json"
  34. },
  35. "body": { "employeeId":"50ccf5d6-2056-4e0c-a160-4e51638410c7",
  36. "superBalance":1050.0}
  37. }
  38. },
  39. continues...

Here is my docker file for mountebank

  1. FROM alpine:3.14
  2. ENV MOUNTEBANK_VERSION=2.4.0
  3. RUN apk add --update nodejs-lts && \
  4. apk add --update npm
  5. RUN npm install -g mountebank@${MOUNTEBANK_VERSION} --production
  6. EXPOSE 2525
  7. ENTRYPOINT ["mb"]
  8. CMD ["start"]

How can I make a change in my code in order to make test_api receive a proper response from the mountebank?

答案1

得分: 1

你应该将test_api中的以下行更改为:

  1. var url = "http://mountebank:3000/ato/employee/?/balance"

因为这些是不同的容器,你应该在Docker环境中指定它们的名称或IP。你的test_api请求到了它的本地主机,但是没有打开3000端口,所以会出现连接被拒绝的错误。你可以参考Docker网络获取更多信息。

英文:

You should change following line in your test_api;

  1. var url = "http://localhost:3000/ato/employee/?/balance"

With the following one;

  1. var url = "http://mountebank:3000/ato/employee/?/balance"

Since these are different container and you should specify their name or IPs in Docker environment. Your test_api requests to its localhost and there is no open port for 3000 and you would get connection refused error. You can take a look Docker Networking for further information.

huangapple
  • 本文由 发表于 2021年11月8日 10:12:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/69878027.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定