Tecnativa / docker-socket-proxy

Proxy over your Docker socket to restrict which requests it accepts
Apache License 2.0
1.3k stars 155 forks source link

HAProxy #74

Open tamimology opened 1 year ago

tamimology commented 1 year ago

When I run the image, in the logs I get the below: Can't open server state file '/var/lib/haproxy/server-state': No such file or directory

I checked the container and did not find that folder as well

/ # ls /var/lib/
apk     misc    udhcpd

Not sure if this has a direct impact on portainer not working using the socket-proxy, as well as the HomeAssistant container showing that the TCP is disconnected

DockerError(900, 'Cannot connect to Docker Engine via tcp://172.18.0.199:2375 [Server disconnected]')

my compose for the socket / portianer / homeassistant are as following:

  socket:
    container_name: socketproxy
    restart: $ALWAYS_ON_POLICY
    environment:
        PUID: $PUID
        PGID: $PGID
        LOG_LEVEL: err # debug,info,notice,warning,err,crit,alert,emerg
        ## Variables match the URL prefix (i.e. AUTH blocks access to /auth/* parts of the API, etc.).
        # 0 to revoke access.
        # 1 to grant access.
        ## Granted by Default
        EVENTS: 1
        PING: 1
        VERSION: 1
        ## Revoked by Default
        # Security critical
        AUTH: 0
        SECRETS: 0
        POST: 1 # Watchtower
        # Not always needed
        BUILD: 1
        COMMIT: 1
        CONFIGS: 1 #0
        CONTAINERS: 1 # Traefik, portainer, etc.
        DISTRIBUTION: 1 #0
        EXEC: 1 #0
        IMAGES: 1 # Portainer
        INFO: 1 # Portainer
        NETWORKS: 1 # Portainer
        NODES: 1 #0
        PLUGINS: 1 #0
        SERVICES: 1 # Portainer
        SESSION: 1 #0
        SWARM: 1 #0
        SYSTEM: 1
        TASKS: 1 # Portainer
        VOLUMES: 1 # Portainer
    volumes:
        - /var/run/docker.sock:/var/run/docker.sock
    ports:
        #- 127.0.0.1:2375:2375 # Port 2375 should only ever get exposed to the internal network. When possible use this line.
    # Use the next line instead, as I want portainer to manage multiple docker endpoints within my home network.
        - 2375:2375
    privileged: true
    image: 'tecnativa/docker-socket-proxy:latest'
  portainer-ce:
    container_name: portainer-ce
    restart: $ALWAYS_ON_POLICY
    command: -H $DOCKER_HOST
    environment:
      DOCKER_HOST: $DOCKER_HOST
    volumes:
      - $PERSIST/portainer-ce:/data
    ports:
      - 8000:8000/tcp
      - 9000:9000/tcp
      - 9443:9443/tcp
    image: 'portainer/portainer-ce'
  homeassistant:
    container_name: homeassistant
    restart: $ALWAYS_ON_POLICY
    privileged: true
    environment:
      - DOCKER_HOST=$SOCKET
      - PUID=$PUID
      - PGID=$PGID
      - TZ=$TZ
    volumes:
      - $LOCAL_TIME:/etc/localtime:ro
      - $PERSIST/homeassistant:/config:rw
    ports:
      - 8123:8123
    working_dir: /config
    depends_on:
      - mariadb
    image: 'ghcr.io/home-assistant/home-assistant:stable'
bartclone commented 1 year ago

@tamimology , have you tried to bind the containers to the specific network the proxy runs on? Because _By default Compose sets up a single network for your app._ (https://docs.docker.com/compose/networking/)

Or you could use a single compose file, including all 3 containers.

tamimology commented 1 year ago

All are on the host network using network_mode: host

bartclone commented 1 year ago

All are on the host network using network_mode: host

Ok. Maybe first try something simpler, and also specify protocol, ip (or hostname) and port? Like:

 portainer-ce:
    container_name: portainer-ce
    command: -H tcp://0.0.0.0:2375 # specify ip, protocol and port 
...
bartclone commented 1 year ago

When I run the image, in the logs I get the below: Can't open server state file '/var/lib/haproxy/server-state': No such file or directory

I see this error too in the logs of the Technativa-container. But Portainer and other containers run fine. I doubt it is the source of your issues.

tamimology commented 1 year ago

All are on the host network using network_mode: host

Ok. Maybe first try something simpler, and also specify protocol, ip (or hostname) and port? Like:

portainer-ce:
   container_name: portainer-ce
   command: -H tcp://0.0.0.0:2375 # specify ip, protocol and port 
...

I did specify the IP and still same issue

ghost commented 1 year ago

I use linuxserver SWAG and added their auto-proxy mod. The mod requires access to the docker socket and they advised using a socket proxy. I duly added this to my docker stack and tried to set it up for portainer and diun, too. https://github.com/linuxserver/docker-mods/tree/swag-auto-proxy

Both portainer and diun started up but couldn't access my containers. When researching the issue, I came across suggestions, for both apps, to change the endpoint. I haven't the foggiest what that means or how to implement it, but am posting the info here in case it helps.

For DIUN, you can add the endpoint as an environment variable: https://github.com/crazy-max/diun/issues/308 https://crazymax.dev/diun/providers/docker/#endpoint

For PORTAINER, a reddit post suggested adding the docker socket as an endpoint in the Portainer GUI. Perhaps there is an environment variable for Portainer similar to DIUN above? https://www.reddit.com/r/docker/comments/l2lf3z/docker_socket_proxy_not_woking/

bartclone commented 1 year ago

I use linuxserver SWAG and added their auto-proxy mod. The mod requires access to the docker socket and they advised using a socket proxy. I duly added this to my docker stack and tried to set it up for portainer and diun, too. https://github.com/linuxserver/docker-mods/tree/swag-auto-proxy ....

An endpoint is "simply" the unix-socket (or IP + port )that an app (portainer, diun, nginx etc) connects to. In case of the tecnativa-docker-proxy, the endpoint is (can be) an IP + Port, and as such it replaces the socket (/var/run/docker.sock).

Depends entirely on the application/container if environment-vars can be used to communicate which endpoint to use.

AFAIK, in Portainer you need to set an endpoint to docker-proxy (so, other than the standard docker socket) in the app itself. At least, I never got it to work using (only) the -H environment var.

HTH.

ghost commented 1 year ago

Hi, BartKoppers

Thanks very much for the info. Every little bit helps :-)

CodeAnthem commented 1 year ago

So, I have your proxy running 3 times, one for traefik, watchtower and portainer.

I have this warning Can't open server state file '/var/lib/haproxy/server-state': No such file or directory on every single one of them.

Example: socket proxy for watchtower

  sp_watchtower:
    <<: *common-keys-socket-proxy # See 'Extension fields' at the top
    image: tecnativa/docker-socket-proxy:latest
    container_name: sp_watchtower
    networks:
      - sp_watchtower
    #ports:
    # - "127.0.0.1:2375:2375" # Port 2375 should only ever get exposed to the internal network. When possible use this line.
    # I use the next line instead, as I want portainer to manage multiple docker endpoints within my home network.
    # - "2375:2375"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
    environment: 
      <<: *defaultenv
      LOG_LEVEL: err # debug,info,notice,warning,err,crit,alert,emerg
      ## Variables match the URL prefix (i.e. AUTH blocks access to /auth/* parts of the API, etc.).
      # 0 to revoke access.
      # 1 to grant access.
      ## Granted by Default
      EVENTS: 1
      PING: 1
      VERSION: 1
      ## Revoked by Default
      # Security critical
      AUTH: 0
      SECRETS: 0
      POST: 1 # Watchtower
      # Not always needed
      BUILD: 0
      COMMIT: 0
      CONFIGS: 0
      CONTAINERS: 1 # Traefik, portainer, etc.
      DISTRIBUTION: 0
      EXEC: 0
      IMAGES: 1 # Portainer
      INFO: 1 # Portainer
      NETWORKS: 0 # Portainer
      NODES: 0
      PLUGINS: 0
      SERVICES: 1 # Portainer
      SESSION: 0
      SWARM: 0
      SYSTEM: 0
      TASKS: 0 # Portainer
      VOLUMES: 1 # Portainer
      com.centurylinklabs.watchtower.enable: true

Watchtower:

  watchtower:
    <<: *common-keys-maintenance # See EXTENSION FIELDS at the top
    image: containrrr/watchtower
    container_name: watchtower
    networks:
      - sp_watchtower
    depends_on:
      - sp_watchtower
    environment:
      <<: *defaultenv
      WATCHTOWER_CLEANUP: true
      WATCHTOWER_INCLUDE_RESTARTING: true
      WATCHTOWER_INCLUDE_STOPPED: true
      WATCHTOWER_LABEL_ENABLE: true
      WATCHTOWER_NOTIFICATIONS_LEVEL: error
      WATCHTOWER_NOTIFICATIONS: email
      WATCHTOWER_NOTIFICATION_EMAIL_DELAY: 0
      WATCHTOWER_NOTIFICATION_TITLE_TAG: ${EMAIL_TITLETAG:?err}
      WATCHTOWER_NOTIFICATION_EMAIL_FROM: ${EMAIL_FROM:?err}
      WATCHTOWER_NOTIFICATION_EMAIL_SERVER: ${EMAIL_SERVER:?err}
      WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PASSWORD: /run/secrets/email_password
      WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PORT: ${EMAIL_SERVER_PORT:?err}
      WATCHTOWER_NOTIFICATION_EMAIL_SERVER_USER: ${EMAIL_FROM:?err}
      WATCHTOWER_NOTIFICATION_EMAIL_TO: ${EMAIL_ADMIN:?err}
      # WATCHTOWER_NOTIFICATIONS: shoutrrr
      # WATCHTOWER_NOTIFICATION_URL: "telegram://$TGRAM_BOT_TOKEN@telegram?channels=$TGRAM_CHAT_ID"
      WATCHTOWER_NO_STARTUP_MESSAGE: true
      WATCHTOWER_POLL_INTERVAL: 21600 # 6h
      WATCHTOWER_REMOVE_VOLUMES: false
      # WATCHTOWER_SCHEDULE: "30 * * * *" # Every 30 min (either interval or schedule can be active)
      WATCHTOWER_TIMEOUT: 30
      DOCKER_HOST: tcp://sp_watchtower:2375
      DOCKER_API_VERSION: "1.40"
    secrets:
      - email_password
    labels:
      com.centurylinklabs.watchtower.enable: true

I noticed issues with portainer, that I get internal server error, when creating/restarting stacks, since I put it behind the socket proxy, I tried to give it every single permission once, didn't help.

Also getting watchtower emails:

Error response from daemon: <html><body><h1>403 Forbidden</h1>
Request forbidden by administrative rules.
</body></html>

even tho I didn't try yet, to add more permissions there.

Any ideas? Thanks :)

EDIT: it's funny i get this warning anyway, since I have loglevels set to error only