5

I'm more of a software developer than a networking/ops person to give you some context.

I'm currently creating an application that is a standard containerised microservices architecture, where my frontend is some static assets in an nginx container, and my backend APIs are expressjs servers running on node containers.

When my frontend makes a call to a backend endpoint, it's going to look like:

const response = await fetch("/api1/v1/items"); 

Because by default the browser is going to make this request to the frontend container, we need some way of redirecting that traffic to the correct backend container.

One standard way to do this, is that I can setup a reverse-proxy in the frontend container's nginx.conf to direct all /api1/* traffic to another service.

ie. you would do something like this:


location /a {
   proxy_pass         http://api1;

Where you have defined api1 as a service in your docker-compose.yml.

I'm a bit uncomfortable with this, at the cluster configuration is mixed up with the implementation.

I am aware with Kubernetes ingresses, this routing can be done from outside of the container - where essentially the traffic is routed as it enters the cluster.

This is a much nicer solution in my view.

But the reason I'm using docker-compose is just for simplicity - it's more for running the cluster on your local machine and just getting the whole thing up and running.

Is there a similar configurable ingress concept for docker-compose?

1
  • you want to run microservices. you want to run on docker alone. you don't want to mix routing concerns into your frontend container. so why not just run a separate routing container that has conf for routes to all the other microservices and the frontend? if you eventually migrate to Kubernetes you would replace the routing component with the built in infrastructure. you can then evaluate different routing tech in the routing container such as openresty if pure nginx isn't smart enough.
    – simbo1905
    Apr 21, 2019 at 7:02

4 Answers 4

1

Kubernetes ingress is implemented by changing the configuration of another container or the cloud load balancer to route traffic to the service port/ip. Docker by itself is fairly lightweight, only runs the containers you start, and does not have external dependencies on things like your cloud load balancer. The solutions to setup a reverse proxy inside a container are almost identical to the kubernetes nginx based ingress controllers, with the key difference being the configuration of that reverse proxy.

There are a variety of docker based reverse proxies that configure themselves, including docker-flow-proxy, nginx-proxy, and Docker-EE ships with interlock that configures HA proxy. Probably the easies solution I've seen to implement is traefik which can be configured to monitor the docker socket for changes and automatically reconfigure based on labels set on your containers.

One important difference from Kubernetes is that docker networks are not flat, you will need to explicitly place the proxy container on the same docker network as your application in order for them to be able to route traffic between each other.

1

jwilder/nginx-proxy image simulates that excatly. Use VIRTUAL_HOST & VIRTUAL_PATH env vars in the backend containers.

example:

version: '3.4'

services:
  ingress:
    image: jwilder/nginx-proxy
    ports:
      - "80:80"
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock:ro

  frontend:
    image: nginx:1.16
    ports:
      - "81:80"
    environment:
      - VIRTUAL_HOST=test.com

  api:
    image: nginx:1.16
    ports:
      - "82:80"
    environment:
      - VIRTUAL_HOST=api.test.com
0

I ended up using dns-proxy-server in combination with nginx reverse proxy (serving as an ingress) on the host using a docker bridge network (not the default one). I wrote Ansible roles and playbooks to run Docker containers in that one network.

In this formation, dns-proxy-server would act as a DNS server for anything running on the host trying to connect to a Docker container (including nginx acting as an ingress). This setup helped with the requirement where you'd wanna have nginx blocks as mentioned in the question.

I have since moved to k3s on a single node for all my container needs.

0

Not a lot of difference between setting up a backend in nginx or an ingress in kubernetes. They work essentially the same way and that's commonly known as reverse proxying, as you said.

What you need in that case is not just a reverse proxy, but an API gateway. We can spend days arguing about your application design, I'm more of a subdomain instead of /prefix guy. But regardless of the decision making, you need something to handle that.

Option 1 Kong Gateway:

https://konghq.com/install/#kong-community

Option 2 Traefik:

https://doc.traefik.io/traefik/

Both work in compose and kubernetes, both are reverse proxies with API gateways capabilities and both have their own kubernetes ingress controllers.

There are loads more, those are the ones I know, trust and have used in production with no awkward surprises.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.