Locust
Overview
This image runs Locust 2.45.0, an open-source developer load-testing tool, on Ubuntu 24.04 LTS. With Locust, you describe how simulated users behave in a small Python file. You then swarm thousands of those users at a target system and watch response times, throughput and failures live in a web dashboard and a matching JSON stats API.
The SecureAnyCloud image is secure by default. The Locust web UI ships with no authentication, so this image binds the Locust server to the loopback interface only and fronts it with nginx on port 80 using HTTP Basic authentication.
The password is a unique value that is generated on first boot for each instance and written to a root-only file. No credential is baked into the image, and no two deployments share one.
What you get:
- Locust 2.45.0 installed into a pinned, self-contained Python virtual environment at
/opt/locust/venv - A dedicated non-root
locustservice (locust-web.service) bound to127.0.0.1:8089 - nginx on port
80, which reverse-proxies the web UI and stats API with HTTP Basic authentication, plus an unauthenticated/healthzendpoint for Azure Load Balancer probes - A one-shot
locust-firstboot.servicethat generates a per-instance password on first boot and writes it to/root/locust-info.txt(mode0600) - A ready-to-run sample scenario at
/opt/locust/locustfile.py, so you can start a test immediately - An Ubuntu 24.04 LTS base, patched at build time, with unattended security upgrades enabled
- 24/7 SecureAnyCloud support
Locust is published by the Locust project under the MIT licence. This image is packaged by SecureAnyCloud and is not affiliated with or endorsed by the Locust project.
Prerequisites
You need an active Azure subscription, an SSH key pair, and a VNet with a subnet in the target region.
Standard_B2s (2 vCPU / 4 GiB RAM) is a sensible starting size for driving load from a single node. Scale up for higher user counts.
Configure the NSG inbound rules to allow 22/tcp from your management network and 80/tcp for the web UI. Locust serves plain HTTP on port 80. For production or shared access, terminate TLS in front of it with your own domain, using a reverse proxy or Azure Application Gateway.
Step 1 - Deploy from the Azure Marketplace
Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Locust by SecureAnyCloud, and select Create.
On the Basics tab, pick your subscription, resource group, region and size. Under Administrator account, choose SSH public key and paste your key. Under Inbound port rules, allow SSH (22) and HTTP (80).
Select Review + create, then Create.
Step 2 - Deploy from the Azure CLI
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:locust-ubuntu-24-04:default:latest
az vm create \
--resource-group <your-rg> \
--name locust \
--image sac1647283583153:locust-ubuntu-24-04:default:latest \
--size Standard_B2s \
--admin-username azureuser \
--ssh-key-values ~/.ssh/id_ed25519.pub \
--vnet-name <your-vnet> --subnet <your-subnet> \
--public-ip-sku Standard
az vm open-port --resource-group <your-rg> --name locust --port 80 --priority 1010Step 3 - Connect to your VM
ssh azureuser@<vm-public-ip>Step 4 - Confirm the services are running
Locust runs as locust-web.service on the loopback interface, fronted by nginx on port 80. A one-shot locust-firstboot.service runs once on first boot to generate the per-instance password.
Confirm that all three units are active, and that nginx is listening on port 80 while Locust stays private on 127.0.0.1:8089:
sudo systemctl is-active nginx locust-web locust-firstboot
sudo ss -tlnp | grep -E ':80 |:8089 'Expected output:
active active active LISTEN 0 128 127.0.0.1:8089 0.0.0.0:* users:(("locust",pid=2459,fd=3)) LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",...)) LISTEN 0 511 [::]:80 [::]:* users:(("nginx",...))Locust listens only on 127.0.0.1, so it is never reachable directly from the network; every request goes through nginx on port 80, which enforces the login.
Step 5 - Retrieve your per-instance credentials
HTTP Basic authentication protects the web UI. The username is locust. The password is generated uniquely for this instance on first boot and stored in a root-only file. Read it with:
sudo cat /root/locust-info.txtThe output shows the access URL, the username and the per-instance password:
locust_url=http://<vm-ip>/ locust_username=locust locust_password=<your-unique-password>Keep this password safe. It is unique to this VM, and no default password ships in the image. You can rotate it at any time with sudo htpasswd -B /etc/nginx/locust.htpasswd locust.
Step 6 - Confirm the web UI is secure by default
The /healthz endpoint used by load-balancer probes is intentionally open and returns 200. The web UI and the stats API require the credentials, so an unauthenticated request returns 401:
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1/healthz
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1/stats/requestsExpected output:
200 401Supplying the per-instance credentials returns the live test state as JSON. Replace <locust-password> with the password from /root/locust-info.txt:
curl -s -u locust:<locust-password> http://127.0.0.1/stats/requestsExpected output (an authenticated request returns the live stats; ready or stopped before you start a test):
{"stats": [...], "errors": [], "state": "ready", "user_count": 0, "total_rps": 0.0, "fail_ratio": 0.0, ...}Step 7 - Confirm the version and the sample scenario
Confirm the pinned Locust version and the health endpoint, and look at the sample scenario that ships on the image:
/opt/locust/venv/bin/locust --version curl -s -o /dev/null -w 'healthz HTTP %{http_code}\n' http://127.0.0.1/healthzExpected output:
locust 2.45.0 from /opt/locust/venv/lib/python3.12/site-packages/locust (Python 3.12.3) healthz HTTP 200The image ships a ready-to-run sample scenario at /opt/locust/locustfile.py. It is a minimal HttpUser that repeatedly requests the root path of a configurable target host. Use it as your starting point, and edit it or replace it with your own scenarios.
Step 8 - Run a load test from the web UI
In a browser, open http://<vm-public-ip>/ and sign in as locust with the per-instance password. Locust shows the Start new load test screen.
Enter the peak number of simulated users, the ramp-up rate (users started per second) and the Host to test against, then click START. The Host defaults to the value in the sample scenario. You can change it to any URL you want to load test.
Once the test is running, the Statistics tab shows a live table. It lists the number of requests and failures per endpoint, the median, 95th and 99th percentile response times, the average and maximum times, and the current requests per second. The aggregated row summarises the whole test.
The Charts tab plots the same data over time: total requests per second, failures per second, response-time percentiles and the number of simulated users. Use it to see how the target behaves as load ramps up.
While a test is running, you can adjust the number of users and the ramp-up rate on the fly from the EDIT button. You can also stop the test and start a fresh run at any time.
Writing your own scenarios
Locust scenarios are plain Python. Edit /opt/locust/locustfile.py, or point the service at your own file, to model real user journeys. A minimal example:
from locust import HttpUser, task, between class WebsiteUser(HttpUser): wait_time = between(1, 3) @task(3) def index(self): self.client.get("/") @task def about(self): self.client.get("/about")After editing, restart the service with sudo systemctl restart locust-web and reload the web UI. You can also run a test headless from the command line, for example sudo -u locust /opt/locust/venv/bin/locust -f /opt/locust/locustfile.py --headless -u 100 -r 10 -t 1m --host https://your-target.example.
Enabling HTTPS for production
Locust serves plain HTTP on port 80 behind nginx. For production or shared access, put your own TLS certificate in front of it.
Point a DNS record at the public IP of the VM. Then terminate TLS with Azure Application Gateway, or extend the nginx configuration in /etc/nginx/sites-available/sac-locust with a certbot-issued certificate for your domain. Once TLS is in place, restrict port 80 to your Application Gateway or management network in the NSG.
Support
Every SecureAnyCloud image includes 24/7 support, 365 days a year, by email and live chat with a 24 hour response SLA. Contact sales@secureanycloud.com with the product name and your Azure region, and we will help.
Deploy on Azure
Launch Locust on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.
View this image
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com
Overview
This image runs Locust 2.45.0, an open-source, developer-friendly distributed load-testing tool. With Locust, you describe how simulated users behave in a small Python file. You then swarm thousands of those users at a target system and watch response times, throughput and failures live in a web dashboard and a matching JSON stats API.
The SecureAnyCloud image is secure by default. The Locust web UI ships with no authentication, so this image binds the Locust server to the loopback interface only and fronts it with nginx on port 80 using HTTP Basic authentication.
The password is a unique value that is generated on first boot for each instance and written to a root-only file. No credential is baked into the image, and no two deployments share one.
What you get:
- Locust 2.45.0 installed into a pinned, self-contained Python virtual environment at
/opt/locust/venv - A dedicated non-root
locustservice (locust-web.service) bound to127.0.0.1:8089 - nginx on port
80, which reverse-proxies the web UI and stats API with HTTP Basic authentication, plus an unauthenticated/healthzendpoint for load-balancer probes - A one-shot
locust-firstboot.servicethat generates a per-instance password on first boot and writes it to/root/locust-info.txt(mode0600) - A ready-to-run sample scenario at
/opt/locust/locustfile.py, so you can start a test immediately - A fully patched Ubuntu 24.04 LTS base
- 24/7 SecureAnyCloud support
Locust is published by the Locust project under the MIT licence. This image is packaged by SecureAnyCloud and is not affiliated with or endorsed by the Locust project.
Prerequisites
You need an AWS account, an EC2 key pair in the target region, and a VPC with a public subnet.
m5.large (2 vCPU / 8 GiB RAM) is the recommended instance type for driving load from a single node. Scale up for higher user counts.
Configure the security group inbound rules to allow 22/tcp from your management network for SSH and 80/tcp for the web UI. Locust serves plain HTTP on port 80. For production or shared access, terminate TLS in front of it with your own domain, using a reverse proxy or an Application Load Balancer.
Step 1 - Launch the AMI
Subscribe to the listing in AWS Marketplace, choose Continue to Launch, and launch through the EC2 console or the AWS CLI. Select the m5.large instance type, your key pair, and a security group that opens ports 22 and 80.
aws ec2 run-instances \
--image-id <ami-id> \
--instance-type m5.large \
--key-name <your-key-pair> \
--security-group-ids <security-group-id> \
--subnet-id <subnet-id> \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=locust}]'Step 2 - Connect to your instance
Connect over SSH as the default login user for the OS variant you launched. This listing may ship more than one OS variant, so use the matching login user below.
OS variant SSH login user Connect
Ubuntu 24.04 LTS ubuntu ssh ubuntu@<instance-public-ip>
Step 3 - Confirm the services are running
Locust runs as locust-web.service on the loopback interface, fronted by nginx on port 80. A one-shot locust-firstboot.service runs once on first boot to generate the per-instance password.
Confirm that all three units are active, and that nginx is listening on port 80 while Locust stays private on 127.0.0.1:8089:
systemctl is-active nginx locust-web locust-firstboot
sudo ss -tlnp | grep -E ':80 |:8089 'Expected output:
active active active LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",...)) LISTEN 0 128 127.0.0.1:8089 0.0.0.0:* users:(("locust",pid=3398,fd=3)) LISTEN 0 511 [::]:80 [::]:* users:(("nginx",...))Locust listens only on 127.0.0.1, so it is never reachable directly from the network; every request goes through nginx on port 80, which enforces the login.
Step 4 - Retrieve your per-instance credentials
HTTP Basic authentication protects the web UI. The username is locust. The password is generated uniquely for this instance on first boot and stored in a root-only file. Read it with:
sudo cat /root/locust-info.txtThe output shows the access URL, the username and the per-instance password:
locust_url=http://<instance-public-ip>/ locust_username=locust locust_password=<locust-password>Keep this password safe. It is unique to this instance, and no default password ships in the image. You can rotate it at any time with sudo htpasswd -B /etc/nginx/locust.htpasswd locust.
Step 5 - Confirm the web UI is secure by default
The /healthz endpoint used by load-balancer probes is intentionally open and returns 200. The web UI and the stats API require the credentials, so an unauthenticated request returns 401:
curl -s -o /dev/null -w 'healthz %{http_code}\n' http://127.0.0.1/healthz
curl -s -o /dev/null -w 'stats-unauth %{http_code}\n' http://127.0.0.1/stats/requestsExpected output:
healthz 200 stats-unauth 401Supplying the per-instance credentials returns the live test state as JSON. This one-liner reads the password directly from the root-only file and uses it:
P=$(sudo awk -F= '/^locust_password=/{print $2}' /root/locust-info.txt)
curl -s -u "locust:$P" http://127.0.0.1/stats/requests | head -c 200Expected output (an authenticated request returns the live stats; ready or stopped before you start a test):
{"current_fail_per_sec": 0, "current_response_time_percentiles": {"response_time_percentile_0.5": 0, "response_time_percentile_0.95": 0}, "current_rps": 0, "errors": [], "fail_r...Step 6 - Confirm the version and the sample scenario
Confirm the pinned Locust version and the health endpoint:
/opt/locust/venv/bin/locust --version curl -s -o /dev/null -w 'healthz HTTP %{http_code}\n' http://127.0.0.1/healthzExpected output:
locust 2.45.0 from /opt/locust/venv/lib/python3.12/site-packages/locust (Python 3.12.3) healthz HTTP 200The image ships a ready-to-run sample scenario at /opt/locust/locustfile.py. It is a minimal HttpUser that repeatedly requests the root path of a configurable target host. Use it as your starting point, and edit it or replace it with your own scenarios.
Step 7 - Run a load test from the web UI
In a browser, open http://<instance-public-ip>/ and sign in as locust with the per-instance password. Locust shows the Start new load test screen.
Enter the peak number of simulated users, the ramp-up rate (users started per second) and the Host to test against, then click START. The Host defaults to the value in the sample scenario. You can change it to any URL you want to load test.
Once the test is running, the Statistics tab shows a live table. It lists the number of requests and failures per endpoint, the median, 95th and 99th percentile response times, the average, min and max times, and the current requests per second. The aggregated row summarises the whole test.
The Charts tab plots the same data over time: total requests per second, failures per second, response-time percentiles and the number of simulated users. Use it to see how the target behaves as load ramps up.
The Failures tab lists any request that did not succeed, grouped by method, name and error message. It shows the count and when each failure was first and last seen, so you can pinpoint what broke under load.
While a test is running, you can adjust the number of users and the ramp-up rate on the fly. You can also stop the test and start a fresh run at any time.
Writing your own scenarios
Locust scenarios are plain Python. Edit /opt/locust/locustfile.py, or point the service at your own file, to model real user journeys. A minimal example:
from locust import HttpUser, task, between class WebsiteUser(HttpUser): wait_time = between(1, 3) @task(3) def index(self): self.client.get("/") @task def about(self): self.client.get("/about")After editing, restart the service with sudo systemctl restart locust-web and reload the web UI. You can also run a test headless from the command line, for example sudo -u locust /opt/locust/venv/bin/locust -f /opt/locust/locustfile.py --headless -u 100 -r 10 -t 1m --host https://your-target.example.
Enabling HTTPS for production
Locust serves plain HTTP on port 80 behind nginx. For production or shared access, put your own TLS certificate in front of it.
Point a DNS record at the public IP of the instance. Then terminate TLS with an Application Load Balancer, or extend the nginx configuration in /etc/nginx/sites-available/sac-locust with a certbot-issued certificate for your domain. Once TLS is in place, restrict port 80 to your load balancer or management network in the security group.
Support
Every SecureAnyCloud image includes 24/7 support, 365 days a year, by email and live chat with a 24 hour response SLA. Contact sales@secureanycloud.com with the product name and your AWS region, and we will help.
Deploy on AWS
Launch Locust with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com