title: gRPC Unimplemented/Unknown Service
body: <p>I'm working on a project using gRPC and have recently migrated it to have each service running in Docker containers (it might be worth adding that I am fairly new to containerisation). Today, while moving one of my Go services into a container I ran into this error and have been trying to work around it for a couple of hours now with no success. The error I'm getting is:</p>
  <p><strong>&quot;rpc error: code = Unimplemented desc = unknown service PowerEstimationServicePackage&quot;</strong></p>
  <p>I've looked around online and it seems that the error, while not hugely descriptive, usually means that the service call your client is making has not been registered on the port by the server. I've spent a couple of hours looking at my code now and can't for the life of me figure out why I'm getting the error - as far as I can tell I have registered it correctly!</p>
  <p>Additionally, when I run the Go service locally, it works perfectly! This leads me to believe that the issue has to do with my port bindings when running it in Docker. I feel like I've got a reasonable understanding of how Docker deals with networks but could very well have overlooked something here.</p>
  <p>The relevant client code (running locally) is:</p>
  <pre><code>const {
      addrEstimationSP = &quot;127.0.0.1:50101&quot;
  }
  
  // Use this to implement the power estimation service routing
  type estimationServer struct {
      serverPB.UnimplementedPowerEstimationServicesServer
  }
  
  func main {
      // Create a connection over the specified tcp port
      callCounter := interceptors.ClientMetricStruct{}
      connEstimationSP := CreateInsecureServerConnection(addrEstimationSP, timeoutDuration, callCounter.ClientMetrics)
  
      /* Create the client and pass the connection made above to it. After the client has been
      created, we create the gRPC request */
      InfoLogger.Println(&quot;Creating clients&quot;)
      clientEstimationSP := estimationPB.NewPowerEstimationServicePackageClient(connEstimationSP)
      DebugLogger.Println(&quot;Succesfully created the clients&quot;)
  
      requestMessageEstimationSP := estimationPB.ServicePackageRequestMessage{
          InputFile: INPUTfilename,
          ModelType: estimationPB.ModelTypeEnum_OPENWATER,
      }
  
      estimationContext, _ := context.WithTimeout(context.Background(), callTimeoutDuration)
      responseEstimationSP, errEstimationSP := clientEstimationSP.PowerEstimatorService(estimationContext, &amp;requestMessageEstimationSP)
      if errEstimationSP != nil {
          ErrorLogger.Println(&quot;Failed to make EstimationSP service call: &quot;)
          ErrorLogger.Println(errEstimationSP)
      } else {
          DebugLogger.Println(&quot;Succesfully made service call to GoLang EstimationSP.&quot;)
          connEstimationSP.Close()
      }
  
      responseMessage := serverPB.PowerEstimationResponse{
          PowerEstimate: responseEstimationSP.PowerEstimate,
      }
  }
  </code></pre>
  <p>, and the relevant code on the server side (this is the service that I'm trying to move into Docker) is:</p>
  <pre><code>var (
      // Addresses
      addrMyself = os.Getenv(&quot;POWERESTIMATIONHOST&quot;) + &quot;:50101&quot;
  )
  
  // server is used to implement PowerEstimationServicePackage
  type server struct {
      serverPB.UnimplementedPowerEstimationServicePackageServer
  }
  
  func main() {
      InfoLogger.Println(&quot;Started GoLang Aggregator&quot;)
  
      // Create a listener on the specified tcp port
      listener, err := net.Listen(&quot;tcp&quot;, addrMyself)
      if err != nil {
          ErrorLogger.Fatalf(&quot;Failed to listen on port %v: \n%v&quot;, addrMyself, err)
      }
      InfoLogger.Println(&quot;Listeneing on port: &quot;, addrMyself)
  
      // Create a gRPC server object
      estimationServer := grpc.NewServer()
      // Attach the power estimation service to the server
      serverPB.RegisterPowerEstimationServicePackageServer(estimationServer, &amp;server{})
      // Start the server
      if err := estimationServer.Serve(listener); err != nil {
          ErrorLogger.Fatalf(&quot;Failed to expose service: \n%v&quot;, err)
      }
  }
  
  
  func (s *server) PowerEstimatorService(ctx context.Context, request *serverPB.ServicePackageRequestMessage) (*serverPB.EstimateResponseMessage, error) {
      ...
  }
  </code></pre>
  <p>The client is able to create a connection to the server but is getting an error when making the clientEstimationPB.PowerEstimatorService(...) call. The service is running inside a Docker network, hence passing environment variables for its address. The Dockerfile and Docker-compose file can be seen below:</p>
  <p>Dockerfile:</p>
  <pre><code>FROM golang:alpine
  
  # Install git.
  # Git is required for fetching the dependencies.
  RUN apk add --no-cache git
  
  WORKDIR $GOPATH/src/github.com/nicholasbunn/masters/
  
  # Create a program logs folder in the service directory
  RUN mkdir ./program\ logs
  RUN mkdir -p $GOPATH/src/github.com/nicholasbunn/masters/src/powerEstimationSP
  
  COPY /src/powerEstimationSP/go.mod ./src/powerEstimationSP
  COPY /src/powerEstimationSP/go.sum ./src/powerEstimationSP
  
  # Copy over contents into image
  COPY src/powerEstimationSP/interceptors/ ./src/powerEstimationSP/interceptors
  COPY src/powerEstimationSP/proto/ ./src/powerEstimationSP/proto
  COPY certification/ certification
  COPY src/powerEstimationSP/powerEstimationSP.go ./src/powerEstimationSP
  COPY src/powerEstimationSP/powerEstimationSP_test.go ./src/powerEstimationSP
  
  COPY src/fetchDataService/proto src/fetchDataService/proto
  COPY src/prepareDataService/proto src/prepareDataService/proto
  COPY src/estimateService/proto src/estimateService/proto
  
  WORKDIR $GOPATH/src/github.com/nicholasbunn/masters//src/powerEstimationSP/
  
  # Fetch the dependecies
  RUN go mod tidy
  
  # Build the binary. for grpc gateway
  RUN go build -o ./powerEstimationSP .
  
  WORKDIR $GOPATH/src/github.com/nicholasbunn/masters/
  
  EXPOSE 50101
  ENTRYPOINT [&quot;./src/powerEstimationSP/powerEstimationSP&quot;]
  </code></pre>
  <p>Docker-compose.yaml:</p>
  <pre><code>version: &quot;3.8&quot;
  
  services:
  ...
      powerestimationsp:
          build: 
              context: .
              dockerfile: src/powerEstimationSP/Dockerfile
          environment: 
              POWERESTIMATIONHOST: powerestimationsp
              FETCHHOST: fetchservice
              PREPAREHOST: prepareservice
              ESTIMATEHOST: estimateservice
              PROMETHEUSHOST: prometheus
          image: power_estimation_sp
          networks: 
              - southernOcean
          ports: 
              - 50101:50101
  networks:
      southernOcean:
  </code></pre>
  <p>I have a feeling the fix for this is really simple and probably just a small misunderstanding on my side, I've just had a bit of a cloudy-head day so hopefully a fresh pair of eyes can help out here.</p>
  <p>Thanks!</p>