DEV Community

Cover image for How to Run a Self-Hosted Mock Server on Your Intranet with Apidog
Hassann
Hassann

Posted on • Originally published at apidog.com

How to Run a Self-Hosted Mock Server on Your Intranet with Apidog

Some teams cannot send API traffic to the cloud. Corporate firewalls may block third-party services, compliance policies may require request and response data to stay on infrastructure you control, or the environment may be fully air-gapped. In these cases, even a hosted mock endpoint with fake data is not an option. Apidog supports this setup with a self-hosted runner: you deploy the runner on your own server and serve mock responses from inside your network, while keeping API definitions and mock design in your Apidog project. For broader context, see self-hosted API mock servers and the OpenAPI Initiative.

Try Apidog today

What the self-hosted runner is

The Apidog Self-hosted Runner, officially called the General Runner, is a program you host on a standalone server. It can:

  1. Run scheduled automated tests.
  2. Import API documents.
  3. Serve mock responses.

This article focuses on mock serving.

Apidog Self-hosted Runner

After you deploy a General Runner and configure its Server Host, Apidog automatically creates a Runner Mock environment in your project. Requests sent through that environment receive responses from your self-hosted runner rather than Apidog cloud mock.

The mock definition and generated data remain the same. Only the machine serving the response changes.

Use the runner when you need one or more of the following:

  • Outbound traffic to external hosts is blocked or audited.
  • Compliance policies require request data to remain on internal infrastructure.
  • Your environment is air-gapped.
  • You need mock latency measured on your LAN rather than over the public internet.

If your team can access the internet and has no data-location restrictions, Apidog cloud mock is usually simpler because there is no server to deploy.

You need team or project admin permissions to deploy a runner. Runner configuration is managed in Team Resources, which is available to admins.

What you need before you start

The General Runner is distributed as a Docker container. Your host needs Docker 20.10.0 or later; Docker 20.10.13 or newer is recommended.

Verify your Docker version:

docker --version
Enter fullscreen mode Exit fullscreen mode

You also need:

  • A Linux, macOS, or Windows machine to run the container.
  • A stable internal IP address or hostname for shared use.
  • Network access between your Apidog clients, the runner host, and the Apidog service.
  • Team or project admin permissions.

Configure the rest from Apidog.

Deploy the General Runner

Apidog generates the Docker command for you. Do not create the command manually because it contains a runner token.

1. Generate the deployment command

In Apidog:

  1. Open Home.
  2. Select your team.
  3. Open Resources in the right sidebar.
  4. Choose Deploy General Runner.

Configure the deployment dialog:

  • Server OS: Select Linux, macOS, or Windows.
  • Docker Image:
    • General includes Node.js 18, Java 21, Python 3, and PHP 8.
    • Slim includes Node.js 18 only.
    • Custom lets you provide a Dockerfile for additional test-script runtimes.
  • Exposed Port: Configure Docker port mapping with -p, such as -p 80:4524.
  • Mounted Data Directory: Configure persistent storage with -v.

Copy the generated command immediately. Apidog displays it only once because it includes your token. If you lose it, generate a new command and token.

2. Run the command on your server

Paste the generated command into a terminal on the runner host.

A typical command looks like this:

docker run -d \
  --name apidog-runner \
  -p 80:4524 \
  -v /opt/apidog-runner/data:/app/data \
  apidog/runner:latest \
  --token <YOUR_GENERATED_TOKEN>
Enter fullscreen mode Exit fullscreen mode

Your actual command will include the token generated by Apidog.

Confirm that the container is running:

docker ps
Enter fullscreen mode Exit fullscreen mode

You should see the runner container and its port mapping. You can also verify this in Docker Desktop.

3. Confirm that the runner registered

Back in Apidog:

  1. Open Team Resources.
  2. Select General Runner.
  3. Click Refresh.

The runner should appear with a Started status.

Runner statuses mean:

  • Started: The runner is enabled, connected to Apidog, and ready to process tasks.
  • Stopped: The runner was manually stopped in Apidog and will not process tasks.
  • Offline: The runner lost its connection to Apidog. Check the container and network connectivity.

Enable Runner Mock

Deploying the container creates the runner agent. Next, point mock traffic at it.

In Team Resources > General Runner, set Server Host to the address where the runner is reachable.

Examples:

http://127.0.0.1:80
Enter fullscreen mode Exit fullscreen mode
http://runner.internal.example.com:80
Enter fullscreen mode Exit fullscreen mode

If you place a TLS-terminating reverse proxy in front of the runner:

https://runner.example.com:443
Enter fullscreen mode Exit fullscreen mode

After you save Server Host, Apidog automatically adds a Runner Mock environment to the project.

Verify it:

  1. Open the project.
  2. Go to Environment Management.
  3. Confirm that Runner Mock appears in the environment list.

Send a request through the self-hosted mock

Assume your internal order-management API has this endpoint:

GET /orders/{orderId}
Enter fullscreen mode Exit fullscreen mode

To use the self-hosted mock:

  1. Open the endpoint in Apidog.
  2. Select Runner Mock from the environment dropdown.
  3. Send the request.

You can also call the runner directly:

curl http://runner.internal.example.com:80/orders/10583
Enter fullscreen mode Exit fullscreen mode

For a well-defined Order schema, the response can contain generated, schema-aware values:

{
  "orderId": 10583,
  "customerEmail": "amelia.turner@example.com",
  "status": "shipped",
  "total": 148.5,
  "currency": "USD",
  "createdAt": "2026-07-14T09:32:11Z"
}
Enter fullscreen mode Exit fullscreen mode

The response is generated and served inside your network. The runner uses the same schema-driven mock behavior as cloud mock.

To return a specific response for a request, add a mock expectation to the endpoint. The runner serves that expectation the same way cloud mock does. For more on generated data, see auto-generating realistic mock data with smart mock. General API mocking concepts apply whether you use cloud mock or a self-hosted runner.

HTTPS, mounts, and deployment details

Use a reverse proxy for HTTPS

The runner does not include built-in HTTPS certificate support or automatic certificate provisioning. To expose the runner over HTTPS, terminate TLS at a reverse proxy such as Nginx.

For example, this Nginx configuration accepts HTTPS traffic and forwards it to a runner listening on port 4524:

server {
    listen 443 ssl;
    server_name runner.example.com;

    ssl_certificate     /etc/ssl/certs/runner.example.com.pem;
    ssl_certificate_key /etc/ssl/private/runner.example.com.key;

    location / {
        proxy_pass http://127.0.0.1:4524;
        proxy_set_header Host $host;
    }
}
Enter fullscreen mode Exit fullscreen mode

Set Server Host to:

https://runner.example.com:443
Enter fullscreen mode Exit fullscreen mode

Without a reverse proxy, use an HTTP address such as http://host:port. Do not configure an https:// Server Host unless TLS is terminated before traffic reaches the runner.

See the MDN HTTPS guide for more on HTTPS and TLS termination.

Mount files at the required container paths

If tests or mocks need external files, mount them at the paths expected by the runner:

Use case Container path
External programs /app/external-programs/
Database connection configuration /app/database/database-connections.json
SSL client certificates /app/ssl/ssl-client-cert-list.json

Use Docker -v mounts so these files persist across container restarts.

Understand redeploy and upgrade behavior

When a new runner version is available, Apidog provides an Upgrade option. You can also use More Actions > Redeploy.

Both operations stop the active container while the replacement starts. Existing scheduled tasks remain configured in Apidog, but live mock serving is interrupted for the duration of the container restart.

Use the Apidog CLI for CI, not mock serving

The General Runner and the Apidog CLI solve different problems:

Tool Purpose
General Runner Long-running agent that serves mocks and runs scheduled tasks
Apidog CLI One-shot test runner for local automation and CI

The CLI does not serve, start, or host a mock server. There is no apidog run mock or apidog mock serve command.

Use apidog run to execute test scenarios, scenario folders, and test suites. The CLI mock command group manages mock expectations as data, but it does not host mock traffic.

A practical workflow looks like this:

  1. Define or update endpoints and schemas in Apidog.
  2. Use Runner Mock to unblock frontend development inside your network.
  3. Run test scenarios against the real backend in CI.

For example:

apidog run -t <scenario_id> -e <env_id> -r html,cli
Enter fullscreen mode Exit fullscreen mode

This runs a test scenario against the selected environment and produces HTML and CLI reports.

Install the CLI with:

npm install -g apidog-cli
Enter fullscreen mode Exit fullscreen mode

The CLI requires Node.js v16 or later. See the Apidog CLI installation guide for apidog login and token setup, then use the Apidog CLI CI/CD guide to run tests on every push.

For the distinction between managing mock definitions and hosting mocks, see mocking APIs from the CLI.

FAQ

Do I need a self-hosted runner if my team can access the internet?

Usually not. Cloud mock is simpler because it requires no infrastructure. Use a runner when outbound traffic is blocked or audited, compliance requires internal data handling, or your environment is air-gapped.

See the Apidog cloud mock guide for the hosted option.

Can the Apidog CLI start a self-hosted mock server?

No. The CLI runs tests with apidog run and manages mock expectations through its mock command group. Mock serving is handled by the General Runner or cloud mock.

Does the runner support HTTPS directly?

No. Put a reverse proxy such as Nginx in front of the runner to terminate TLS, then configure Server Host with the proxy's https:// URL. Otherwise, use http://host:port.

Why does my runner not appear after deployment?

Try these checks:

  1. In Apidog, open Team Resources > General Runner and click Refresh.
  2. Confirm that the container is running:
   docker ps
Enter fullscreen mode Exit fullscreen mode
  1. Verify that the runner host has the required network connectivity.

An Offline status indicates a lost connection. The expected status is Started.

Can multiple teams share one runner?

A runner registers with the team where it was deployed, and Runner Mock environments appear per project. If you need a distributed setup, see sharing mock environments across global teams.

Wrapping up

The General Runner lets you serve Apidog mocks from infrastructure you control while keeping API definitions and mock configuration in your Apidog project.

The implementation path is straightforward:

  1. Deploy the Docker container.
  2. Configure Server Host.
  3. Select the automatically created Runner Mock environment.
  4. Send requests without routing mock traffic through the public internet.

Use self-hosted mock when cloud access is restricted. Otherwise, cloud mock remains the lower-maintenance option. To get started, download Apidog, deploy a runner, and serve your first internal mock response.

Top comments (0)