How can multiple services use LocalStack from their own docker-compose.yml files at the same time?

I am trying to spin up several local services that run independently via docker compose. Each uses LocalStack to create AWS services locally. I can get the first one running but when I try to docker compose up the second service it collides on port 4566 because the first service already has that port allocated.

Things of I tried so far:

  • Expose a different port for the second application’s docker-compose. LocalStack eventually shuts down in the container with the message: LocalStack supervisor: localstack process (PID 15) returned with exit code -9
  • Expose another port and forward connections to 4566 (something like ports: - “4511:4566”). LocalStack appears to run but this obviously just ports all traffic to the first application.

Is this supported or do we have to try to move all of our LocalStack setup to its own container and expose the ports there? We have a lot of different services that run from their own docker-compose files. It would be an organizational nightmare to move everything into the same container for LocalStack.

If you want to run multiple instances of localstack, you need to map the edge port (default: 4566), as well as the external service ports to a different range that doesn’t overlap. for instance, if you are starting localstack with the localstack CLI, you could do something like:

GATEWAY_LISTEN=0.0.0.0:4566 EXTERNAL_SERVICE_PORTS_START=4510 EXTERNAL_SERVICE_PORTS_END=4559 MAIN_CONTAINER_NAME=localstack_main_1 localstack start 
GATEWAY_LISTEN=0.0.0.0:4666 EXTERNAL_SERVICE_PORTS_START=4610 EXTERNAL_SERVICE_PORTS_END=4659 MAIN_CONTAINER_NAME=localstack_main_2 localstack start 
GATEWAY_LISTEN=0.0.0.0:4766 EXTERNAL_SERVICE_PORTS_START=4710 EXTERNAL_SERVICE_PORTS_END=4759 MAIN_CONTAINER_NAME=localstack_main_3 localstack start

You can alternatively use this docker-compose.yml file:

version: '3.0'
services:
  localstack-01:
    image: localstack/localstack:1.4.0
    network_mode: bridge
    environment:
      - DEBUG=1
      - DEFAULT_REGION=us-east-1
    volumes:
      - ./localstack/bootstrap:/opt/bootstrap/
      - "/var/run/docker.sock:/var/run/docker.sock"
    ports:
      - '5001:4566'
  localstack-02:
    image: localstack/localstack:1.4.0
    network_mode: bridge
    environment:
      - DEBUG=1
    volumes:
      - ./localstack/bootstrap:/opt/bootstrap/
      - "/var/run/docker.sock:/var/run/docker.sock"
    ports:
      - '5002:4566'
  localstack-03:
    image: localstack/localstack:1.4.0
    network_mode: bridge
    environment:
      - DEBUG=1
    volumes:
      - ./localstack/bootstrap:/opt/bootstrap/
      - "/var/run/docker.sock:/var/run/docker.sock"
    ports:
      - '5003:4566'
  localstack-04:
    image: localstack/localstack:1.4.0
    network_mode: bridge
    environment:
      - DEBUG=1
      - DEFAULT_REGION=us-east-1
    volumes:
      - ./localstack/bootstrap:/opt/bootstrap/
      - "/var/run/docker.sock:/var/run/docker.sock"
    ports:
      - '5004:4566'

I hope this helps!

It sounds like you are running multiple separate docker compose stacks at the same time, but each one contains a LocalStack instance right?

If your application(s) can be run from your docker-compose.yml files then you don’t need to bind any ports to the host, and you can keep all of your networking within the docker network.

For example:

version: '3.0'
services:
  localstack:
    image: localstack/localstack
    environment:
      - DEBUG=1
      - DEFAULT_REGION=us-east-1
      - HOSTNAME_EXTERNAL=localstack
      - LOCALSTACK_HOST=localstack
    volumes:
      - ./localstack/bootstrap:/opt/bootstrap/
      - "/var/run/docker.sock:/var/run/docker.sock"

  application:
    image: ghcr.io/simonrw/docker-debug:main
    command: sleep infinity

where the application service represents your application. In this case it’s running a debug image that I maintain. Notice the ports block is absent, meaning no ports are published to the host.

You can connect from the application container to your LocalStack instance over the docker network via the service hostname. To demonstrate this with the compose example posted above, you can run:

docker compose up
# in another terminal
docker compose exec application curl http://localstack:4566/_localstack/health

and you should get the response from the LocalStack health endpoint from the container running as service localstack.

You can then run multiple copies if this stack (or your different stacks) at the same time and there should be no port collisions.

For more information, you can see our network troubleshooting guide.

Thanks! The problem we’re having right now is that we are trying to connect to an API Gateway created by localstack directly from outside of the container rather than route to the API Gateway through the application itself.

I’m still new to localstack but to do that it seems like I would need to bind port 4566, right?