Search code examples
ruby-on-railsrubydockermicroservicesnet-http

Failed to open TCP connection to localhost:3101 - Rails / Docker


I'm trying to ping one of our Rails Microservices (handles emails) from our app, and I'm getting the title error.

Our microservice is running in docker on localhost:3101, whilst our app is on localhost:3000 on docker also - I've pinged it with postman requests and it's working fine.

I've set our auth token and email service API in our ENV variables like so:-

EMAIL_SERVICE=http://localhost:3101
EMAIL_SERVICE_TOKEN=1234

Here's my EmailService:-

class EmailService
  require 'net/http'

  HEADER = { 'Content-Type': 'application/json' }.freeze
  ENDPOINTS = {
    root: ENV['EMAIL_SERVICE'],
    test_email: {
      post: {
        url: '/api/test_email'
      }
    }
  }

  def initialize
    @token = ENV['EMAIL_SERVICE_TOKEN']
  end

  def call_api(section, action, data, method='POST')
    address_url = ENDPOINTS[section][action][:url]
    uri = URI.parse("#{ENDPOINTS[:root]}#{address_url}")

    # Create the HTTP objects
    http = Net::HTTP.new(uri.host, uri.port)
    if method == 'POST'
      request = Net::HTTP::Post.new(
        uri.request_uri,
        HEADER
      )
      request.body = data.merge({ auth_token: @token }).to_json

    else
      request = Net::HTTP::Get.new(
        uri.request_uri,
        HEADER
      )
    end

    http.use_ssl = true
    response = http.request(request)
  end
end

Any idea what I'm missing?


Solution

  • I assume that both of those microservices run on separate docker containers.

    I think the problem is that when docker receives your request from outside of the container and then tries to make an HTTP request to localhost it actually is making request to its OWN localhost (so inside the container) and not the localhost of your machine. To fix this, instead of trying to send request to localhost make the app inside the docker send the request to host.docker.internal:DESIRED_PORT this tells docker to use localhost of it's host machine.

    You can read more about that here:

    https://docs.docker.com/docker-for-mac/networking/#use-cases-and-workarounds