Skip to content

Commit af382f7

Browse files
authored
feat(mqtt): MosquittoContainer: Add version 2.1.2 (#978)
This PR enables the testcontainer MosquittoContainer (which I contributed to this project a few years ago) to work with version 2.1.2 and higher of Mosquitto. In particular this PR is fixing an issue where rw mode is now needed for /data partition for Mosquitto version 2.1.1 (released 2026-02-04), which fixed a PUID/PGID issue. In addition, it contains a fix for Mosquitto warnings generated by the `listener` directive appearing after `protocol` directive.
1 parent b12ae13 commit af382f7

File tree

4 files changed

+19
-6
lines changed

4 files changed

+19
-6
lines changed

core/testcontainers/core/container.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ def __init__(
8282
for vol in volumes:
8383
self.with_volume_mapping(*vol)
8484

85+
self.tmpfs: dict[str, str] = {}
86+
8587
self.image = image
8688
self._docker = DockerClient(**(docker_client_kw or {}))
8789
self._container: Optional[Container] = None
@@ -198,6 +200,7 @@ def start(self) -> Self:
198200
ports=cast("dict[int, Optional[int]]", self.ports),
199201
name=self._name,
200202
volumes=self.volumes,
203+
tmpfs=self.tmpfs,
201204
**{**network_kwargs, **self._kwargs},
202205
)
203206

@@ -270,6 +273,16 @@ def with_volume_mapping(self, host: Union[str, PathLike[str]], container: str, m
270273
self.volumes[str(host)] = mapping
271274
return self
272275

276+
def with_tmpfs_mount(self, container_path: str, size: Optional[str] = None) -> Self:
277+
"""Mount a tmpfs volume on the container.
278+
279+
:param container_path: Container path to mount tmpfs on (e.g., '/data')
280+
:param size: Optional size limit (e.g., '256m', '1g'). If None, unbounded.
281+
:return: Self for chaining
282+
"""
283+
self.tmpfs[container_path] = size or ""
284+
return self
285+
273286
def get_wrapped_container(self) -> "Container":
274287
return self._container
275288

modules/mqtt/testcontainers/mqtt/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,10 @@ def start(self, configfile: Optional[str] = None) -> Self:
121121
# default config file
122122
configfile = Path(__file__).parent / MosquittoContainer.CONFIG_FILE
123123
self.with_volume_mapping(configfile, "/mosquitto/config/mosquitto.conf")
124+
# since version 2.1.1 - 2026-02-04, which fixed a PUID/PGID issue, the container needs to write to the data directory,
125+
# so we mount it as tmpfs for better performance in tests
126+
self.with_tmpfs_mount("/data")
127+
124128
# if self.password:
125129
# # TODO: add authentication
126130
# pass
Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
# see https://mosquitto.org/man/mosquitto-conf-5.html
22

3-
protocol mqtt
4-
user root
3+
listener 1883
54
log_dest stdout
65
allow_anonymous true
76

@@ -14,7 +13,4 @@ log_timestamp_format %Y-%m-%d %H:%M:%S
1413
persistence true
1514
persistence_location /data/
1615

17-
listener 1883
18-
protocol mqtt
19-
2016
sys_interval 1

modules/mqtt/tests/test_mosquitto.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from testcontainers.mqtt import MosquittoContainer
44

5-
VERSIONS = ["1.6.15", "2.0.18"]
5+
VERSIONS = ["1.6.15", "2.0.18", "2.1.2-alpine"]
66

77

88
@pytest.mark.parametrize("version", VERSIONS)

0 commit comments

Comments
 (0)