Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

help: proxy to secured docker registry container #672

Closed
cdaringe opened this issue Jan 8, 2017 · 6 comments
Closed

help: proxy to secured docker registry container #672

cdaringe opened this issue Jan 8, 2017 · 6 comments

Comments

@cdaringe
Copy link

cdaringe commented Jan 8, 2017

problem statement

  • i am unable to proxy to my internal docker registry container

context

  • registry must secure itself to enable auth. therefore, I must configure the registry container to consume a cert of its own
    • my cert are for my *.TLD, but the proxied URI is probably not.

i see that this image supports "basic auth," but it's not clear how auth here in the proxy tells the registry that "yes, this user logged in." reference links:

any tips would be appreciated! thanks!

# docker-compose.yaml
version: '2'
services:
  # service proxy
  nginx-proxy:
    image: jwilder/nginx-proxy
    container_name: nginx-proxy
    ports:
      - "80:80"
      # - "443:443"
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock:ro
      # - /www/certs/:/etc/nginx/certs
    environment:
      - DEFAULT_HOST=$HOSTNAME
    restart: always

  # docker registry
  docker_registry:
    image: registry:2
    expose:
      - 5000
    restart: unless-stopped
    # volumes:
      # - /www/registry/auth:/auth
      # - /www/registry/registry:/var/lib/registry
      # - /www/certs:/certs
    environment:
      - VIRTUAL_HOST=registry.$HOSTNAME
      - VIRTUAL_PORT=5000
      # - HTTPS_METHOD=noredirect
      # - STORAGE_PATH=/www/registry
      # - CERT_NAME=server
      # - REGISTRY_AUTH=htpasswd
      # - REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm
      # - REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd
      # - REGISTRY_HTTP_TLS_CERTIFICATE=/certs/server.crt
      # - REGISTRY_HTTP_TLS_KEY=/certs/server.key
      # - REGISTRY_HTTP_SECRET=<SOME_SECRET>
@cdaringe
Copy link
Author

cdaringe commented Jan 9, 2017

the solution was to use Basic Authentication support and authenticate at the proxy and not run an authenticated registry.

@cdaringe cdaringe closed this as completed Jan 9, 2017
@npotier
Copy link

npotier commented Jan 12, 2017

Hi @cdaringe it seems that you solved your problem. I'm having the same troubles, so do you think you could post a working version of your docker-compose.yml ? Thanks :)

@cdaringe
Copy link
Author

hey @npotier, my code is private ATM, so maybe i could slap something together later, but pretty much just run the registry insecurely (don't configure any SSL or auth bits), and follow https://github.com/jwilder/nginx-proxy#basic-authentication-support

@cdaringe
Copy link
Author

what i dont like about this strategy is that if you misplace or misconfigure your someservice.domain's htpsswd, then your registry gets exposed wide open. it would be nice if we could add to this package a FORCE_BASIC_AUTH flag that redundantly exposure in the event of a misconfig. I feel like given the ease of making a mistake, a failsafe is warranted

@Ovski4
Copy link

Ovski4 commented May 19, 2018

Thank you for your help and questions @cdaringe and @npotier. One year and a half later, this issue helped me.

An easy way to prevent any unexpected exposure of the container is to just let the proxy forward the request and do not expose any port on the host machine. The proxy will automatically pick the port 5000.

I was able to configure a secured registry easily with that configuration. If it can help others as well, here is my docker-compose.yml file (this applies for docker-compose v2 only, I'm not up to date):

version: '2'

services:

  proxy:
    container_name: nginx-proxy
    image: jwilder/nginx-proxy:alpine-0.6.0
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock
      - /var/docker/proxy/htpasswd/:/etc/nginx/htpasswd
      - /var/docker/proxy/certs:/etc/nginx/certs
      - /var/docker/proxy/vhost.d:/etc/nginx/vhost.d
      - /var/docker/proxy/html:/usr/share/nginx/html
    labels:
      - "com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy=true"

  letsencrypt:
    container_name: lets-encrypt-companion
    image: jrcs/letsencrypt-nginx-proxy-companion:v1.6
    volumes:
      - /var/docker/proxy/certs:/etc/nginx/certs:rw
      - /var/run/docker.sock:/var/run/docker.sock:ro
    volumes_from:
      - proxy

  registry:
    container_name: docker-registry
    image: registry:2.6.2
    environment:
      VIRTUAL_HOST: registry.my-domain.com
      LETSENCRYPT_HOST: registry.my-domain.com
      LETSENCRYPT_EMAIL: dummy.user@hello.com      
      REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /var/docker/registry
      REGISTRY_HTTP_SECRET: whateveryouwantgoeshere

I created a file called registry.my-domain.com in the directory /var/docker/proxy/vhost.d with the following content to allow the uploading of images with a size up to 512m.

client_max_body_size 512m;

I eventually created a htpasswd file called registry.my-domain.com in /var/docker/proxy/htpasswd to enable user auth

The TLS part is automatically managed by the letsencrypt companion for me

@MJGTwo
Copy link

MJGTwo commented Feb 15, 2019

@Ovski4 there is a very obnoxious edge case with this configuration that needs an additional line in your docker-compose.yml

version: '2'

services:

  proxy:
    container_name: nginx-proxy
    image: jwilder/nginx-proxy:alpine-0.6.0
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock
      - /var/docker/proxy/htpasswd/:/etc/nginx/htpasswd
      - /var/docker/proxy/certs:/etc/nginx/certs
      - /var/docker/proxy/vhost.d:/etc/nginx/vhost.d
      - /var/docker/proxy/html:/usr/share/nginx/html
    labels:
      - "com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy=true"

  letsencrypt:
    container_name: lets-encrypt-companion
    image: jrcs/letsencrypt-nginx-proxy-companion:v1.6
    volumes:
      - /var/docker/proxy/certs:/etc/nginx/certs:rw
      - /var/run/docker.sock:/var/run/docker.sock:ro
    volumes_from:
      - proxy

  registry:
    container_name: docker-registry
    image: registry:2.6.2
    volumes:
      - /var/docker/registry:/var/docker/registry       # this line here
    environment:
      VIRTUAL_HOST: registry.my-domain.com
      LETSENCRYPT_HOST: registry.my-domain.com
      LETSENCRYPT_EMAIL: dummy.user@hello.com      
      REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /var/docker/registry
      REGISTRY_HTTP_SECRET: whateveryouwantgoeshere

The registry will attempt over a period of 10 seconds 3 times (30 seconds in total) to look for a registry at REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY inside of itself, but it does not exist because it must be created for. It will then fail. What must be done is add a volume on your host so that this path is created. This is a similar issue for any other storage service (e.g. S3 buckets).

You may not have ran into this issue because if you push an image within 30 seconds you force the registry contain to make that path, creating the registry. However this volume is not persistent if you do not define it in relation to the host.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants