Repository navigation
Question: Communication between azurite container and custom one #851
Description
What are you trying to do?
This question is a copy of the one posted on SO. You can answer here or use SO to get bounty.
I'm currently working on integration tests for my project, which consists of two main components: an application and an engine. Both components are deployed into Azure Container Apps. The engine scales using Azure Storage Queue. The workflow is as follows:
- The application sends a request to the Azure queue.
- The engine consumes the request and processes it.
- Engine sends status to the status queue
- Engine saves artifacts to the blob storage.
I'm facing difficulties in establishing a connection to the Azurite container from my custom engine container. Below is the test case I'm using:
class TestEngine(BaseTestCase):
def test_integration_engine(self):
with Network() as network:
logger.info(f"Network {network.name}")
with AzuriteContainer() \
.with_network(network) \
.with_network_aliases("azurite_server") \
.with_exposed_ports(10000, 10000) \
.with_exposed_ports(10001, 10001) as azurite_container:
connection_string = azurite_container.get_connection_string()
with DockerContainer("57361aab4105730a7ff9d538e9bee44dfe9c24d57cc6e396edff7dbea2de5031") \
.with_env("blob_connection_string", connection_string) \
.with_network(network) \
.with_network_aliases("engine_app") \
.with_exposed_ports(80, 80) as container:
logger.info("Waiting for logs from engine!")
try:
wait_for_logs(container, "Starting handling", timeout=60)
logger.info("Engine processing started according to logs.")
except Exception as e:
logger.warning(f"Engine processing start logs not found within timeout: {e}")
logger.warning("Collecting logs and continuing anyway.")
# send_request_task(connection_string)
print(collect_logs(container, 200))Note: The validation logic and docstrings have been omitted for brevity.
However, the engine process (running on a custom container) is terminated with the following error message:
raise error\nazure.core.exceptions.ServiceRequestError: <urllib3.connection.HTTPConnection object at 0x7fddad8b47c0>: Failed to establish a new connection: [Errno 111] Connection refused\n')]
Could someone help me understand why the connection to the Azurite container is being refused and how I can resolve this issue? Any guidance or suggestions would be greatly appreciated!
Runtime environment
I am using:
- python 3.10,
- testcontainers 4.12.0
Activity
aybanda commentedon Jul 29, 2025
Hi @adendek
I've successfully reproduced and analyzed the issue you're experiencing. The problem occurs when your custom engine container tries to connect to an Azurite container that's on the same custom Docker network. The root cause is in the
get_connection_string()method of theAzuriteContainerclass.Root Cause
The issue is in
modules/azurite/testcontainers/azurite/__init__.pyat line 70-95. Theget_connection_string()method always usesself.get_container_host_ip()to generate connection strings, which returns the Docker host IP regardless of whether the container is on a custom network.When containers are on the same custom network, they should communicate using:
azurite_server)But the current implementation always uses
localhost(Docker host IP), which is not accessible from within the custom network.Your Specific Error
The error you encountered:
This happens because your engine container receives a connection string like:
But from within the custom network,
localhostrefers to the engine container itself, not the Azurite container.Solution
I've implemented a fix that detects network context and generates appropriate connection strings:
Code Changes
File:
modules/azurite/testcontainers/azurite/__init__.pyHow the Fix Works
Network Detection: The method checks if the container is on a custom network (
self._network) and has network aliases (self._network_aliases)Network Context:
azurite_server) and internal container ports (e.g.,10000)localhost) and exposed ports (e.g.,57984)Backward Compatibility: The fix maintains full backward compatibility - existing code without custom networks continues to work exactly as before.
Testing Your Specific Scenario
I've created a test that reproduces your exact scenario:
Before Fix (Your Error):
After Fix (Success):
The test successfully:
Your Use Case - Now Working
Your original code will now work correctly:
Impact
This fix resolves the issue for your specific scenario:
The fix makes the Azurite container more flexible and suitable for complex multi-container test scenarios, which is exactly what you need for your Azure Container Apps integration testing.
Steps to follow
The fix is minimal, well-tested, and maintains full backward compatibility while solving the network communication issue you encountered.
You mentioned a bounty above - if this solution helps resolve your Azurite network communication issue, I'd appreciate your support. I'm available for any further discussion or investigation if needed.
adendek commentedon Jul 29, 2025
Thank you @aybanda ! You are awesome!
Let me check it, and I'll get back to you
adendek commentedon Jul 29, 2025
Hello @aybanda ,
It is almost good, the connection between container and azurite works, but I am not able to access the queue from my local machine.
I have the following code:
I am getting the following error:
The connection from the local environment is needed to trigger the test, sending a request to be consumed and handled by the containerized application.
My custom QueueClient, under the hood uses the following code for authentication:
aybanda commentedon Jul 29, 2025
@adendek
Thank you for the feedback! You're right - the initial fix solved the inter-container communication issue, but created a new problem for local machine access.
I've enhanced the solution to address both scenarios and confirmed that I can reproduce your exact error:
Your Exact Error Reproduced
I've successfully reproduced the exact error you encountered:
This happens because when your local machine tries to use a connection string with the network alias
azurite_server, it cannot resolve that hostname since it only exists within the Docker network.Solution: Dual Connection Strings
The issue is that we need two different connection strings for different access patterns:
Code Changes
I've added a new method to the
AzuriteContainerclass:Updated Usage for Your Code
Key Changes
azurite_container.get_connection_string()(network alias)azurite_container.get_external_connection_string()(localhost)Testing Results
✅ Exact error reproduced: Confirmed the same
Failed to resolve 'azurite_server'error✅ Inter-container communication: Engine container successfully connects using
azurite_server:10000✅ Local machine access: Your local machine successfully connects using
localhost:52149✅ Queue operations: Both contexts can create queues and send messages
✅ Backward compatibility: Existing code without custom networks continues to work
This updated solution addresses both the original inter-container communication issue and your feedback about local machine access. The fix maintains full backward compatibility while providing the flexibility needed for complex multi-container test scenarios.
adendek commentedon Jul 30, 2025
@aybanda Thank you, this works!
Do you have a plan to submit the changes as a PR? Do you know how long it would take to integrate them into a release? Obviously, I can fork the repo, apply them and use my private one, but this would make the deployment a little more complex. Also, this would require maintaining the fork to ensure that new features are propagated properly.
If you are planning to submit the PR, I have one technical suggestion. I am not a fan of extending the interface by adding new methods. What I'd suggest instead is to add an enum to keep track of the types of connection string and then, based on its type, return the proper one. Something like:
In this case, we keep the interface compact and we have a backward compatibility, for the current user perspective nothing changes.
alexanderankin commentedon Jul 30, 2025
adendek commentedon Jul 30, 2025
@alexanderankin thank you for your comment. The size of the changes should be very small, I assume around 100 lines of code, excluding update to the documentation. I can finalize this by the end of the week.
@aybanda do you want to prepare the PR, or should I do this?
All of the code is yours, so I don't want to take the credit (in the form of GH contribution).
Let me know, whether you want to finalize the issue, or should I do this?
aybanda commentedon Aug 1, 2025
@adendek No issues you can proceed with PR
adendek commentedon Aug 11, 2025
I've just created PR #859 with all the changes and unit tests.
feat(azurite): Enhance connection string generation for network and l…