Thanks for raising this question. I am currently working on improving the user experience on connecting application code to LocalStack, and came upon this question. You’re certainly not the first person to find the configuration a little confusing!
You have posted your docker-compose
configuration for the LocalStack container, but you have not shown the configuration for the container running your application code. Just as a sanity check: have you added that container to the bill_network
network as well? I have tried to re-create your issue and found that if I add my “application” code to the bill_network
, then the LocalStack container can be found under the following names:
-
localstack
(the name of the service in docker-compose
)
-
localstack_test
(the explicit hostname
value you’ve specified)
-
localstack.test.internal
(the additional network alias you’ve specified)
This uses a feature of docker called “user-defined bridge networks”, and provides powerful name resolution capabilities.
To complete your example application, I have my “application” service defined in docker-compose
as:
mycontainer:
build: .
environment:
- AWS_ACCESS_KEY_ID=test
- AWS_SECRET_ACCESS_KEY=test
- AWS_REGION=us-east-1
networks:
bill_network:
(note: the last line is not a typo, it means use the network with no additional configuration… yaml is weird)
The application is built with this Dockerfile:
FROM python:3.10-slim
# Install `dig` and `ip` to help diagnose networking
RUN apt-get update && \
apt-get install -y --no-install-recommends \
dnsutils \
iproute2
RUN python3 -m pip install \
boto3
COPY main.py /main.py
CMD ["/main.py"]
and application code
#!/usr/bin/env python
import boto3
# could use
# - `localstack:4566` or
# - `localstack_test:4566` or
# - `localstack.test.internal:4566`
# as the endpoint hostname here
client = boto3.client("s3", endpoint_url="http://localstack:4566")
print(client.list_buckets())
This code is approximately equivalent to your example above, but I am more familiar with Python.
With this example, I am able to run
# start localstack in the background
docker compose up -d localstack
# wait for a few seconds until the container is ready
sleep 5
# run the example "application" code
docker compose run mycontainer
# I get the output below indicating success
# {'ResponseMetadata': {'RequestId': 'TLMHvnoOqVotqVjJxvHpI3sgDNmD6m7WZFCkF665C7dRZVajshsQ', 'HTTPStatusCode': 200, 'HTTPHeaders': {'content-type': 'application/xml; charset=utf-8', 'server': 'Werkzeug/2.1.2 Python/3.10.8, hypercorn-h11', 'date': 'Mon, 20 Feb 2023 11:53:02 GMT, Mon, 20 Feb 2023 11:53:02 GMT', 'x-amzn-requestid': 'TLMHvnoOqVotqVjJxvHpI3sgDNmD6m7WZFCkF665C7dRZVajshsQ', 'access-control-allow-origin': '*', 'connection': 'close', 'last-modified': 'Mon, 20 Feb 2023 11:53:02 GMT', 'x-amz-request-id': '38C08B543275A9C6', 'x-amz-id-2': 'MzRISOwyjmnup38C08B543275A9C67/JypPGXLh0OVFGcJaaO3KW/hRAqKOpIEEp', 'accept-ranges': 'bytes', 'content-language': 'en-US', 'transfer-encoding': 'chunked'}, 'RetryAttempts': 0}, 'Buckets': [], 'Owner': {'DisplayName': 'webfile', 'ID': 'bcaf1ffd86f41161ca5fb16fd081034f'}}
If you’re interested, I have a WIP PR for improving the documentation around this issue (rendered), perhaps this may of some additional use.
Please let me know if this information is useful - I’d like to help you diagnose this issue, as it helps improve the project!
Debugging connectivity
In my application container I install two programs: dig
and ip
. These can help me debug network connectivity. In particular, I’m able to start my application container into a bash shell with docker compose run --entrypoint bash mycontainer
then run
root@4085a3281948:/# dig +noall +answer localstack
localstack. 600 IN A 172.28.0.2
This replies with an IP address 172.28.0.2, indicating that the name localstack
is resolvable to the LocalStack container. I can use docker inspect
on the LocalStack container to get its IP address:
$ docker inspect <container name> \
| jq -r '(.[0].NetworkSettings.Networks | to_entries[]).value.IPAddress'
172.28.0.2
and they match.
HOSTNAME_EXTERNAL
This configuration value is used when returning URLs from LocalStack resources, e.g. an RDS cluster URL. It does not affect the name at which LocalStack can be reached. This is certainly something I want to clear up going forward.