Running MockServer
Pick the way that fits your environment; every option serves mock + proxy on port 1080.
The fastest way to run MockServer is a single command — pick whichever fits your environment. Every option below starts a server that mocks and proxies HTTP and HTTPS on one port (default 1080):
# Docker — no Java required
docker run -p 1080:1080 mockserver/mockserver
# Node — no Java and no Docker (downloads a self-contained bundle)
npx -p mockserver-node mockserver run -p 1080
# Homebrew (macOS / Linux)
brew install mockserver && mockserver run -p 1080
Confirm it is up (the status endpoint returns 200 once MockServer is ready):
curl -i -X PUT http://localhost:1080/mockserver/status
MockServer is flexible and support numerous usage patterns.
MockServer can be run:
- programmatically via a Java API in an @Before or @After method
- in-process, without an HTTP server, by passing requests to it as Java method calls (for example in AWS Lambda)
- using a JUnit 4 @Rule via a @Rule annotated field in a JUnit 4 test
- using a JUnit 5 Test Extension via a @ExtendWith annotated JUnit 5 class
- using a Spring Test Execution Listener via a @MockServerTest annotated test class
- as a Docker container in any Docker enabled environment
- via a Helm chart in any Kubernetes environment
- from the command line as a stand-alone process in a test environment
- via a Maven Plugin as part of a Maven build cycle
- as a Node.js (npm) module from any Node.js code
- as a Grunt plugin as part of a Grunt build cycle
- as a deployable WAR to an existing application server
- via a client library binary launcher (Node, Python, Ruby, Go, .NET, Rust) — downloads a cross-platform, JVM-less binary bundle automatically
- as a throwaway Testcontainers container started and stopped automatically by your test run
- as a shared, centralised deployment across multiple teams or CI pipelines — another good option when several projects share one running MockServer
To simplify configuration, all versions (except the deployable WAR) use a single port to support the control plane and data plane in HTTP, HTTPS or SOCKS.
Keeping tests fast: for the patterns that keep test suites quick — one container per suite with reset() between tests, container reuse, memory limits, and in-process alternatives for JVM tests — see Fast Tests: Startup Time, Memory and Reuse.
MockServer is available in the following formats:
- java dependency
- Docker container
- Helm chart for Kubernetes
- executable jar
- Homebrew package
- maven plugin
- npm plugin
- Grunt plugin
- deployable WAR that runs on JEE web servers
- client library binary bundle — a self-contained, cross-platform binary (no Java required) downloaded automatically by the Node, Python, Ruby, Go, .NET, and Rust clients
It is also possible to build and run MockServer directly from source code
Maven Plugin
To run MockServer as part of your build add the following plugin to your pom.xml:
<plugin>
<groupId>org.mock-server</groupId>
<artifactId>mockserver-maven-plugin</artifactId>
<version>9.2.0</version>
<configuration>
<serverPort>1080</serverPort>
<logLevel>DEBUG</logLevel>
<initializationClass>org.mockserver.maven.ExampleInitializationClass</initializationClass>
</configuration>
<executions>
<execution>
<id>process-test-classes</id>
<phase>process-test-classes</phase>
<goals>
<goal>start</goal>
</goals>
</execution>
<execution>
<id>verify</id>
<phase>verify</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
This will start MockServer during the process-test-classes phase and will stop MockServer during the verify phase. For more details about Maven build phases see: Introduction to the Build Lifecycle.
This ensures that any integration tests you run during the test or integration-test phases can use MockServer on the port specified.
It is also possible to run MockServer as a forked JVM using the runForked and stopForked goals as follows:
<plugin>
<groupId>org.mock-server</groupId>
<artifactId>mockserver-maven-plugin</artifactId>
<version>9.2.0</version>
<configuration>
<serverPort>1080</serverPort>
<logLevel>DEBUG</logLevel>
</configuration>
<executions>
<execution>
<id>process-test-classes</id>
<phase>process-test-classes</phase>
<goals>
<goal>runForked</goal>
</goals>
</execution>
<execution>
<id>verify</id>
<phase>verify</phase>
<goals>
<goal>stopForked</goal>
</goals>
</execution>
</executions>
</plugin>
Stop MockServer Even When Tests Fail
If you use the runForked goal as above and the test phase fails (because a test has failed) MockServer will not be stopped as Maven does not run any more phases after a phase has failed. In the case above the verify phase is not run if a test fails so the forked MockServer will not be stopped.
If you want to ensure MockServer is stopped even when there are test failures make sure you use start and stop goals as these run MockServer on a separate thread that is stopped however maven exits (even if a test fails).
Alternatively a TestListener can be used with maven-surefire-plugin to ensure that MockServer is stopped even when a test fails, as follows:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.5.5</version>
<configuration>
<properties>
<property>
<name>listener</name>
<value>org.mockserver.maven.StopMockServerTestListener</value>
</property>
</properties>
</configuration>
</plugin>
The Maven plugin can also be used from the command line to start and stop MockServer, as follows:
To run MockServer synchronously and block:
mvn mockserver:run
To run MockServer asynchronously as a forked JVM:
mvn mockserver:runForked
Or:
mvnw org.mock-server:mockserver-maven-plugin:9.2.0:runForked -DserverPort=1080
To stop a forked instance of MockServer running on the same machine:
mvn mockserver:stopForked
Or:
mvnw org.mock-server:mockserver-maven-plugin:9.2.0:stopForked -DserverPort=1080
The stopForked goal assumes that MockServer is running on the same physical machine as it uses 127.0.0.1 to communicate with MockServer stop socket.
The Maven plugin has the following goals:
- start - start MockServer, do not block, but stop when build ends
- stop - stop a MockServer started earlier as part of the current build
- run - run MockServer and block waiting for requests (timeout config if provided limits how long to block for)
- runForked - run MockServer as separate forked JVM, do not block, stay alive when build ends
- stopForked - stop a forked MockServer, previously started by a runForked goal
If MockServer refuses to start (for example because a port it was given is already in use, or because the dnsPort or http3Port it was given cannot be opened), the start, run and runForked goals fail the build with the reason, rather than carry on without a running MockServer. The runForked goal also fails the build, and stops the forked JVM, if MockServer has not started within about 75 seconds.
The Maven plugin can be configured with the following properties:
- serverPort - The port the MockServer listens for incoming request. Port unification is used to support both HTTP and HTTPS on the same port (required: true)
- proxyRemotePort - The port proxied requests are forwarded to (required: false)
- proxyRemoteHost - The host proxied requests are forwarded to (required: false)
- timeout - How long to block waiting for MockServer, after the timeout the plugin will shutdown MockServer, used by run goal, 0 means wait indefinitely (required: false, default: 0)
- logLevel - The logging level (required: false, default: INFO)
- skip - Prevent the plugin from running (required: false, default: false)
- initializationClass - To enable the creation of default expectations a class can be specified to initialize expectations in MockServer, this class must implement org.mockserver.client.initialize.PluginExpectationInitializer interface. The initializeExpectations(MockServerClient mockServerClient) method will be called once MockServer has been started. Note: that the plugin must be started during the process-test-classes to ensure that the initialization class has been compiled from either src/main/java or src/test/java locations. In addition the initializer can only be used with start and run goals, it will not work with the runForked goal as a JVM is forked with a separate classpath. (required: false, default: false)
Client API - starting and stopping
Use the client API to run or interact with MockServer programmatically.
For more details about the different dependency versions see the page on Maven Central
For example add the following maven dependency:
<!-- mockserver -->
<dependency>
<groupId>org.mock-server</groupId>
<artifactId>mockserver-netty-no-dependencies</artifactId>
<version>9.2.0</version>
</dependency>
To start the server or proxy create a client, for example by using one of the start factory methods ClientAndServer.startClientAndServer as follows:
Add includes:
import static org.mockserver.integration.ClientAndServer.startClientAndServer;
Add fields:
private ClientAndServer mockServer;
Use factory method to start server and client when appropriate, for example in @Before method:
@Before
public void startMockServer() {
mockServer = startClientAndServer(1080);
}
Stop server and client when appropriate, for example in @After method:
@After
public void stopMockServer() {
mockServer.stop();
}
With DNS mocking on, mockServer.getDnsPort() gives the UDP port of the DNS mock server, the port MockServer chose unless dnsPort is set, or -1 while DNS mocking is off.
The mockserver-example project contains an example test called BooksPageIntegrationTest that demonstrates a fully working example.
In-Process, Without an HTTP Server
InProcessMockServer handles requests as Java method calls, without opening a port. Use it where requests reach your code as objects rather than over a socket, such as an AWS Lambda handler, or to test an HTTP adapter without network I/O. It is like WireMock's DirectCallHttpServer. It is in mockserver-core, which mockserver-netty already includes.
try (InProcessMockServer mockServer = new InProcessMockServer()) {
mockServer.upsert(
new Expectation(request().withPath("/orders/1"))
.thenRespond(response().withStatusCode(200).withBody("{\"id\": 1}"))
);
HttpResponse response = mockServer.handle(request().withMethod("GET").withPath("/orders/1"));
mockServer.verify(request().withPath("/orders/1"), VerificationTimes.once());
}
Requests go through the same matching and actions as a running MockServer, so expectations, response templates, delays, forwards, class callbacks, verification and the log behave the same. Most of the REST API works too: pass a request such as PUT /mockserver/expectation with a JSON body to handle. The routes that only a running server answers (/mockserver/configuration, /mockserver/ready, /mockserver/metrics and the dashboard) return 404. The Java methods are upsert, verify, retrieveRecordedRequests and reset, and getHttpState() gives access to everything else.
- Delays: handle blocks the calling thread for a response delay, and for a forward until the upstream answers (at most maxSocketTimeoutInMillis). handleAsync returns a CompletableFuture straight away and completes it when the delay has passed or the upstream has answered.
- Forwards use MockServer's own HTTP client, so the target must be reachable over the network. They go through forwardHttpProxy, forwardHttpsProxy or forwardSocksProxy when one is set.
- Security: the Java methods (upsert, verify, reset and the others) are plain method calls and are not authenticated. REST requests passed to handle are checked against the control-plane authentication settings, as on a running server. If handle receives traffic from callers you do not trust, for example in a Lambda function, turn control-plane authentication on or drop /mockserver/ paths before calling handle. With data-plane authentication on, a mocked request passed to handle must carry the credentials in its headers, as over HTTP; there is no TLS, so client certificates do not count.
- Unmatched requests get a 404. They are never proxied to the host in their Host header, because every request is treated as addressed to MockServer itself. proxyRemoteHost still applies.
- Not available, because they need a connection: object callbacks (which use a WebSocket, so use a class callback instead), SSE, WebSocket and gRPC streaming responses, and HttpError connection faults.
- Responses are returned as MockServer HttpResponse objects. A missing status code becomes 200 and a body's content type becomes a Content-Type header, as they would on the wire. Framing headers such as Content-Length are not added.
- Close it with close() (or try-with-resources). This stops its threads, which include the scheduler, the event log and the forward client. A delayed response that is still pending completes when its delay ends. After close(), every method throws IllegalStateException.
- Extensions load as they do on a running server: pass them with configuration().extensions(MyExtension.class) or the extensions property. They start when the instance is created and stop, in reverse order, when it is closed. Their admin routes are reached by passing a request for /mockserver/extensions/<name>/... to handle, with the same control-plane authentication as other REST requests; they run on the calling thread, with no extensionAdminTimeoutMillis. onStarted receives an empty port list, and a settings listener is not called, because PUT /mockserver/configuration is not available in-process. Served-request and expectation listeners and $ext template helpers work as usual.
- Reset clears this instance's expectations and log. As with a running server, it also resets the settings that every MockServer in the same JVM shares, such as rate limits, chaos and quotas.
Running MockServer via a JUnit 4 @Rule
MockServer can be run using the MockServerRule. The MockServerRule starts MockServer (for both mocking and proxying) on a free port before the any test runs and stops MockServer after all tests have completed.
An instance of MockServerClient is assigned to any field in the unit test of type org.mockserver.client.MockServerClient. Alternatively an instance of MockServerClient can be retrieved from the MockServerRule using the method getClient().
@Rule
public MockServerRule mockServerRule = new MockServerRule(this);
private MockServerClient mockServerClient;
The MockServerRule can be added to your project by including the following maven dependency:
<dependency>
<groupId>org.mock-server</groupId>
<artifactId>mockserver-junit-rule-no-dependencies</artifactId>
<version>9.2.0</version>
</dependency>
Any test method can now use the mockServerClient field to create expectation or verify requests.
The MockServerRule has the following constructors:
/**
* Start MockServer prior to test execution and stop MockServer after the tests have completed.
* This constructor dynamically allocates a free port for MockServer to use.
*
* @param target an instance of the test being executed
*/
public MockServerRule(Object target);
/**
* Start MockServer prior to test execution and stop MockServer after the tests have completed.
* This constructor dynamically allocates a free port for MockServer to use.
*
* @param target an instance of the test being executed
* @param perTestSuite indicates how many instances of MockServer are created
* if true a single MockServer is created per JVM
* if false one instance per test class is created
*/
public MockServerRule(Object target, boolean perTestSuite);
/**
* Start the proxy prior to test execution and stop the proxy after the tests have completed.
* This constructor dynamically create a proxy that accepts HTTP(S) requests on the specified port
*
* @param target an instance of the test being executed
* @param port the HTTP(S) port for the proxy
*/
public MockServerRule(Object target, Integer... ports);
/**
* Start the proxy prior to test execution and stop the proxy after the tests have completed.
* This constructor dynamically create a proxy that accepts HTTP(S) requests on the specified port
*
* @param target an instance of the test being executed
* @param perTestSuite indicates how many instances of MockServer are created
* if true a single MockServer is created per JVM
* if false one instance per test class is created
* @param port the HTTP(S) port for the proxy
*/
public MockServerRule(Object target, boolean perTestSuite, Integer... ports);
mockServerRule.getPort() gives the HTTP(S) port and, with DNS mocking on, mockServerRule.getDnsPort() gives the UDP port of the DNS mock server (-1 while DNS mocking is off). Turn DNS mocking on with the mockserver.dnsEnabled system property.
Reducing in-memory store size (optional). Each MockServer keeps an in-memory event log and expectation store whose default sizes are derived from the JVM's maximum heap (up to maxLogEntries = 250000 / maxExpectations = 15000) and stay constant for the life of the JVM. A test suite that starts many short-lived servers in one JVM can trim its memory footprint by enabling dev mode with -Dmockserver.devMode=true (or MOCKSERVER_DEV_MODE=true), which fixes both stores at 1000 entries — measured at roughly 117 MB down to 52 MB across 32 servers in one JVM. Enabling dev mode applies JVM-wide, not only to servers the MockServerRule started, so a ClientAndServer you construct directly is affected too. If 1000 is too small for a test — a full store overwrites its oldest entries, so a verify can stop matching once more than 1000 requests or expectations accumulate in a single server — raise the limits explicitly with -Dmockserver.maxLogEntries=… / -Dmockserver.maxExpectations=… (or the matching MOCKSERVER_* environment variables, or a mockserver.properties file); an explicit size always wins over the dev-mode default. When dev mode is enabled MockServer logs the effective sizes at INFO once per JVM.
Running MockServer via a JUnit 5 Test Extension
MockServer can be run using the Test Extension MockServerExtension. The MockServerExtension starts MockServer (for both mocking and proxying) before the any test runs and stops MockServer after all tests have completed.
The port(s) MockServer uses can be controlled using MockServerSettings
An instance of MockServerClient or ClientAndServer is injected into any method using Parameter Resolution this includes: constructors, lifecycle methods (like @BeforeEach / @BeforeAll), or test methods.
The MockServerExtension Test Extension can be added to your project by including the following maven dependency:
<dependency>
<groupId>org.mock-server</groupId>
<artifactId>mockserver-junit-jupiter-no-dependencies</artifactId>
<version>9.2.0</version>
</dependency>
Warning: @MockServerSettings already includes @ExtendWith(MockServerExtension.class) internally. Do not add both annotations to the same test class — doing so will cause MockServer to start twice, resulting in port conflicts or unexpected behaviour. Use @ExtendWith(MockServerExtension.class) alone for default settings, or @MockServerSettings alone when you need to configure ports or other options.
The following code examples show how to use the MockServerExtension Test Extension.
@ExtendWith(MockServerExtension.class)
@MockServerSettings(ports = {8787, 8888})
class ExampleTestClass {
private final ClientAndServer client;
public ExampleTestClass(ClientAndServer client) {
this.client = client;
}
@Test
void testSomething() {
// ...
}
}@ExtendWith(MockServerExtension.class)
class ExampleTestClass {
private final ClientAndServer client;
public ExampleTestClass(ClientAndServer client) {
this.client = client;
}
@Test
void testSomething() {
// ...
}
}@ExtendWith(MockServerExtension.class)
class ExampleTestClass {
private MockServerClient client;
@BeforeEach
public void beforeEachLifecycleMethod(MockServerClient client) {
this.client = client;
}
@Test
void testSomething() {
// ...
}
}@ExtendWith(MockServerExtension.class)
class ExampleTestClass {
@Test
void testSomething(MockServerClient client) {
// ...
}
}By default a shared MockServer instance accumulates expectations across all tests in the class. Add resetBeforeEach = true to @MockServerSettings to have MockServer automatically reset (clear all expectations, recorded requests, and logs) before each test method runs — without you having to call client.reset() yourself.
@MockServerSettings(ports = {1080}, resetBeforeEach = true)
class IsolatedTestClass {
private final MockServerClient client;
public IsolatedTestClass(MockServerClient client) {
this.client = client;
}
@Test
void firstTest() {
// MockServer is clean — no expectations from any earlier test
client.when(request().withPath("/hello"))
.respond(response().withBody("world"));
// ...
}
@Test
void secondTest() {
// MockServer is clean again — expectations from firstTest are gone
client.when(request().withPath("/goodbye"))
.respond(response().withBody("farewell"));
// ...
}
}
The reset fires in BeforeEachCallback, which runs before any @BeforeEach methods in the test class. When combined with perTestSuite = true the same shared server is reset before each test across all test classes in the suite.
An injected ClientAndServer also gives, with DNS mocking on, the UDP port of the DNS mock server from getDnsPort() (-1 while DNS mocking is off). Turn DNS mocking on with the mockserver.dnsEnabled system property, or register an extension with a server of your own:
class ExampleDnsTestClass {
@RegisterExtension
static MockServerExtension mockServer = new MockServerExtension(
ClientAndServer.startClientAndServer(configuration().dnsEnabled(true))
);
@Test
void testSomething(ClientAndServer client) {
int dnsPort = client.getDnsPort();
// ...
}
}
Reducing in-memory store size (optional). Each MockServer keeps an in-memory event log and expectation store whose default sizes are derived from the JVM's maximum heap (up to maxLogEntries = 250000 / maxExpectations = 15000) and stay constant for the life of the JVM. A test suite that starts many short-lived servers in one JVM can trim its memory footprint by enabling dev mode with -Dmockserver.devMode=true (or MOCKSERVER_DEV_MODE=true), which fixes both stores at 1000 entries — measured at roughly 117 MB down to 52 MB across 32 servers in one JVM. Enabling dev mode applies JVM-wide, not only to servers the MockServerExtension started, so a ClientAndServer you construct directly is affected too. If 1000 is too small for a test — a full store overwrites its oldest entries, so a verify can stop matching once more than 1000 requests or expectations accumulate in a single server — raise the limits explicitly with -Dmockserver.maxLogEntries=… / -Dmockserver.maxExpectations=… (or the matching MOCKSERVER_* environment variables, or a mockserver.properties file); an explicit size always wins over the dev-mode default. When dev mode is enabled MockServer logs the effective sizes at INFO once per JVM.
Running MockServer via Spring TestExecutionListener @MockServerTest
MockServer can be run using @MockServerTest. The mockserver-spring-test-listener dependency registers a Spring TestExecutionListener which starts MockServer on a free port if the test class is annotated with @MockServerTest. MockServer is reset after each test and closed after all tests via a shutdown hook.
As the MockServer instance is shared between all test classes @MockServerTest does not support parallel test execution, unless each test uses a unique value in each request matcher.
The TestExecutionListener with @MockServerTest can be added to your project by including the following maven dependency:
<dependency>
<groupId>org.mock-server</groupId>
<artifactId>mockserver-spring-test-listener-no-dependencies</artifactId>
<version>9.2.0</version>
</dependency>
An instance of MockServerClient is assigned to any field in the unit test of type org.mockserver.client.MockServerClient.
@MockServerTest
@RunWith(SpringRunner.class)
public class ExampleSpringTestListenerTestWithClientInjection {
private MockServerClient mockServerClient;
@Test
public void testSomething() {
// test code
}
}
If you want to configure a client (Spring Bean) to use MockServer you can create a test property with ${mockServerPort} placeholder. This is replaced by the chosen free port for MockServer.
@RunWith(SpringRunner.class)
@MockServerTest("server.url=http://localhost:${mockServerPort}/path")
@ContextConfiguration(classes = MockServerTestFullSampleTest.Config.class)
public class ExampleSpringTestListenerTestWithUrlInjection {
static class Client {
@Value("${server.url}")
private URI serverUrl;
private final RestTemplate restTemplate = new RestTemplate();
@Nullable
public <T> T getResult(String path, Class<T> responseType) {
return restTemplate.getForObject(serverUrl + path, responseType);
}
}
static class Config {
@Bean
public Client client() {
return new Client();
}
}
@Autowired
private Client client;
private MockServerClient mockServerClient;
@Test
public void testSomething() {
// test code
}
}
Properties prefixed with mockserver. are applied to the MockServer Configuration object, allowing declarative configuration of MockServer directly in the annotation. All other properties are injected into the Spring Environment as test properties (with ${mockServerPort} substitution). This enables setting any configuration property such as initializationClass, logLevel, maxExpectations, etc. without needing separate system property setup.
Note: Because the MockServer instance is shared across all test classes, mockserver.* configuration properties from the first @MockServerTest class to run are used. If multiple test classes specify different mockserver.* properties, only the first class's configuration takes effect.
@RunWith(SpringRunner.class)
@MockServerTest({
"server.url=http://localhost:${mockServerPort}/path",
"mockserver.initializationClass=org.mockserver.server.initialize.ExpectationInitializerExample",
"mockserver.logLevel=WARN"
})
public class ExampleSpringTestListenerTestWithConfiguration {
private MockServerClient mockServerClient;
@Test
public void testSomething() {
// expectations from ExpectationInitializerExample are available immediately
}
}
The free port itself is also added as test property and can be retrieved with @MockServerPort.
@MockServerTest
@RunWith(SpringRunner.class)
public class ExampleSpringTestListenerTestWithPortInjection {
@MockServerPort
Integer mockServerPort;
@Test
public void testSomething() {
// test code
}
}
With DNS mocking on (mockserver.dnsEnabled=true), the UDP port of the DNS mock server, which MockServer chooses unless mockserver.dnsPort is set, is added the same way: as the ${mockServerDnsPort} placeholder and with @MockServerDnsPort. Both are -1 while DNS mocking is off. See DNS Port.
@MockServerTest({
"mockserver.dnsEnabled=true",
"resolver.address=127.0.0.1:${mockServerDnsPort}"
})
@RunWith(SpringRunner.class)
public class ExampleSpringTestListenerTestWithDnsPortInjection {
@MockServerDnsPort
Integer mockServerDnsPort;
@Test
public void testSomething() {
// test code
}
}
Several Named MockServer Instances
When the code under test calls more than one service, start one MockServer per service with @MockServerInstance. Repeat the annotation once per service; each instance gets its own free port.
Each instance adds these properties to the Spring Environment:
mockserver.<name>.port, the instance's portmockserver.<name>.baseUrl,http://localhost:<port>- every name in
portProperties(set to the port) andbaseUrlProperties(set to the base URL), so your application's own properties, such aspayment.url, point at the mock. These override values fromapplication.propertiesor@TestPropertySource
A MockServerClient (or ClientAndServer) field annotated with @InjectMockServer("<name>") receives the client for that instance. initializationJsonPath loads expectations into one instance only. It accepts a JSON file, a classpath resource, a glob such as src/test/resources/payment/*.json, or a file-system directory (every *.json file directly in it; a classpath directory is not expanded). properties takes the same mockserver.* settings as @MockServerTest, for that instance only.
@RunWith(SpringRunner.class)
@SpringBootTest
@MockServerInstance(
name = "payment",
baseUrlProperties = "payment.url",
initializationJsonPath = "src/test/resources/payment"
)
@MockServerInstance(
name = "inventory",
portProperties = "inventory.port",
properties = "mockserver.logLevel=WARN"
)
public class ExampleSpringTestListenerTestWithNamedInstances {
@InjectMockServer("payment")
private MockServerClient paymentMock;
@InjectMockServer("inventory")
private MockServerClient inventoryMock;
@Value("${mockserver.inventory.baseUrl}")
private String inventoryBaseUrl;
@Test
public void testSomething() {
inventoryMock
.when(request().withPath("/stock/42"))
.respond(response().withBody("{\"available\": 3}"));
// test code that calls ${payment.url} and ${inventory.port}
paymentMock.verify(request().withPath("/payments"), once());
}
}
Each instance is reset after every test method. After a reset it restores the expectations it had when it started, so an initialization file applies to every test, not only the first; each time-to-live starts again from the reset. Changes to an initialization file during the run (with mockserver.watchInitializationJson=true) are not part of what is restored.
An instance stops when the last Spring context using it closes. Spring caches test contexts, so this is usually when the JVM exits, but an instance stops earlier when its context is marked with @DirtiesContext or is evicted from Spring's context cache. Test classes that declare an instance with the same name and settings share that instance and its Spring context; don't call stop() on an injected instance, because a later test class sharing the context would fail with an error naming the instance.
Parallel tests: don't run test classes that share an instance in parallel in the same JVM, because one class's reset clears the other's expectations and recorded requests. Some state, such as chaos and quota settings, is shared by every MockServer in the JVM, and any instance's reset clears it, including for the @MockServerTest server.
Instance names may contain letters, digits, - and _, and each name can be declared once in a test class and its superclasses. @MockServerInstance can be used alone or with @MockServerTest; un-annotated MockServerClient fields still receive the @MockServerTest instance.
Running From Command Line
MockServer can be run from the command line in the following ways:
- using homebrew i.e. brew install mockserver && mockserver run -p 1080
- using java directly i.e. java -jar mockserver-netty-9.2.0-no-dependencies.jar run -p 1080
- using maven plugin i.e. mvn org.mock-server:mockserver-maven-plugin:9.2.0:runForked
- using docker i.e. docker run -d --rm -p 1080:1080 mockserver/mockserver
Running From Command Line - Using Homebrew
Homebrew, a package manager for macOS and Linux, can be used to install MockServer, as follows:
brew install mockserver
The MockServer formula in Homebrew performs the following actions:
- installs the binaries and scripts
- creates the log directory
- adds the scripts to the PATH variable
Once MockServer has been installed by Homebrew it is available from any command shell as the mockserver command.
mockserver run -p 1080
Running From Command Line - Using Java
MockServer can be run directly from the command line using java as follows:
download mockserver-netty-9.2.0-no-dependencies.jar from Maven Central
-
java -jar <path to mockserver-netty-9.2.0-no-dependencies.jar> run -p <port>
Subcommands
The MockServer CLI uses subcommands. The most common is run, which starts MockServer and accepts expectations and proxied traffic on the specified port. You can omit the subcommand name entirely — bare flags like -p 1080 are treated as run automatically.
| Subcommand | What it does | Example |
|---|---|---|
| run | Start MockServer in mock and/or proxy mode (default subcommand) | mockserver run -p 1080 |
| proxy | Start MockServer as a pure forwarding proxy — shorthand for run --proxy-to | mockserver proxy --to api.example.com:8080 -p 1080 |
| openapi | Start MockServer and automatically create expectations from an OpenAPI spec | mockserver openapi ./petstore.yaml -p 1080 |
| import | Load expectations from a JSON file into an already-running MockServer | mockserver import ./expectations.json -p 1080 |
| lint | Check expectation files for expectations that can never match or will not match as written, with no server needed | mockserver lint ./expectations.json |
| demo | Start MockServer pre-loaded with a small set of example expectations and print a getting-started URL and sample curl — the fastest way to try MockServer | mockserver demo -p 1080 |
| version | Print MockServer version and exit | mockserver version |
| help | Print usage for the top command or any subcommand | mockserver help run |
Options for run
| Option | Description | Configuration property |
|---|---|---|
| -p, --port <port> | Port(s) to listen on. Comma-separated list to bind multiple ports, e.g. 1080,1081. Port unification means HTTP, HTTPS, and all proxy protocols share the same port. | mockserver.serverPort |
| --proxy-to <target> | Forward unmatched requests to the given target. Enables port-forwarding (proxy) mode. Accepts host:port, https://host[:port] (port 443 inferred from scheme), or http://host[:port] (port 80 inferred). A bare hostname with no port and no http(s):// scheme is rejected with an error. | mockserver.proxyRemoteHost + mockserver.proxyRemotePort |
| --openapi <specUrlOrPath> | Initialize expectations from an OpenAPI spec on startup. Accepts a file path or URL. | mockserver.initializationOpenAPIPath |
| --init <fileOrGlob> | Initialize expectations from a JSON file or glob pattern on startup. | mockserver.initializationJsonPath |
| --watch | Watch the initializer/expectations file(s) (from --init / --openapi) and live-reload expectations when they change, without restarting MockServer (~5s poll). Handy for editing expectations while the server runs. Also available as MOCKSERVER_WATCH_INITIALIZATION_JSON=true or -Dmockserver.watchInitializationJson=true. | mockserver.watchInitializationJson |
| --persist <file> | Enable expectation persistence and write expectations to the given file. MockServer reloads the file on restart. | mockserver.persistExpectations + mockserver.persistedExpectationsPath |
| -l, --log-level <level> | Set the log level. Accepts SLF4J levels: TRACE, DEBUG, INFO, WARN, ERROR, OFF, or Java Logger levels: FINEST, FINE, INFO, WARNING, SEVERE, OFF. Default: INFO. | mockserver.logLevel |
| --dev | Enable developer-friendly defaults for laptop and test-suite workloads. Sets maxLogEntries=1000 and maxExpectations=1000 (reducing memory usage). Any explicit configuration (system property, environment variable, or properties file) overrides the dev-mode defaults. Also available as MOCKSERVER_DEV_MODE=true or -Dmockserver.devMode=true. | mockserver.devMode |
| --validate-openapi <spec> | Validate every forwarded/proxied request and its upstream response against the given OpenAPI spec. Accepts a URL, file path, or inline JSON/YAML payload. Violations are logged as OPENAPI_REQUEST_VALIDATION_FAILED and OPENAPI_RESPONSE_VALIDATION_FAILED events. By default, traffic is not blocked — combine with --validate-enforce to reject non-conformant traffic. | mockserver.validateProxyOpenAPISpec |
| --validate-enforce | When combined with --validate-openapi, reject requests that violate the spec with a 400 status code, and replace non-conformant upstream responses with a 502. Without this flag, violations are report-only (logged but traffic flows unmodified). | mockserver.validateProxyEnforce |
| --print-config | Print the effective configuration and exit. Each known property is listed as name = value [source], where source is the tier that supplied the value — system-property, properties-file, environment-variable, default, or runtime-set (a value applied at runtime in Java code) — so you can see exactly which value MockServer will use and where it came from. Properties left at their built-in default show the default's value with the source default; a default worked out from the JVM heap size or another property shows the value worked out now. A property changed from its default ends its line with (default: ...), the built-in default it replaced. Sensitive values (passwords, API keys, tokens, secrets, private keys, credentials) are redacted as ***REDACTED***. After the properties it lists any mockserver.* / MOCKSERVER_* key that is not a known property, so is ignored, with the property it was most likely meant to be (the key's name only, never its value). The same report is available at runtime as JSON from the authenticated GET /mockserver/config control-plane endpoint; add ?nonDefault=true to list only the properties not at their built-in default. See Checking The Configuration In Use. | — |
| -h, --help | Print usage and exit. | — |
Options for proxy
| Option | Required | Description |
|---|---|---|
| --to <target> | Yes | Forward all unmatched requests to this target. Accepts host:port or a full URL such as https://api.example.com (port 443 inferred) or http://api.example.com (port 80 inferred). A bare hostname with no port and no http(s):// scheme is rejected with an error. |
| -p, --port <port> | No | Port(s) to listen on. |
| -l, --log-level <level> | No | Log level (see above). |
| --validate-openapi <spec> | No | Validate forwarded/proxied traffic against the given OpenAPI spec (URL, file path, or inline payload). Violations are logged; combine with --validate-enforce to block non-conformant traffic. |
| --validate-enforce | No | When combined with --validate-openapi, block non-conformant traffic (400 for requests, 502 for responses). |
Options for openapi
| Argument / Option | Required | Description |
|---|---|---|
| <specUrlOrPath> | Yes (positional) | OpenAPI spec file path or URL. |
| -p, --port <port> | No | Port(s) to listen on. |
| -l, --log-level <level> | No | Log level (see above). |
Options for import
The import subcommand connects to an already-running MockServer and loads expectations into it from a JSON file. It does not start a server — start one first (e.g. mockserver run -p 1080), then import. The file may be a single expectation object or an array of expectations, the same format produced by the --persist flag, the dashboard export, or the active-expectations retrieve endpoint. Each expectation is created, or updated if its id matches an existing one. If the file is missing/invalid or the server is unreachable, a clear error is printed and the command exits with a non-zero status.
| Argument / Option | Required | Description |
|---|---|---|
| <file> | Yes (positional) | Path to a JSON file containing a single expectation or an array of expectations. |
| -p, --port <port> | Yes | Port of the running MockServer to load the expectations into. |
| -H, --host <host> | No | Host of the running MockServer. Default: localhost. |
Options for lint
The lint subcommand checks expectation files for mistakes that stop an expectation matching, such as an expectation that another one always matches first, a path without a leading /, or times of 0 (see Linting Expectations for every rule). It does not start or contact a server and never changes the files. Several files are checked together, in the order given, so an expectation in one file that hides one in another is found. Each finding names its file and its position in that file, counting from 0.
Lint is advisory, so the command exits with status 0 even when it finds warnings, unless you pass --strict. It exits with 1 when a file cannot be read or contains an invalid expectation.
| Argument / Option | Required | Description |
|---|---|---|
| <file>... | Yes (positional) | One or more JSON files, each containing a single expectation or an array of expectations. |
| --json | No | Print the report as JSON (the PUT /mockserver/lint format, with each finding's file) instead of text. |
| --strict | No | Also exit with status 1 when a warning is found, for example to fail a CI step. |
Options for demo
The demo subcommand starts MockServer pre-loaded with a small set of example expectations (GET /hello and GET /users/{id}) and prints a getting-started URL, the dashboard URL, and a sample curl command. It is the fastest way to see MockServer responding to requests without writing any expectations first. It accepts the same -p, --port (default 1080), -l, --log-level, and -D<key>=<value> options as run. After starting, try curl http://localhost:1080/hello.
Common examples
Start MockServer on port 1080:
java -jar mockserver-netty-no-dependencies-9.2.0.jar run -p 1080
Start MockServer on two ports:
java -jar mockserver-netty-no-dependencies-9.2.0.jar run -p 1080,1081
Start MockServer and forward unmatched requests to an upstream API:
java -jar mockserver-netty-no-dependencies-9.2.0.jar run -p 1080 --proxy-to api.example.com:8080
Start MockServer, load expectations from an OpenAPI spec, and persist any additional expectations set via the API:
java -jar mockserver-netty-no-dependencies-9.2.0.jar run -p 1080 \
--openapi ./petstore.yaml \
--persist ./expectations.json
Load expectations from a JSON file into a server that is already running on port 1080:
java -jar mockserver-netty-no-dependencies-9.2.0.jar import ./expectations.json -p 1080
Check expectation files before loading them, failing on any warning:
java -jar mockserver-netty-no-dependencies-9.2.0.jar lint --strict ./expectations.json ./more-expectations.json
Start a demo server pre-loaded with example expectations (then try curl http://localhost:1080/hello):
java -jar mockserver-netty-no-dependencies-9.2.0.jar demo -p 1080
Start MockServer initialized from a JSON file and live-reload expectations whenever that file changes, with no restart:
java -jar mockserver-netty-no-dependencies-9.2.0.jar run -p 1080 --init ./expectations.json --watch
Start MockServer as a plain forwarding proxy (shorthand form, explicit port):
java -jar mockserver-netty-no-dependencies-9.2.0.jar proxy --to api.example.com:8080 -p 1080
Start MockServer as a plain forwarding proxy using a scheme URL — port 443 is inferred from https://:
java -jar mockserver-netty-no-dependencies-9.2.0.jar proxy --to https://api.example.com -p 1080
The same with run --proxy-to:
java -jar mockserver-netty-no-dependencies-9.2.0.jar run -p 1080 --proxy-to https://api.example.com
Note: a bare hostname such as --proxy-to api.example.com (no port, no scheme) is rejected. Use api.example.com:8080 or a scheme URL such as https://api.example.com.
Contract-validating proxy
Combine --validate-openapi and --validate-enforce to turn MockServer into a contract-validating proxy that checks every request and response against an OpenAPI spec. This is useful in CI to catch API drift early, or in a staging environment to find clients that send non-conformant requests before they reach production.
Step 1 — Report-only mode: start without --validate-enforce. MockServer forwards all traffic unchanged and logs any violations as OPENAPI_REQUEST_VALIDATION_FAILED and OPENAPI_RESPONSE_VALIDATION_FAILED log events. Nothing is blocked, so existing clients are unaffected:
java -jar mockserver-netty-no-dependencies-9.2.0.jar proxy --to https://api.example.com -p 1080 \
--validate-openapi ./openapi-spec.yaml
Violations appear in the MockServer log (and in the dashboard Log Messages panel) as OPENAPI_REQUEST_VALIDATION_FAILED or OPENAPI_RESPONSE_VALIDATION_FAILED events with the path, method, violation details, and schema location.
Step 2 — Enforce mode: add --validate-enforce to reject non-conformant traffic. A request that violates the spec receives a 400 response; an upstream response that violates the spec is replaced with a 502:
java -jar mockserver-netty-no-dependencies-9.2.0.jar proxy --to https://api.example.com -p 1080 \
--validate-openapi ./openapi-spec.yaml \
--validate-enforce
Notes:
- The spec can be a local file path, a URL, or an inline JSON/YAML payload passed as a string.
- Streaming responses (chunked transfer-encoding, SSE) are validated in report-only mode even when --validate-enforce is set, because the response headers have already been sent to the client before the body is fully available.
- The same flags are available as configuration properties: mockserver.validateProxyOpenAPISpec and mockserver.validateProxyEnforce, so you can set them via environment variables or a properties file in Docker.
Start MockServer and pre-load expectations from a JSON file:
java -jar mockserver-netty-no-dependencies-9.2.0.jar run -p 1080 --init ./expectations.json
All interactions with the MockServer are logged, including setting up expectations, matching expectations, clearing expectations, and verifying requests. This log information can be particularly helpful when trying to debug why a test is failing or expectations are not being matched.
The --log-level flag can be used to set the log level, as shown in the options table above. It is also possible to further customise where loggers send log events by overriding the default logging configuration.
Legacy flags (still fully supported)
All command-line flags from earlier versions of MockServer continue to work. You do not need to update existing scripts or Docker commands.
| Legacy flag | New equivalent |
|---|---|
| -serverPort <port> | run -p <port> |
| -proxyRemotePort <port> | run --proxy-to host:<port> |
| -proxyRemoteHost <hostname> | run --proxy-to <hostname>:port |
| -logLevel <level> | run -l <level> |
For example, this legacy command continues to work unchanged:
java -jar mockserver-netty-no-dependencies-9.2.0.jar -serverPort 1080 -proxyRemotePort 80 -proxyRemoteHost www.mock-server.com -logLevel WARN
Configuration precedence
MockServer resolves configuration from multiple sources. The order of precedence, from highest to lowest, is:
- Command-line flag — e.g. -p 1080
- JVM system property — e.g. -Dmockserver.serverPort=1080
- Environment variable — long form MOCKSERVER_SERVER_PORT checked before short form SERVER_PORT
- mockserver.properties file — a mockserver.properties file on the classpath or working directory
This means that a flag passed on the command line always overrides the same setting from an environment variable or properties file. For a full list of configuration properties and their environment variable names, see the configuration properties page.
Running From Command Line - Using Maven Plugin
MockServer can be run directly from the command line and using the mockserver-maven-plugin as follow:
mvn -Dmockserver.serverPort=1080 -Dmockserver.logLevel=INFO org.mock-server:mockserver-maven-plugin:9.2.0:runForked
When run from the command line the Maven plugin can be configured with the following properties:
- mockserver.serverPort - The port the MockServer listens for incoming request. Port unification is used to support both HTTP and HTTPS and proxying on the same port (required: false)
- mockserver.logLevel - The logging level (required: false, default: INFO)
The runForked goal of the mockserver-maven-plugin will fork a JVM process containing the Netty based MockServer. To stop the forked JVM process use the stopForked goal, as follows:
mvn -Dmockserver.serverPort=1080 org.mock-server:mockserver-maven-plugin:9.2.0:stopForked
For more information on the mockserver-maven-plugin see the section on MockServer Maven Plugin
Web Archive (WAR)
To run as a WAR deployed on any JEE web server:
- download mockserver-war-9.2.0.war from Maven Central
- deploy mockserver-war-9.2.0.war to any JEE web server
WAR Context Path
The WAR context path is ignored from all request matching for path.
The MockServerClient constructor includes an argument for the context path that the WAR has been deployed to, as follows:
public MockServerClient(String host, int port, String contextPath)
NPM Module & MockServer Grunt Plugin
The node module can be used to start and stop MockServer as a node module or as a Grunt plugin.
You may install this plugin / node module with the following command:
npm install mockserver-node --save-dev
Node Module
To start or stop the MockServer from any Node.js code you need to import this module using require('mockserver-node') as follows:
var mockserver = require('mockserver-node');
Then you can use either the start_mockserver or stop_mockserver functions as follows:
var mockserver = require('mockserver-node');
mockserver.start_mockserver({
serverPort: 1080,
verbose: true,
trace: true
});
// do something
mockserver.stop_mockserver({
serverPort: 1080
});
You can customize the JVM arguments and set configuration options as follows
var mockserver = require('mockserver-node');
mockserver.start_mockserver({
serverPort: 1080,
jvmOptions: [
'-Dmockserver.enableCORSForAllResponses=true',
'-Dmockserver.corsAllowMethods="CONNECT, DELETE, GET, HEAD, OPTIONS, POST, PUT, PATCH, TRACE"',
'-Dmockserver.corsAllowHeaders="Allow, Content-Encoding, Content-Length, Content-Type, ETag, Expires, Last-Modified, Location, Server, Vary, Authorization"',
'-Dmockserver.corsAllowCredentials=true',
'-Dmockserver.corsMaxAgeInSeconds=300'
],
mockServerVersion: "9.2.0",
verbose: true
});
MockServer uses port unification to support HTTP, HTTPS, SOCKS, HTTP CONNECT, Port Forwarding Proxying on the same port. A client can then connect to the single port with both HTTP and HTTPS as the socket will automatically detected SSL traffic and decrypt it when required.
Requirements
start_mockserver runs MockServer with the java command, so Java 17 or later must be installed and its bin directory must be on the PATH of the Node.js process. JAVA_HOME is not used, and there is no option for the location of java.
When a start fails
start_mockserver returns a promise. It is rejected with an Error, and the same message is printed to stderr, when:
- there is no java on the PATH (error.code is ENOENT), or the one found cannot be run (EACCES): the message says where java was looked for
- java exits with a failing status, or is ended by a signal, before MockServer is ready, for example when jvmOptions holds an option it does not accept: the start fails at once and the message ends with the last lines the process printed
- MockServer does not become ready in the time startupRetries allows
A failed start never ends the calling process, and leaves it free to carry on or to exit (unless a JVM was left waiting for a debugger, see javaDebugPort). Handle the rejection to fail your own script, and call stop_mockserver afterwards if you wish: it resolves when nothing is running.
mockserver.start_mockserver({serverPort: 1080}).then(function () {
// MockServer is ready
}, function (error) {
process.exitCode = 1;
});
TypeScript
TypeScript typings for mockserver-node are published in the npm package. They use Node's own types, so your project needs @types/node installed. Both import mockserver = require('mockserver-node') and import * as mockserver from 'mockserver-node' work with or without esModuleInterop; a default import (import mockserver from 'mockserver-node') needs esModuleInterop turned on and is otherwise a compile error.
Note: the package declares an exports map, naming index, downloadJar, downloadBinary and package.json. A deep import of a path it doesn't name — for example mockserver-node/tasks/mockServer.js — now fails with ERR_PACKAGE_PATH_NOT_EXPORTED, where previously any file inside the package could be required.
Grunt Plugin
If you haven't used Grunt before, be sure to check out the Getting Started guide, as it explains how to create a Gruntfile as well as install and use Grunt plugins.
In your project's Gruntfile, add a section named start_mockserver and stop_mockserver to the data object passed into grunt.initConfig().
The following example starts a MockServer on port 1080 (with a matching task to stop it again).
grunt.initConfig({
start_mockserver: {
start: {
options: {
serverPort: 1080,
trace: true
}
}
},
stop_mockserver: {
stop: {
options: {
serverPort: 1080
}
}
}
});
grunt.loadNpmTasks('mockserver-node');
Request Log
The request log will only be captured in MockServer if the log level is INFO (or more verbose, i.e. DEBUG or TRACE) therefore to capture the request log and use the /retrieve endpoint ensure either the option trace: true or the command line switch --verbose is set.Grunt Plugin & NPM Module Options
options.serverPort
Type: Integer Default: undefined
The HTTP, HTTPS, SOCKS and HTTP CONNECT port(s) for both mocking and proxying requests. Port unification is used to support all protocols for proxying and mocking on the same port(s). Supports comma separated list for binding to multiple ports.
options.proxyRemotePort
Type: Integer Default: undefined
Optionally enables port forwarding mode. When specified all requests received will be forwarded to the specified port, unless they match an expectation.
options.proxyRemoteHost
Type: String Default: undefined
Specified the host to forward all proxy requests to when port forwarding mode has been enabled using the proxyRemotePort option. This setting is ignored unless proxyRemotePort has been specified. If no value is provided for proxyRemoteHost when proxyRemotePort has been specified, proxyRemoteHost will default to "localhost".
options.artifactoryHost
Type: String Default: oss.sonatype.org
This value specifies the name of the artifact repository host.
options.artifactoryPath
Type: String Default: /content/repositories/releases/org/mock-server/mockserver-netty/
This value specifies the path to the artifactory leading to the mockserver-netty jar with dependencies.
options.mockServerVersion
Type: String Default: 9.2.0
This value specifies the artifact version of MockServer to download.
Note: It is also possible to specify a SNAPSHOT version to get the latest unreleased changes.
Note: The jar is downloaded once and kept inside the installed mockserver-node module itself (i.e. node_modules/mockserver-node), not in the directory you run from, so it is re-used no matter where you start MockServer from and is removed when the module is uninstalled. Jars for different versions are kept side by side, so switching between versions does not re-download them; a SNAPSHOT version is always re-fetched, since its contents change without its version changing. If that directory is not writable — for example a global install owned by root but used by another user, or a read-only container layer — the jar is downloaded into the directory you run from instead.
Note: A download that receives nothing at all for 60 seconds is abandoned with an error rather than waiting indefinitely. A slow download is never interrupted, only a silent one, but if you are behind a proxy that pauses for longer than this before it starts sending, set the MOCKSERVER_DOWNLOAD_IDLE_TIMEOUT_MILLIS environment variable to a larger number of milliseconds.
options.verbose
Type: Boolean Default: false
This value indicates whether the MockServer logs should be written to the console. In addition to logging additional output from the grunt task this options also sets the logging level of the MockServer to INFO. At INFO level all interactions with the MockServer including setting up expectations, matching expectations, clearing expectations and verifying requests are written to the log.
Note: It is also possible to use the --verbose command line switch to enabled verbose level logging from the command line.
options.trace
Type: Boolean Default: false
This value sets the logging level of the MockServer to TRACE. At TRACE level (in addition to INFO level information) all matcher results, including when specific matchers fail (such as HeaderMatcher) are written to the log.
options.javaDebugPort
Type: Integer Default: undefined
This value indicates whether Java debugging should be enabled and if so which port the debugger should listen on. When this options is provided the following additional option is passed to the JVM:
"-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=" + javaDebugPort
Note: suspend=y is used so the MockServer will pause until the debugger is attached. The grunt task will wait 50 seconds for the debugger to be attached before it exits with a failure status. The paused JVM is left running when that happens, so a debugger can still be attached to it; stop it yourself when you are done.
options.runForked
Type: Boolean Default: false
If the calling process meets an uncaught exception, the MockServer it launched is ended so that it is not left running once the process has gone. The exception itself is left alone: Node.js reports it and exits with a failing status, or your own uncaughtException handler deals with it. The server is ended even when your own handler, or a test runner, deals with the exception and the process carries on. Only the java process the launcher started is signalled: if the java on your PATH is a wrapper script that does not exec the JVM, the JVM is left running. Set this option to true to leave MockServer running instead.
options.jvmOptions
Type: String Default: undefined
This value allows any system properties to be passed to the JVM that runs MockServer, for example:
start_mockserver: {
options: {
serverPort: 1080,
jvmOptions: "-Dmockserver.enableCORSForAllResponses=true"
}
}
options.startupRetries
Type: Integer Default: if javaDebugPort is not set 110, but if javaDebugPort is set 500
This value indicates the how many times we will call the check to confirm if the mock server started up correctly. It will default to 110 which will take about 11 seconds to complete, this is normally long enough for the server to startup. The server can take longer to start up if Java debugging is enabled so this will default to 500. The default will, in some cases, need to be overridden as the JVM may take longer to start up on some architectures, e.g. Mac seems to take a little longer.
The checks are 100 milliseconds apart, and each one waits up to 2 seconds for an answer. A check that gets no answer in that time uses up 20 further retries, so a server that accepts connections and never answers makes the start give up after about startupRetries × 100 milliseconds plus 2 seconds, much as one that refuses connections does. When the start gives up it fails with a message saying so and stops the JVM it launched, unless javaDebugPort is set.
Run via a Client Library (Binary Bundle)
Most MockServer client libraries can download and launch a local MockServer instance automatically — no Java installation and no Docker required. Each client downloads a self-contained platform bundle that includes a trimmed JVM runtime, the MockServer server, and a launcher script. The bundle is fetched from the GitHub Release, verified against its published SHA-256 checksum, and cached per-user so subsequent launches are instant.
Supported clients
| Client | Language | Launch API |
|---|---|---|
| mockserver-node | Node.js | npx -p mockserver-node mockserver run -p 1080 or ensureBinary(version) / runBinary(version, args) |
| mockserver-client | Python | start(port=1080) / ensure_binary() |
| mockserver-client | Ruby | MockServer::BinaryLauncher.start(port: 1080) / .ensure_launcher |
| mockserver-client-go | Go | mockserver.StartServer(1080, "", nil) / mockserver.EnsureBinary(version, nil) |
| MockServerClient | .NET | MockServerBinaryLauncher.Start(port: 1080) / .EnsureBinary() |
| mockserver-client | Rust | launcher::start(1080) / launcher::ensure_launcher() |
| PHP | PHP | Not supported — start MockServer via Docker, the executable JAR, or another client’s launcher. |
Binary bundle format
Each bundle is named mockserver-<version>-<os>-<arch>.tar.gz (or .zip on Windows), where:
- os:
linux,darwin, orwindows - arch:
x86_64oraarch64
The bundle is a jlink-assembled custom JVM image — it runs on any machine with a compatible OS and CPU, with no external Java dependency.
Environment variables
All client launchers honour the same set of environment variables for customisation:
| Variable | Purpose |
|---|---|
MOCKSERVER_BINARY_BASE_URL | Override the download base URL. Use this to point at a corporate mirror or an air-gapped artifact store instead of GitHub. |
MOCKSERVER_BINARY_CACHE | Override the per-user cache directory. Default: ~/.cache/mockserver/binaries (Unix) or %LOCALAPPDATA%\mockserver\binaries (Windows). |
MOCKSERVER_SKIP_BINARY_DOWNLOAD | Set to any value to prevent the launcher from downloading. If no cached binary exists, the launcher fails immediately. Useful in CI with a pre-seeded cache. |
Version
By default, each client downloads the MockServer version that matches its own package version. You can override this by passing an explicit version to the start/ensure function.
Docker Container
The typical sequence for running the MockServer docker image is as follows: In addition it is possible to customise how the container is run.Install Docker
To install Docker see the installation instructions.
Pull MockServer Image
To pull the MockServer Docker image use the pull command, as follows:
docker pull mockserver/mockserver
This is not strictly necessary as the image will be automatically pulled if it does not exist when the run command is used. However, using the pull command will ensure the latest version of the image is downloaded.
Docker Hub limits how many images anonymous users can pull, which often hits CI builds that share an IP address. The same images are also published to two other registries, and pulls from them do not count against the Docker Hub limit:
- GitHub Container Registry (GHCR), a good choice for CI and especially for GitHub Actions:
docker pull ghcr.io/mock-server/mockserver:9.2.0 - AWS ECR Public, which gives lower latency for AWS-based CI/CD:
docker pull public.ecr.aws/t2x9c0i6/mockserver:9.2.0
GHCR and ECR Public carry the same tags as Docker Hub (for example latest, 9.2.0, mockserver-9.2.0, 9.2.0-graaljs and clustered-9.2.0) and each tag has the same image digest on every registry, so switching registry changes nothing but where the image comes from. The Kubernetes admission webhook image is at ghcr.io/mock-server/mockserver-webhook and public.ecr.aws/t2x9c0i6/mockserver-webhook. On GHCR:
- releases from 7.1.0 onwards are available; earlier versions are not
- the experimental -aot tags and the snapshot tags are not published to GHCR; pull them from Docker Hub or ECR Public
Verifying Image Signatures
Release images are signed with Sigstore cosign using the MockServer public key, published at https://www.mock-server.com/mockserver-cosign.pub (the same key signs the Helm chart). To verify an image before running it:
cosign verify --key https://www.mock-server.com/mockserver-cosign.pub mockserver/mockserver:9.2.0
A successful verification prints the signed payload and exits with status 0. The same key verifies the -graaljs, -http3 and clustered- image variants and the GHCR and ECR Public copies, for example cosign verify --key https://www.mock-server.com/mockserver-cosign.pub ghcr.io/mock-server/mockserver:9.2.0. Image versions before 9.2.0 predate signing.
Run MockServer Container
Then to run MockServer as a Docker container run the following command:
docker run -d --rm -P mockserver/mockserver
The -P switch in this command tells Docker to map all ports exported by the MockServer container to dynamically allocated ports on the host machine.
To view information about the MockServer container, including which dynamic ports have been used run the following command:
docker ps
No Interactive Shell
MockServer uses distroless as its based container for both size and security and so does not contain an interactive shell. This minimises the likelihood of vulnerabilities and to reduces the attack surface by ensuring only the JVM and MockServer code is inside the container.
Configure Port Mapping
This MockServer docker container exports the following port:
- serverPort 1080
To specify which ports (on the host machine) should be mapped to the MockServer docker container use the -p <host port>:<container port> option, as follows:
docker run -d --rm -p <serverPort>:1080 mockserver/mockserver
For example:
docker run -d --rm -p 1080:1080 mockserver/mockserver
HTTP/3 (experimental)
The standard image serves HTTP/3: set MOCKSERVER_HTTP3_PORT and publish that port as UDP:
docker run -d --rm -p 1080:1080 -p 8443:8443/udp -e MOCKSERVER_HTTP3_PORT=8443 mockserver/mockserver:9.2.0
This also works with a read-only root filesystem (--read-only). The -graaljs, clustered- and -aot images also serve HTTP/3, but only if the container can write to /tmp. If MockServer cannot start HTTP/3 on that port — for example with --network host when another process already holds the UDP port — it exits with a non-zero status, printing one line that names the port and the cause, rather than running without HTTP/3.
Deprecated: the -http3 tags (9.2.0-http3, latest-http3, snapshot-http3) used to be the only images that could serve HTTP/3. They are now the same as the standard image and are kept for one more release only, so switch to the standard tag.
Environment Variables
It is possible configure MockServer behaviour through environment variables, this includes port mappings, log level and lots of other properties for example:
docker run -d --rm -p 1090:1090 --env MOCKSERVER_LOG_LEVEL=TRACE --env MOCKSERVER_SERVER_PORT=1090 mockserver/mockserver
JVM Heap Size
The Docker image caps the JVM heap at 45% of the container's memory limit (it sets -XX:MaxRAMPercentage=45.0). Always run the container with an explicit memory limit — without one the JVM sizes its heap off the host's total memory and can be OOM-killed under load. 512 MiB (--memory=512m) is the smallest supported limit (768 MiB for the -clustered image when clustering is switched on — see clustering); use --memory=1g or more for larger bodies or many expectations, and --memory=2g for sustained production load. The rest of the limit is not spare: the Java process needs memory the heap setting does not count — class metadata and compiled code, thread stacks, garbage-collector bookkeeping, the off-heap network buffers Netty uses for bodies, and the kernel's per-connection socket buffers — and most of it does not shrink when the heap does, so it is a bigger share of a small container. To set an explicit heap (for high-throughput use cases or large response bodies), pass -Xmx via JAVA_TOOL_OPTIONS, which disables the percentage cap — keep the heap you pin at or under 45% of the limit on a small container. If a container is killed with exit code 137 and OOMKilled: true (no Java stack trace — the kernel killed it), the fix is a larger --memory or a smaller heap, not a bigger one. See the memory tuning guide for the sizing arithmetic:
docker run -d --rm -p 1080:1080 --memory=1g --env JAVA_TOOL_OPTIONS="-XX:+UseZGC -Xmx512m" mockserver/mockserver
The images use the Z garbage collector (ZGC) by default (the -aot fast-start image is the exception and stays on the default collector). ZGC collects concurrently with request handling, which markedly lowers response tail latency (p95/p99) under load at the same throughput — you get this without configuring anything. It uses a little more memory than the previous default — under load it grows to its full heap and keeps it while the load lasts, in memory the kernel cannot reclaim — which the images' heap cap allows for, so it runs under sustained load within a --memory=512m limit. The collector is set through the JAVA_TOOL_OPTIONS environment variable, so if you set JAVA_TOOL_OPTIONS yourself it replaces the default — include -XX:+UseZGC when you set it for another reason (for example JAVA_TOOL_OPTIONS="-XX:+UseZGC -Xmx512m"), or you will silently fall back to the JDK's default collector. To switch back to the G1 collector, set JAVA_TOOL_OPTIONS=-XX:+UseG1GC:
docker run -d --rm -p 1080:1080 --memory=1g --env JAVA_TOOL_OPTIONS="-XX:+UseG1GC" mockserver/mockserver
How much memory does MockServer actually use? A freshly started, idle MockServer settles at roughly 120 MB of container memory, and this barely changes between --memory=512m and --memory=1g. Under load it grows well beyond that: at --memory=512m on one CPU core, serving a small mocked response at 16,000 requests a second over about 4,500 open connections, the container peaked at about 79–83% of the limit (a 232 MB heap plus about 150 MB of other JVM memory and about 20 MB of kernel socket buffers). So 512 MB suits small request and response bodies (up to a few kilobytes) with a modest number of expectations; at the default INFO log level it is not enough once individual bodies reach roughly 16 KB (measured with a single expectation — a best case) — see the memory tuning guide for body-size guidance and the levers available. --memory=256m is not supported with the default settings: it starts and idles (around 95 MB), but under load the container is killed. If you must run in 256 MB, set a small explicit heap (for example JAVA_TOOL_OPTIONS="-XX:+UseZGC -Xmx96m") and keep traffic and body sizes light — even then the container runs close to its limit (about 95% at 8,000 requests a second in our tests). Memory in use grows with your expectations, request log, response sizes and number of open connections, and rises on hosts with more CPU cores (MockServer sizes its network thread pools to the available cores).
If MockServer becomes slow or unresponsive under sustained load, see the troubleshooting guide for recommended memory and logging configuration.
Modifying Default Command
The MockServer container entrypoint calls org.mockserver.cli.Main directly with CMD [] (no default arguments). The SERVER_PORT environment variable defaults to 1080 in the Dockerfile. Command line options can be explicitly provided, for example:
docker run --rm --name mockserver -p 1080:1090 mockserver/mockserver -logLevel INFO -serverPort 1090 -proxyRemotePort 443 -proxyRemoteHost mock-server.com
The application code is split across two jars in the image, /mockserver.jar (MockServer's own classes) and /mockserver-deps.jar (its dependencies), instead of the single mockserver-netty-jar-with-dependencies.jar used before 9.0.0. /mockserver.jar's manifest carries a Class-Path: mockserver-deps.jar entry, so java -jar /mockserver.jar still runs correctly on its own — it just starts more slowly, because it bypasses the image's AppCDS shared archive (-XX:SharedArchiveFile=/mockserver.jsa, built against the full -cp /mockserver.jar:/mockserver-deps.jar:/libs/*:/extensions/* below). java -jar /mockserver-deps.jar does not run; it has no Main-Class.
If you override the container's entrypoint rather than only its command — for example a Dockerfile ENTRYPOINT, a Compose entrypoint: list, or a Kubernetes command: list — base your override on the exact ENTRYPOINT the image you run already has, rather than retyping one by hand: the Java binary's path, and whether -XX:SharedArchiveFile/-XX:AOTCache is present, differ between the standard, -clustered, -graaljs and -aot images, and a hand-written override that drops -Dmockserver.propertyFile=/config/mockserver.properties silently stops /config properties (see "Detailed MockServer Configuration" below) from loading. Check the real entrypoint first:
docker inspect --format '{{json .Config.Entrypoint}}' mockserver/mockserver:9.2.0
For the standard image, that is the following exec-form array — the same JSON-array shape a Dockerfile ENTRYPOINT, a Compose entrypoint:, or a Kubernetes command: list each expect, one argument per element (quoting /libs/* and /extensions/* inside the single -cp element, as shown, avoids the shell expanding them before Java sees them):
[
"/usr/lib/jvm/temurin25-trimmed/bin/java",
"-Dfile.encoding=UTF-8",
"--enable-native-access=ALL-UNNAMED",
"-XX:MaxRAMPercentage=45.0",
"-XX:SharedArchiveFile=/mockserver.jsa",
"-cp", "/mockserver.jar:/mockserver-deps.jar:/libs/*:/extensions/*",
"-Dmockserver.propertyFile=/config/mockserver.properties",
"org.mockserver.cli.Main"
]
Copy it verbatim and change only what you need to — for example appending -serverPort 1080 as an extra element, or (more simply) leaving the entrypoint untouched and passing -serverPort 1080 as the CMD/command instead, which needs no entrypoint override at all.
Adding Extensions
Every MockServer image loads any JAR in /extensions, so you can add your own extensions without building a new image. Mount the folder read-only and name the extension classes:
docker run -v $(pwd)/ext:/extensions:ro -e MOCKSERVER_EXTENSIONS=com.example.AuditExtension -p 1080:1080 mockserver/mockserver
When nothing is mounted at /extensions, the image starts exactly as before.
Detailed MockServer Configuration
To support configuring MockServer a mockserver.properties will be loaded from /config directory if it exists.
A mockserver.properties configuration file and other related configuration files such as json expectation initialization, or custom TLS CA, X.509 Certificate or Private Key should be mapping into the /config directory.
For example to add configuration files in the current directory, such as mockserver.properties, map $(pwd) into /config, as follows:docker run -v $(pwd):/config -p 1080:1080 mockserver/mockserver -serverPort 1080
See MockServer Configuration for details of all configuration options.
As the Docker image is based from gcr.io/distroless/java-base-debian12:nonroot and the user nonroot is used, we need to configure permissions in order to allow the user in the container read/write files in mounted volumes:chmod o+r $(pwd)/mockserver.properties
Extending MockServer Classpath
To use class callbacks or an expectation initializer class the classpath for MockServer must include the specified classes.
To support adding classes to the classpath any jar files contained in the /libs directory will be added into MockServer classpath.
For example to add all jar files in the current directory, map $(pwd) into /libs, as follows:docker run -v $(pwd):/libs -p 1080:1080 mockserver/mockserver -serverPort 1080
Docker Health Checks
MockServer Docker images include a built-in HEALTHCHECK instruction that verifies the server is serving requests. Since the images are based on distroless containers (no shell, no curl), the image ships its own tiny health check program, /mockserver-healthcheck, which calls the PUT /mockserver/status endpoint over plain HTTP on localhost. It is a small native binary (about 2 MB on disk and about 4 MB of memory for the moment it runs) rather than a second Java process, so running it every 10 seconds does not eat into the container's memory limit.
The built-in health check works automatically with no configuration required:
HEALTHCHECK --interval=10s --timeout=5s --start-period=120s --retries=3
CMD ["/mockserver-healthcheck"]
The health check reads the MOCKSERVER_SERVER_PORT or SERVER_PORT environment variable to determine the port (the first port if several are listed; defaults to 1080). It reports healthy only when the status endpoint answers 200 within 3 seconds. If you set the port another way (for example -serverPort on the command line or mockserver.serverPort in a properties file), also set SERVER_PORT to the same value so the health check probes the right port. Docker reports the container as healthy once MockServer is ready to accept requests.
Using with Docker Compose
The built-in health check integrates with Docker Compose depends_on conditions:
services:
mockserver:
image: mockserver/mockserver:9.2.0
ports:
- "1080:1080"
app:
image: my-app:latest
depends_on:
mockserver:
condition: service_healthy
To override or disable the built-in health check, use the healthcheck key in your Compose file.
Kubernetes Liveness and Readiness Probes
In Kubernetes, use httpGet probes with the configurable liveness endpoint:
containers:
- name: mockserver
image: mockserver/mockserver:9.2.0
ports:
- containerPort: 1080
env:
- name: MOCKSERVER_LIVENESS_HTTP_GET_PATH
value: "/liveness/probe"
livenessProbe:
httpGet:
path: /liveness/probe
port: 1080
initialDelaySeconds: 10
periodSeconds: 5
readinessProbe:
httpGet:
path: /mockserver/ready
port: 1080
initialDelaySeconds: 5
periodSeconds: 5
Important: the MOCKSERVER_LIVENESS_HTTP_GET_PATH environment variable must be set (as shown above) for the livenessProbe httpGet to work. This path is empty (disabled) by default — without the env var, the liveness probe will return a 404. If you copy only the livenessProbe block without the env section, it will fail. The readinessProbe uses /mockserver/ready, a fixed built-in endpoint that needs no env var: it returns 503 until expectation initializers and OpenAPI seeding complete, then 200, so traffic is not routed to the pod before the seeded mocks exist.
The MockServer Helm chart configures these probes automatically.
Amazon ECS Health Check
For ECS task definitions, the built-in HEALTHCHECK in the Docker image is used automatically. Alternatively, configure an explicit health check — call the bundled probe directly, because the image has no shell or curl for a CMD-SHELL command to use:
{
"containerDefinitions": [{
"name": "mockserver",
"image": "mockserver/mockserver:9.2.0",
"healthCheck": {
"command": ["CMD", "/mockserver-healthcheck"],
"interval": 10,
"timeout": 5,
"retries": 3,
"startPeriod": 120
}
}]
}
Note: The ECS CMD-SHELL health check runs on the host, not inside the distroless container, so curl is available.
For more information on the liveness endpoint configuration, see liveness configuration properties.
A selection of commonly used environment variables is shown in the Docker Compose examples below. MOCKSERVER_MAX_LLM_CONVERSATION_BODY_SIZE controls the maximum request body size that conversation-aware LLM matchers will parse (default 1 MiB; valid range 16 KiB–64 MiB). See Performance Configuration for details.
Docker Compose
MockServer can be run using docker compose by adding the container as a service.
For ready-to-run, one-command starting points — mock from an OpenAPI spec, a record/replay proxy, a contract-validating proxy, or a chaos proxy — see the Docker Compose recipes.
The MockServer container uses an entrypoint, so it is possible to configure the MockServer by specifying the command line flags using by specifying the command, as follows:
services:
mockServer:
image: mockserver/mockserver:9.2.0
command: -logLevel DEBUG -serverPort 1090 -proxyRemotePort 80 -proxyRemoteHost www.mock-server.com
ports:
- 1080:1090
It is also possible to configure the MockServer by setting environment variables, as follows:
services:
mockServer:
image: mockserver/mockserver:9.2.0
ports:
- 1080:1090
environment:
MOCKSERVER_MAX_EXPECTATIONS: 100
MOCKSERVER_MAX_HEADER_SIZE: 8192
MOCKSERVER_MAX_LLM_CONVERSATION_BODY_SIZE: 1048576
It is also possible to configure the MockServer by mounting a volume containing a properties file or JSON expectation initializer, as follows:
services:
mockServer:
image: mockserver/mockserver:9.2.0
ports:
- 1080:1080
environment:
MOCKSERVER_PROPERTY_FILE: /config/mockserver.properties
MOCKSERVER_INITIALIZATION_JSON_PATH: /config/initializerJson.json
volumes:
- type: bind
source: .
target: /config
To initialise MockServer using an OpenAPI specification file, mount the file and set the MOCKSERVER_INITIALIZATION_OPENAPI_PATH environment variable:
services:
mockServer:
image: mockserver/mockserver:9.2.0
ports:
- 1080:1080
environment:
MOCKSERVER_INITIALIZATION_OPENAPI_PATH: /config/petstore.yaml
volumes:
- type: bind
source: .
target: /config
One-command docker-compose recipes
The repository ships task-oriented docker-compose.yml recipes — each is a self-contained directory you can docker compose up with no extra configuration. Clone the repo (or copy a recipe), cd into it, and run:
cd examples/docker-compose/mock-from-openapi
docker compose up
| Recipe | What it does |
|---|---|
| mock-from-openapi | Serve mocks generated automatically from a mounted OpenAPI / Swagger spec. |
| record-replay-proxy | Proxy to an upstream and record traffic to a replayable expectations file. |
| validation-proxy | Proxy to an upstream and validate requests / responses against an OpenAPI spec. |
| chaos-proxy | Proxy to an upstream while injecting latency and intermittent errors. |
More configuration permutations (custom ports, mounted properties files, mTLS, persisted expectations) live in the docker-compose examples folder.
Deploying MockServer Helm Chart
There are four ways to deploy the MockServer helm chart:
- via OCI registry (recommended, Helm 3.8+)
- via chart repository
- via package
- via local source
You can also discover MockServer Helm charts on Artifact Hub, the CNCF registry for Kubernetes packages. The official chart is published to the GitHub Container Registry (OCI) as described below; the OCI install command is the recommended way to install it.
 Deploy Via OCI Registry
The chart is published to the GitHub Container Registry as an OCI artifact. No helm repo add is needed — helm install can pull straight from oci://:
helm upgrade --install --kube-context <your kube context> --namespace mockserver --create-namespace --version 9.2.0 mockserver oci://ghcr.io/mock-server/charts/mockserver
To inspect chart metadata for a specific version without installing:
helm show chart oci://ghcr.io/mock-server/charts/mockserver --version 9.2.0
To browse the full list of published versions, open the package page on GHCR: github.com/orgs/mock-server/packages/container/package/charts%2Fmockserver
The OCI artifact is public — no authentication is required for helm pull or helm install. Every released chart version (5.3.0 onward) is available at the same path.
To mirror the chart into a private OCI registry (Harbor, Artifactory, ECR, GAR, ACR, etc.):
helm pull oci://ghcr.io/mock-server/charts/mockserver --version 9.2.0
helm push mockserver-9.2.0.tgz oci://<your-private-registry>/<namespace>
 
Verifying The Chart Signature
Recent chart releases are signed with Sigstore cosign. You can verify a chart against the published MockServer public key before installing it:
cosign verify --key https://www.mock-server.com/mockserver-cosign.pub ghcr.io/mock-server/charts/mockserver:9.2.0
A successful verification prints the signed payload and exits with status 0. Older chart versions predate signing, so verification will report no matching signatures for them.
 Deploy Via Chart Repository
The legacy HTTP-based Helm repository remains available at www.mock-server.com. Chart versions 5.3.0–5.14.0 (2018–2022) are no longer served from it; 5.15.0 (the last Java 11-compatible release) and 6.0.0 onwards remain. Any removed version is still installable from the OCI registry (oci://ghcr.io/mock-server/charts/mockserver).
helm repo add mockserver https://www.mock-server.com
helm repo update
Then the helm chart can be installed as follows:
helm upgrade --install --kube-context <your kube context> --namespace mockserver --create-namespace --version 9.2.0 mockserver mockserver/mockserver
If using get the following error:
Error: failed to download "mockserver/mockserver" at version "9.2.0"
Then update local cache of helm charts:
helm repo update
 
Deploy Via Package
To run MockServer in Kubernetes the easiest way is to use the existing MockServer helm chart.
This is available by using www.mock-server.com as a chart repo, with the following command:
helm upgrade --install --namespace mockserver mockserver http://www.mock-server.com/mockserver-9.2.0.tgz
 
Deploy Via Local Source
If you have helm chart source folder (i.e. you have the repository cloned):
helm upgrade --install --namespace mockserver mockserver helm/mockserver
The commands above will install MockServer into a namespace called mockserver with default configuration (as per the embedded values.yaml).
MockServer will then be available on domain name mockserver.mockserver.svc.cluster.local, as long as the namespace you are calling from isn't prevented (by network policy) to call the mockserver namespace.
 Chart Deployment Status
To view the logs:
kubectl -n mockserver logs --tail=100 -l app=mockserver,release=mockserver
or open the UI
To wait until the deployment is complete run:
kubectl -n mockserver rollout status deployments mockserver
To check the status of the deployment without waiting, run the following command and confirm the mockserver has the Running status:
kubectl -n mockserver get po -l release=mockserver
To undeploy the helm chart:
helm delete -n mockserver mockserver
 
Basic MockServer Configuration
Modify the arguments used to start the docker container by setting values explicitly using --set, as follows:
helm upgrade --install --namespace mockserver --set app.serverPort=1080 --set app.logLevel=INFO mockserver http://www.mock-server.com/mockserver-9.2.0.tgz
The following values are supported:
- app.serverPort (default: 1080)
- app.logLevel (default: INFO)
- app.proxyRemoteHost (no default)
- app.proxyRemotePort (no default)
- app.jvmOptions (no default)
- image.snapshot (default: false) - set true to use latest snapshot version
- image.variant (default: empty) - set graaljs for JavaScript templates. The default image serves HTTP/3: set mockserver.http3Port in your properties and expose that port as UDP on your Service; a pod that cannot start HTTP/3 on that port exits and restarts instead of running without it, and its log names the port and the cause. http3 is deprecated: it is now the same as the default image and is kept for one more release only
- podLabels (default: {}) - additional labels to add to the MockServer pods
- imagePullSecrets (default: []) - list of image pull secrets for private registries
- app.terminationGracePeriodSeconds (default: 45) - seconds Kubernetes waits after SIGTERM before SIGKILL; must comfortably exceed app.preStopSleepSeconds plus the server's own in-flight drain (mockserver.stopDrainMillis, default 15s)
- app.preStopSleepSeconds (default: 0, disabled) - seconds to pause before MockServer is told to shut down, so Service endpoint removal has time to propagate before the pod actually stops serving. Uses the native lifecycle.preStop.sleep action, because the distroless image has no shell for an exec hook. Requires Kubernetes 1.30+ (the PodLifecycleSleepAction feature is Beta and on by default from 1.30; Alpha and off by default in 1.29) — confirm your cluster version before enabling it
The chart's readiness probe polls /mockserver/ready every second from pod start (periodSeconds: 1, failureThreshold: 20), rather than the slower 2-second interval used before, so a pod that is ready quickly joins Service endpoints sooner.
For example configure a proxyRemoteHost and proxyRemotePort, as follows:
helm upgrade --install --namespace mockserver --set app.serverPort=1080 --set app.proxyRemoteHost=www.mock-server.com --set app.proxyRemotePort=443 mockserver http://www.mock-server.com/mockserver-9.2.0.tgz
Double check the correct arguments have been passed to the pod, as follows:
kubectl -n mockserver logs -l app=mockserver,release=mockserver
 
Detailed MockServer Configuration
There are two ways to provide MockServer configuration (properties file, expectation initialization JSON, TLS certificates, etc.):
- Inline configuration (recommended) — provide configuration directly in values.yaml
- External ConfigMap — create a ConfigMap separately (manually, via CI, or using the example mockserver-config chart)
Both approaches mount configuration into the container at /config. See MockServer Configuration for details of all configuration options.
 Option 1: Inline Configuration (single chart install)
Set app.config.enabled=true and provide configuration content directly in values. This creates a ConfigMap as part of the main chart — no separate chart or manual ConfigMap creation is needed.
Using --set-string (commas in JSON must be escaped as \,):
helm upgrade --install --namespace mockserver \
--set app.config.enabled=true \
--set app.config.properties="mockserver.initializationJsonPath=/config/initializerJson.json" \
--set-string 'app.config.initializerJson=[{"httpRequest":{"path":"/example"}\,"httpResponse":{"body":"response"}}]' \
mockserver helm/mockserver
Note: Helm's --set flag treats commas as key/value separators, which corrupts JSON values. Use --set-string with escaped commas (\,) for simple cases, or a values.yaml file (recommended) for anything non-trivial.
Or using a values.yaml file (recommended for complex configuration):
app:
config:
enabled: true
properties: |
mockserver.initializationJsonPath=/config/initializerJson.json
mockserver.enableCORSForAPI=true
mockserver.enableCORSForAllResponses=true
initializerJson: |
[
{
"httpRequest": { "path": "/example" },
"httpResponse": { "body": "some response" }
}
]
helm upgrade --install --namespace mockserver -f values.yaml mockserver helm/mockserver
When using inline configuration, pods are automatically restarted on helm upgrade whenever the configuration content changes. This ensures MockServer always runs with the latest configuration.
The following inline config values are supported:
- app.config.enabled (default: false) - set true to create a ConfigMap from inline values
- app.config.properties (default: "") - content of mockserver.properties
- app.config.initializerJson (default: "") - content of initializerJson.json
- app.config.extraFiles (default: {}) - map of additional filenames to content (e.g. TLS certificates)
Option 2: External ConfigMap
If a ConfigMap called mockserver-config (or a custom name) exists in the same namespace, it will be mounted into the MockServer container under the mountPath /config.
This ConfigMap can be used to configure MockServer by containing a mockserver.properties file and other related configuration files such as:
The mockserver.properties file should load these additional files from the directory /config which is the mountPath for the ConfigMap.
The mapping of the configuration ConfigMap can be configured as follows:
- app.mountedConfigMapName (default: mockserver-config) - name of the configuration ConfigMap (in the same namespace) to mount
- app.propertiesFileName (default: mockserver.properties) - name of the property file in the ConfigMap
helm upgrade --install --namespace mockserver --set app.mountedConfigMapName=other-mockserver-config --set app.propertiesFileName=other-mockserver.properties mockserver helm/mockserver
An example of a helm chart to create this ConfigMap is helm/mockserver-config
 
Extending MockServer Classpath
To use class callbacks or an expectation initializer class the classpath for MockServer must include the specified classes.
To support adding classes to the classpath if a configmap called mockserver-config exists in the same namespace any jar files contained in this configmap will be added into MockServer classpath.
The mapping of the libs configmap can be configured as follows:
- app.mountedLibsConfigMapName (default: mockserver-config) - name of the libs configmap (in the same namespace) to mount
helm upgrade --install --namespace mockserver --set app.mountedLibsConfigMapName=mockserver-libs mockserver helm/mockserver
Extensions
Extensions are your own Java classes that MockServer loads when it starts. Put the extension JARs in any Kubernetes volume, such as a ConfigMap, a Secret or a PersistentVolumeClaim, and name the classes; the chart mounts the volume read-only at /extensions, which every MockServer image loads JARs from:
- extensions.classes (default: empty) - comma-separated extension class names
- extensions.scanning (default: false) - also load the extensions listed in META-INF/services files
- extensions.volume (default: none) - the volume holding the JARs, in the same form as a pod's volumes entry without its name
extensions:
classes: "com.example.AuditExtension"
volume:
configMap:
name: mockserver-extensions
MockServer refuses to start if persisted expectations, persisted recorded expectations or requests, the audit log or the memory-usage CSV files are turned on and would be written into /extensions.
Persistent Storage
By default, MockServer holds expectations in memory only. On Kubernetes, this means expectations are lost when a pod restarts. To persist expectations across pod restarts, enable persistent storage. This creates (or references) a PersistentVolumeClaim and automatically configures MockServer to save and reload expectations from it.
Quick Start
The simplest way to enable persistence is with a single --set flag:
helm upgrade --install --namespace mockserver \
--set app.persistence.enabled=true \
mockserver helm/mockserver
This creates a 256Mi PersistentVolumeClaim using the cluster's default StorageClass, and automatically configures MockServer to persist expectations to it.
How It Works
When app.persistence.enabled=true, the chart:
- Creates a PersistentVolumeClaim (unless app.persistence.existingClaimName is set)
- Mounts the PVC into the container at /persistence (configurable via app.persistence.mountPath)
- Sets the following environment variables to enable persistence automatically:
- MOCKSERVER_PERSIST_EXPECTATIONS=true
- MOCKSERVER_PERSISTED_EXPECTATIONS_PATH=/persistence/persistedExpectations.json
- MOCKSERVER_INITIALIZATION_JSON_PATH=/persistence/persistedExpectations.json
Important: These environment variables provide defaults. Any matching property in your mockserver.properties file takes precedence over environment variables. If you need custom paths or want to disable auto-initialization, set the equivalent properties in your properties file. See MockServer Configuration for the full property precedence rules.
Persistence Values
The following values control persistent storage:
- app.persistence.enabled (default: false) — set true to enable persistent storage
- app.persistence.existingClaimName (default: "") — name of an existing PVC to use; if empty, the chart creates one
- app.persistence.storageClass (default: "") — StorageClass for the PVC; if empty, the cluster default is used
- app.persistence.accessModes (default: [ReadWriteOnce]) — access modes for the PVC
- app.persistence.size (default: 256Mi) — size of the PVC
- app.persistence.mountPath (default: /persistence) — mount path inside the container
- app.persistence.annotations (default: {}) — annotations for the PVC (only used when creating a new PVC)
Pod securityContext (PVC write permissions)
On clusters with restrictive defaults the pod may be unable to write to the mounted volume, so persistence silently fails. Set a pod-level fsGroup so the volume is group-owned and writable. The chart exposes a top-level podSecurityContext value that is rendered verbatim into the Deployment's spec.template.spec.securityContext, so any pod-level field is supported:
helm upgrade --install --namespace mockserver \
--set app.persistence.enabled=true \
--set podSecurityContext.fsGroup=2000 \
mockserver helm/mockserver
podSecurityContext defaults to {} (no pod-level securityContext is emitted). It accepts any pod-level fields such as fsGroup, fsGroupChangePolicy, runAsGroup, or seccompProfile.
Example: Chart-Managed PVC
Let the chart create and manage the PVC:
app:
persistence:
enabled: true
storageClass: "gp3"
size: 1Gi
helm upgrade --install --namespace mockserver -f values.yaml mockserver helm/mockserver
Example: Existing PVC
If you manage PVCs separately (e.g. via GitOps or Terraform), reference an existing PVC by name:
helm upgrade --install --namespace mockserver \
--set app.persistence.enabled=true \
--set app.persistence.existingClaimName=my-mockserver-data \
mockserver helm/mockserver
Example: Clustering with Shared Storage
For clustered MockServer deployments, use a ReadWriteMany access mode with a shared filesystem such as NFS, AWS EFS, or Azure Files:
replicaCount: 3
app:
persistence:
enabled: true
accessModes:
- ReadWriteMany
storageClass: "efs-sc"
See Persisting & Clustering Expectations for more details on how MockServer clustering works.
 MockServer URL
Local Kubernetes Cluster (i.e. minikube, microk8s)
If the service type hasn't been modified the following will provide the MockServer URL from outside the cluster.
export NODE_PORT=$(kubectl get -n mockserver -o jsonpath="{.spec.ports[0].nodePort}" services mockserver)
export NODE_IP=$(kubectl get nodes -n mockserver -o jsonpath="{.items[0].status.addresses[0].address}")
export MOCKSERVER_HOST=$NODE_IP:$NODE_PORT
echo http://$MOCKSERVER_HOST
To test the installation the following curl command should return the ports MockServer is bound to:
curl -v -X PUT http://$MOCKSERVER_HOST/mockserver/status
Docker for Desktop
Docker for Desktop automatically exposes LoadBalancer services.
On MacOS Docker for Desktop runs inside Hyperkit so the node IP address is not reachable, therefore the only way to call services is via the exposed LoadBalancer service added by Docker for Desktop.
To ensure that Docker for Desktop exposes MockServer update the service type to LoadBalancer using --set service.type=LoadBalancer and set the exposed port using --set service.port=1080, as follows:
helm upgrade --install --namespace mockserver --set service.type=LoadBalancer --set service.port=1080 mockserver http://www.mock-server.com/mockserver-9.2.0.tgz
MockServer will then be reachable on http://localhost:1080
For LoadBalancer services it is possible to query kubernetes to programmatically determine the MockServer base URL as follows:
export SERVICE_IP=$(kubectl get svc --namespace mockserver mockserver -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')
export MOCKSERVER_HOST=$SERVICE_IP:1080
echo http://$MOCKSERVER_HOST
Outside Remote Kubernetes Cluster (i.e. Azure AKS, AWS EKS, etc) via Port Forward
kubectl -n mockserver port-forward svc/mockserver 1080:1080 &
export MOCKSERVER_HOST=127.0.0.1:1080
echo http://$MOCKSERVER_HOST
Inside Kubernetes Cluster
If a DNS server has been installed in the Kubernetes cluster the following DNS name should be available mockserver.<namespace>.svc.cluster.local, i.e. mockserver.mockserver.svc.cluster.local
 Helm Delete
To completely remove the chart:
helm uninstall -n mockserver mockserver
Testcontainers
To have a MockServer container started and torn down automatically by your test run, use MockServer with Testcontainers rather than running a long-lived instance yourself.
Initialize & Persist Mocks
However you run MockServer, you can preload expectations at startup and persist them across restarts. These work as CLI flags, configuration properties, or environment variables:
| What you want | CLI flag | Environment variable |
|---|---|---|
| Preload expectations from a JSON file or glob | --init <fileOrGlob> | MOCKSERVER_INITIALIZATION_JSON_PATH |
| Preload expectations from an OpenAPI spec | --openapi <specUrlOrPath> | MOCKSERVER_INITIALIZATION_OPENAPI_PATH |
| Persist expectations to a file across restarts | --persist <file> | MOCKSERVER_PERSIST_EXPECTATIONS=true + MOCKSERVER_PERSISTED_EXPECTATIONS_PATH |
For example, with Docker, mount a spec and serve it as a mock:
docker run -p 1080:1080 \
-v $(pwd)/openapi.yaml:/config/openapi.yaml \
-e MOCKSERVER_INITIALIZATION_OPENAPI_PATH=/config/openapi.yaml \
mockserver/mockserver
See Initializing Expectations, Persisting Expectations, and the configuration properties page (each property lists its environment-variable form) for full details.
Bootstrap from a Browser HAR
To get a working mock from real traffic in seconds: open your browser DevTools, record the requests on the Network tab, and Export HAR. Then import that file into a running MockServer — it creates one expectation per recorded entry:
curl -X PUT "http://localhost:1080/mockserver/import?format=har" \
--data-binary @recording.har
The same endpoint also imports Postman collections. See Importing Expectations from HAR & Postman for format detection, options, and examples.
Build & Run From Source
MockServer is written in Java and built using maven. The maven wrapper is used so maven does not need to be installed but Java JDK 17 or higher must be installed.
First clone the repository as follows:
git clone https://github.com/mock-server/mockserver-monorepo.git
cd mockserver-monorepo/mockserver
Next use maven to build an executable jar containing all dependencies as follows:
./mvnw clean package
This will produce an executable jar file under the target directory called, as follows:
mockserver-netty-no-dependencies/target/mockserver-netty-no-dependencies-9.2.0.jar
Run MockServer then using the executable jar as per the instruction above in Running From The Command Line
Next steps: once MockServer is running, head to Setup Expectations to create your first mock. Running MockServer in a test suite? See Fast Tests: Startup Time, Memory and Reuse for the patterns that keep per-test cost down to milliseconds.