diff --git a/CHANGES.rst b/CHANGES.rst
index e47dd40..e2575de 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -6,7 +6,9 @@ Changelog
 
 Breaking changes:
 
-- *add item here*
+- Default to picking a dynamical port for ZServer layers instead of a static
+  default port.
+  [Rotonen]
 
 New features:
 
diff --git a/src/plone/testing/z2.py b/src/plone/testing/z2.py
index 17f7a83..b5b65f6 100644
--- a/src/plone/testing/z2.py
+++ b/src/plone/testing/z2.py
@@ -973,8 +973,8 @@ class ZServer(Layer):
 
     defaultBases = (STARTUP,)
 
-    host = os.environ.get('ZSERVER_HOST', 'localhost')
-    port = int(os.environ.get('ZSERVER_PORT', 55001))
+    host = os.environ.get('ZSERVER_HOST', '')
+    port = int(os.environ.get('ZSERVER_PORT', 0))
     timeout = 5.0
     log = None
 
@@ -1044,6 +1044,16 @@ def setUpServer(self):
 
         self.zserver = server
 
+        # If we dynamically set the host/port, we want to reset it to localhost
+        if self.host == '':
+            self.zserver.server_name = 'localhost'
+
+        # Refresh the hostname and port in case we dynamically picked them
+        self.host = self.zserver.server_name
+        self['host'] = self.host
+        self.port = self.zserver.server_port
+        self['port'] = self.port
+
     def tearDownServer(self):
         """Close the ZServer socket
         """
diff --git a/src/plone/testing/z2.rst b/src/plone/testing/z2.rst
index 6479e6a..6f7dcfb 100644
--- a/src/plone/testing/z2.rst
+++ b/src/plone/testing/z2.rst
@@ -470,8 +470,8 @@ After layer setup, the resources ``host`` and ``port`` are available, and indica
 
     >>> port = z2.ZSERVER['port']
     >>> import os
-    >>> port == int(os.environ.get('ZSERVER_PORT', 55001))
-    True
+    >>> port == int(os.environ.get('ZSERVER_PORT', 0))
+    0
 
 Let's now simulate a test.
 Test setup does nothing beyond what the base layers do.::