Reverse proxy to Mailcow-Dockerized returns 502 Bad Gateway

Hi,

I’m new to Docker (and to reverse proxy) and I’m trying to setup Caddy as a reverse proxy in front of Mailcow-Dockerized (mailcow-dockerized/docker-compose.yml at master · mailcow/mailcow-dockerized · GitHub).

Caddy is itself in a Docker container. It works to serve the simple website on the host, but I’m not able to configure it to serve as a reverse proxy the Mailcow Webui I have in another container. I get 502 Bad Gateway error.

All that is currently running in a CoreOS vm on my local machine and nothing is accessible from Internet for now.

I run Caddy with this command:

docker run -d --name caddy -e "CADDYPATH=/etc/caddycerts" -v $(pwd)/Caddyfile:/etc/Caddyfile -v $HOME/.caddy:/etc/caddycerts -p 80:80 -p 443:443 abiosoft/caddy

Here is what I currently have in the Caddyfile:

:80 {
    root /srv/
    proxy /mailcow 127.0.0.1:8080 {
        transparent
    }
}

What is wrong with what I do?

I already read many other 502 Bad Gateway related topics but could not figure out if the solution was in there, sorry.

Thank you!

Jean-Philippe

Consider using this proxy directive:

proxy /mailcow nginx:80 {
    transparent
}

You were probably referring to this page, but it seems to talk about reverse proxies outside of the Docker environment.

I don’t think using alias will work as the two containers are on different docker networks.

And now I realize my Caddy is itself in a container so 127.0.0.1 relates to that container and not the host… D’oh!

I seem to have two options:

  • Make the two containers be on the same networks.
  • Or is there a way to make two networks talk to each others (just to avoid messing too much with provided docker-compose files)?
  • Point the proxy to the host (how?) as for what I understand the mailcow nginx webserver is already bind to the host on port 8080.

Thanks again!

Going off this StackOverflow question, you could proxy to the Docker network interface on port 8080.

Assuming that your CoreOS’s Docker network interface is using the IP 172.17.42.1, your proxy directive then becomes:

proxy /mailcow 172.17.42.1:8080 {
    transparent
}

I don’t understand. Sorry I’m new to Docker (and not very savvy with networking).

Here is the relevant part of ‘docker ps’:

mailcowdockerized_nginx-mailcow_1: 127.0.0.1:8080->8080/tcp, 80/tcp, 127.0.0.1:8443->8443/tcp
caddy:                             0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp, 2015/tcp

‘docker network inspect mailcowdockerized_mailcow-network’:

    "Name": "mailcowdockerized_mailcow-network",
    "Id": "5d2339456aa5a11ae17cfa62b0ec63eb49eca47afed05924d3ebac90e8112d48",
    "Scope": "local",
    "Driver": "bridge",
    "EnableIPv6": true,
    "IPAM": {
        "Driver": "default",
        "Options": null,
        "Config": [
            {
                "Subnet": "172.22.1.0/24",
                "Gateway": "172.22.1.1"
            },
            {
                "Subnet": "fd4d:6169:6c63:6f77::/64",
                "Gateway": "fd4d:6169:6c63:6f77::1"
            }
        ]
    },
    "Internal": false,
    "Containers": {
         "1fe251d32c8a615c621bc2a15f2a417fa921b3386f56db24d53cd562a7004661": {
            "Name": "mailcowdockerized_nginx-mailcow_1",
            "EndpointID": "ded2a388ffa2099df1a638b1c2df352892b774e5531bc86545b4c4831004ee2b",
            "MacAddress": "02:42:ac:16:01:fb",
            "IPv4Address": "172.22.1.251/24",
            "IPv6Address": "fd4d:6169:6c63:6f77::7/64"
        }
    }, ....

‘docker network inspect bridge’:

    "Name": "bridge",
    "Id": "3191e317527d32fe7f984fc02e4ed94db6130905f76b87922e1ce06b73716822",
    "Scope": "local",
    "Driver": "bridge",
    "EnableIPv6": false,
    "IPAM": {
        "Driver": "default",
        "Options": null,
        "Config": [
            {
                "Subnet": "172.17.0.0/16",
                "Gateway": "172.17.0.1"
            }
        ]
    },
    "Internal": false,
    "Containers": {
        "88982b3fa106953baf47fd445626022f27b9409165970e24a0d0daa2ac55e02e": {
            "Name": "caddy",
            "EndpointID": "4a418bd50c97a06982474f3616ecad4127298df1364f43866bdee61622152bec",
            "MacAddress": "02:42:ac:11:00:02",
            "IPv4Address": "172.17.0.2/16",
            "IPv6Address": ""
        }
    }, ...

Sorry for my ‘newbieness’ and thanks.

Throwing in my 2c, I’d have to recommend using internal DNS rather than trying to hard-code the IP address of the container. If I were you I’d modify the docker-compose.yml to make nginx-mailcow available on the same network as your Caddy instance. Assuming Caddy is composed as well, it has a network called [project]_default. [project] is usually named after the folder your docker-compose.yml is located in.

So change this section:

To add it to another network, with a “mailcow” alias:

networks:
  mailcow-network:
    ipv4_address: 172.22.1.251
    aliases:
      - nginx
  caddy:
    aliases:
      - mailcow

Then at the bottom of the mailcow-dockerized Compose file, where it defines the networks:

Specify the caddy network to be the external network made by your Caddy compose project, replacing [project] with the relevant name:

networks:
  mailcow-network:
    driver: bridge
    enable_ipv6: true
    ipam:
      driver: default
      config:
        - subnet: 172.22.1.0/24
        - subnet: fd4d:6169:6c63:6f77::/64
  caddy:
    external:
      name: [project]_default

Then, refer to mailcow in your Caddyfile:

:80 {
  root /srv
  proxy /mailcow mailcow:80 {
    transparent
  }
}

Or as an alternate approach, I would define the Caddy service within the mailcow-dockerized Compose file itself, removing the ports from mailcow-nginx and giving them to Caddy instead, and refer to mailcow-nginx from within the Caddyfile.

2 Likes

I added mailcow-nginx to the caddy network. Thanks @Whitestrake.

That still did not work but by adding “without /mailcow” it’s now nearly working.

I finally do arrive on the homepage, but all links are broken because the html/css code miss the “/mailcow” part.

What do I need to make it work perfectly?

For reference that’s what I have in the Caddyfile:

:80 {
  proxy /mailcow mailcow:8080 {
    without /mailcow
    transparent
  }
}

Thanks to you all for helping a newbie.

I don’t believe Mailcow has the option of setting a URL base, so you will not be able to reverse proxy it into a folder.

It doesn’t look like you’re doing much else with that site at the moment, so move Mailcow to / and it should work as intended.

:80 {
  proxy / mailcow:8080 {
    transparent
  }
}

Thanks again @Whitestrake.

I’ll ask the devs if it’s possible to make changes so we can use it with folder reverse proxy.

Good idea. Make sure to make the distinction between a normal reverse proxy and a subfolder (URL base) reverse proxy. Hopefully they are open to the idea.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.