Skip to content

Running Multiple Surfmeter Instances

You may want to run multiple Surfmeter Automator instances in parallel on the same machine, e.g. to increase throughput. At the moment we do not allow executing multiple instances of the browser from the same machine, so the easiest way to achieve this is with Docker.

Requirements

You need to first set up Docker according to our setup guide.

Each Surfmeter instance requires CPU, memory, and disk space. Make sure your host machine has sufficient resources. As a rough guideline:

  • CPU: 1-2 cores per instance (during active measurements)
  • RAM: 2-4 GB per instance
  • Disk: Varies based on video recordings and reports

Monitor your system resources when running multiple instances, especially during concurrent measurements.

Setup

Currently, each service needs:

  • A unique container name
  • Unique port mappings (for VNC and health check)
  • Separate bind mount directories for config, reports, and logs
  • A uniquely named volume for the profile
  • Optionally, different registration keys or environment variables

Here's an example with two instances:

name: surfmeter-lab-automator

services:
  surfmeter-1: # (1)!
    image: registry.aveq.info/<customer>/surfmeter-lab-automator:<customer>-latest
    container_name: surfmeter-1
    restart: unless-stopped
    cap_add:
      - NET_ADMIN
      - NET_RAW
    volumes:
      - profile-1:/home/surfmeter/profile # (2)!
      - ./surfmeter-1/reports:/home/surfmeter/reports
      - ./surfmeter-1/config:/home/surfmeter/config
      - ./surfmeter-1/logs:/home/surfmeter/logs
    environment:
      SURFMETER_AUTO_LOAD_SCHEDULE: "1"
      SURFMETER_AUTO_REGISTER: "1"
      SURFMETER_DEFAULT_REGISTRATION_KEY: "<your-registration-key-1>"
    ports: # (3)!
      - "127.0.0.1:5123:5123"
      - "127.0.0.1:8080:80"

  surfmeter-2:
    image: registry.aveq.info/<customer>/surfmeter-lab-automator:<customer>-latest
    container_name: surfmeter-2
    restart: unless-stopped
    cap_add:
      - NET_ADMIN
      - NET_RAW
    volumes:
      - profile-2:/home/surfmeter/profile
      - ./surfmeter-2/reports:/home/surfmeter/reports
      - ./surfmeter-2/config:/home/surfmeter/config
      - ./surfmeter-2/logs:/home/surfmeter/logs
    environment:
      SURFMETER_AUTO_LOAD_SCHEDULE: "1"
      SURFMETER_AUTO_REGISTER: "1"
      SURFMETER_DEFAULT_REGISTRATION_KEY: "<your-registration-key-2>"
    ports: # (4)!
      - "127.0.0.1:5124:5123"
      - "127.0.0.1:8081:80"

volumes:
  profile-1: # (5)!
  profile-2:
  1. Each service has a unique name. You can use any naming scheme that makes sense for your setup.
  2. Each instance has its own named volume and bind mount directories. The bind mount paths are relative to the docker-compose.yml file.
  3. Instance 1 uses the default ports 5123 and 8080.
  4. Instance 2 uses different host ports (5124 and 8081) to avoid conflicts. The internal container ports must remain the same (5123 and 80).
  5. Each instance needs its own named volume to store the profile independently.

Adjust the number of instances, port mappings, and other settings as needed for your use case.

After creating this file, you need to create the bind mount directories:

mkdir -p surfmeter-1/{config,reports,logs}
mkdir -p surfmeter-2/{config,reports,logs}

Then start all instances with:

docker compose up -d

To view logs:

docker compose logs -f

Running Commands Across All Instances

Sometimes you may want to run the same command across all Surfmeter instances, e.g. to check their status or update configurations. Here are some useful patterns:

for service in $(docker compose ps --services | grep surfmeter); do
    echo "=== $service ==="
    docker compose exec -it --user surfmeter $service \
        surfmeter-lab-automator/surfmeter-automator-headless --version
done
for service in $(docker compose ps --services | grep surfmeter); do
    echo "=== $service ==="
    docker compose exec -it --user surfmeter $service \
        surfmeter-lab-automator/surfmeter-automator-headless --show-registration
done

You can add this function to your ~/.bashrc or ~/.zshrc to make it easier:

surfmeter-exec() {
    for service in $(docker compose ps --services | grep surfmeter); do
    echo "=== $service ==="
    docker compose exec -it --user surfmeter $service "$@"
    done
}

Then use it like:

surfmeter-exec surfmeter-lab-automator/surfmeter-automator-headless --version

Note that this only works from within the directory containing the docker-compose.yml file.