FreedomBen / dory

Your development proxy for docker
MIT License
156 stars 24 forks source link

(question) Can't connect to non-http services #17

Closed prismic closed 7 years ago

prismic commented 7 years ago

I am considering using dory for my OSX dev env, but I am probably missing something. I want to use the reverse proxy to connect to my postgres service, and not having much success.

Here's what I am starting with. An empty repository with nothing but this docker-compose.yml, taken from the example on the README:

version: '2'
services:
  redis:
    image: redis
    environment:
      VIRTUAL_HOST: redis.docker
      VIRTUAL_PORT: 6379

  db:
    image: postgres
    environment:
      VIRTUAL_HOST: postgres.docker
      VIRTUAL_PORT: 5432

After this is spun up, I expected to be able to connect to redis via redis.docker:6379, but no luck. However, I could connect to redis if I went to port 80.

Curious, I went into the http proxy container and looked at the nginx config, and realized that the config for redis looked like this:

upstream redis.docker {
    server 172.20.0.2:6379;
}
server {
    server_name redis.docker ~^redis.docker\.\d+\.\d+\.\d+\.\d+\.xip\.io$;
    listen 80;
    access_log /var/log/nginx/access.log vhost;
        listen 443 ssl;
        ssl_certificate /etc/nginx/certs/default.crt;
        ssl_certificate_key /etc/nginx/certs/default.key;
    location / {
        proxy_pass http://redis.docker;
    }
}

This looked to me like it's actually listening on port 80 coming in from the host, which would explain why trying to connect to 80 worked, contrary to the example shown in the README.

I could live with that, however, I am not able to get this to work at all with the postgres container, when trying to connect with postgres.docker:80, I get this error:

psql: received invalid response to SSL negotiation: H

My first thought is that because proxy_pass http://postgres.docker; is only meant for http traffic, so it wouldn't work with postgres, but I am not an expert on this.

I am running Docker For Mac 17.09.0-ce-mac35, and default settings for dory.

What am I doing wrong?

FreedomBen commented 7 years ago

Thanks for the feedback! Yes you are correct that you have to hit the services on either 80 or 443 and the proxy then routes the request to the container on VIRTUAL_PORT. It does sound like the example in the README is wrong. I'll try to get that fixed.

For postgres this will be a little tricky because as you discovered, the request gets answered by nginx acting as a proxy. I'm sure there's an nginx config option to make that work, but I don't know it off the top of my head.

Honestly when I've had to speak a protocol to a container (like postgres usually), I will just bind the port to localhost and hit it that way by adding a ports: key to the config (example below). This can be painful if you have a lot of services like that, but I generally find that it's only one or two that don't speak HTTP.

version: '2'
services:
  db:
    image: postgres
    ports:
        - "5432:5432"
    environment:
      VIRTUAL_HOST: postgres.docker
      VIRTUAL_PORT: 5432

Then point psql at localhost:5432 instead of postgres.docker. I know it's not a very elegant solution, sorry :disappointed:

prismic commented 7 years ago

Thanks for the advice. I totally get the rationale. Incidentally, I realize this is a problem with all of the nginx proxies I've found - to make it work with non-http services you need nginx compiled with stream, and most don't. Thanks for pointing me in the right direction!