Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Microservices can't communicate using Docker for Mac

I am trying to get two containers that are each running a different Go service. Both services were built with the net/http package. I have an API frontend as one and an Authentication service backend.

Here is my compose file:

version: "2"
services:
  staticfiles:
    build: ./files
    volumes:
      - /public
      - /views
  api:
    build: ./api
    environment:
      - PORT=8080
      - BASE_URL=https://example.org
      - AUTH_HOST=auth
      - AUTH_PORT=8080
      - VIEW_DIR=/views
      - PUBLIC_DIR=/public
    ports:
      - "80:8080"
    volumes_from:
      - staticfiles:ro
    links:
      - auth
    depends_on:
      - staticfiles
  db:
    build: ./postgres
    environment:
      - POSTGRES_USER=inheritor
      - POSTGRES_DB=inheritor
  auth:
    build: ./auth
    expose:
      - "8080"
    environment:
      - PORT=8080
      - DB_USER=inheritor
      - DB_NAME=inheritor
      - DB_HOST=db
      - DB_Port=5432
    links:
      - db

I know the links are working because from the api container I can ping auth and curl -X Post http://auth:8080/validate but within Go I get a dial address tcp i/o timeout. Here is the code.

var (
    authString = "http://" + env.AuthHost + ":" + env.AuthPort
)

//ValidateToken validates a token using the session in DB
func ValidateToken(req *model.ValidateRequest) (*model.JWTClaims, error) {
    client := new(http.Client)
    api := authString + "/validate"
    cont, err := model.Jsonify(req)
    if err != nil {
        return nil, exception.NewInternalError("Could not turn the request into a json object.")
    }

    request, err := http.NewRequest("POST", api, bytes.NewBuffer(cont))
    if err != nil {
        return nil, exception.NewInternalError("Could not create request: " + err.Error())
    }
    request.Header.Set("Content-type", "application/json")
    response, err := client.Do(request)
    if err != nil {
        return nil, exception.NewInternalError("Could not make the request: " + err.Error())
    }
    defer response.Body.Close()

    res := new(model.AuthResponse)
    res.Claims = new(model.JWTClaims)
    decoder := json.NewDecoder(response.Body)
    err = decoder.Decode(&res)
    spew.Dump(response.Body)
    if err != nil {
        return nil, exception.NewInternalError("Could not parse response back from auth service. " + err.Error())
    }

    if response.StatusCode != http.StatusOK {
        return nil, exception.NewInvalidJWTError(res.Error)
    }

    return res.Claims, nil
}

The client.Do(request) is what is throwing the Dial error. Now my auth service is not even being touched because I have a logger that prints to screen every request that is coming in.

  • env.AuthHost is mapped to the AUTH_HOST environment variable.
  • env.AuthPort is mapped to the Auth_PORT environment variable.

Much help is appreciated.

If it helps I am running MacOSX.

Client:
 Version:      1.12.0-rc4
 API version:  1.24
 Go version:   go1.6.2
 Git commit:   e4a0dbc
 Built:        Wed Jul 13 03:28:51 2016
 OS/Arch:      darwin/amd64
 Experimental: true

Server:
 Version:      1.12.0-rc4
 API version:  1.24
 Go version:   go1.6.2
 Git commit:   e4a0dbc
 Built:        Wed Jul 13 03:28:51 2016
 OS/Arch:      linux/amd64
 Experimental: true

Both Dockerfiles looks like this:

FROM golang:1.6
RUN mkdir -p /go/src/github.com/dixonwille/Inheritor/api
WORKDIR /go/src/github.com/dixonwille/Inheritor/api

COPY . /go/src/github.com/dixonwille/Inheritor/api

RUN go build -v -o Inheritor cmd/Inheritor/main.go

USER nobody
ENTRYPOINT ["./Inheritor"]

EDIT:

I ran net.LookupHost(env.AuthHost) within Go and it is returning a different IP address then ping, curl, and even docker inspect. Is this a Go thing then?

EDIT:

If I remove the port portion of the authString, the request goes through but get an error when parsing response. The response is a 301 redirect by NGINX which I think is strange because that is not even in my stack. The location header for the redirect is localhost, which I think is strange as well.

I have tried exposing a port on the host machine and accessing it with that port with no better luck (same hostname).

EDIT:

So it is a Mac only thing I assume. I cloned down the repo and ran on Windows 10 and I was able to connect to my auth service. Would this be Docker for Mac error? I am probably going to report it to them, but I would not consider this closed since it still is an issue for Mac users.

like image 219
Clemsonopoly94 Avatar asked Jul 28 '16 04:07

Clemsonopoly94


1 Answers

So Docker for Mac just came out with a new beta version today. This seemed to have fixed my issue with connecting. Now I did make changes to source code when I found out it worked on my Windows pc.

Here is the version of Docker for fix:

Client:
 Version:      1.12.0
 API version:  1.24
 Go version:   go1.6.3
 Git commit:   8eab29e
 Built:        Thu Jul 28 21:04:48 2016
 OS/Arch:      darwin/amd64
 Experimental: true

Server:
 Version:      1.12.0
 API version:  1.24
 Go version:   go1.6.3
 Git commit:   8eab29e
 Built:        Thu Jul 28 21:04:48 2016
 OS/Arch:      linux/amd64
 Experimental: true

And here is the compose file:

version: "2"
services:
  staticfiles:
    build: ./files
    volumes:
      - /public
      - /views
      - /migrations
  databasefiles:
    build: ./databasefiles
    volumes:
      - /var/lib/postgresql/data
  db:
    build: ./postgres
    depends_on:
      - databasefiles
    volumes_from:
      - databasefiles
    environment:
      - POSTGRES_USER=inheritor
      - POSTGRES_DB=inheritor
  auth:
    build: ./auth
    expose:
      - "8080"
    depends_on:
      - staticfiles
    volumes_from:
      - staticfiles:ro
    environment:
      - PORT=8080
      - DB_USER=inheritor
      - DB_NAME=inheritor
      - DB_HOST=db
      - DB_PORT=5432
      - MIGRATION_DIR=/migrations
    links:
      - db
  api:
    build: ./api
    environment:
      - PORT=8080
      - BASE_URL=https://example.org
      - AUTH_HOST=auth
      - AUTH_PORT=8080
      - VIEW_DIR=/views
      - PUBLIC_DIR=/public
    ports:
      - "80:8080"
    volumes_from:
      - staticfiles:ro
    links:
      - auth
    depends_on:
      - staticfiles

I did move services around but I do not see anything different that would change the communication between containers. This is just here incase others have same problem.

like image 101
Clemsonopoly94 Avatar answered Oct 05 '22 12:10

Clemsonopoly94