Pull the latest Dodo image from Docker Hub:
docker pull aykhans/dodo:latest
To use Dodo with Docker and a local config file, mount the config file as a volume and pass it as an argument:
docker run -v /path/to/config.json:/config.json aykhans/dodo -f /config.json
If you're using a remote config file via URL, you don't need to mount a volume:
docker run aykhans/dodo -f https://raw.githubusercontent.com/aykhans/dodo/main/config.yaml
Download the latest binaries from the releases section.
To build Dodo from source, ensure you have Go 1.24+ installed.
go install -ldflags "-s -w" github.com/aykhans/dodo@latest
Dodo supports CLI arguments, configuration files (JSON/YAML), or a combination of both. If both are used, CLI arguments take precedence.
Send 1000 GET requests to https://example.com with 10 parallel dodos (threads), each with a timeout of 2 seconds, within a maximum duration of 1 minute:
dodo -u https://example.com -m GET -d 10 -r 1000 -o 1m -t 2s
With Docker:
docker run --rm -i aykhans/dodo -u https://example.com -m GET -d 10 -r 1000 -o 1m -t 2s
Send 1000 GET requests to https://example.com with 10 parallel dodos (threads), each with a timeout of 800 milliseconds, within a maximum duration of 250 seconds:
method: "GET"
url: "https://example.com"
yes: false
timeout: "800ms"
dodos: 10
requests: 1000
duration: "250s"
skip_verify: false
params:
# A random value will be selected from the list for first "key1" param on each request
# And always "value" for second "key1" param on each request
# e.g. "?key1=value2&key1=value"
- key1: ["value1", "value2", "value3", "value4"]
- key1: "value"
# A random value will be selected from the list for param "key2" on each request
# e.g. "?key2=value2"
- key2: ["value1", "value2"]
headers:
# A random value will be selected from the list for first "key1" header on each request
# And always "value" for second "key1" header on each request
# e.g. "key1: value3", "key1: value"
- key1: ["value1", "value2", "value3", "value4"]
- key1: "value"
# A random value will be selected from the list for header "key2" on each request
# e.g. "key2: value2"
- key2: ["value1", "value2"]
cookies:
# A random value will be selected from the list for first "key1" cookie on each request
# And always "value" for second "key1" cookie on each request
# e.g. "key1=value4; key1=value"
- key1: ["value1", "value2", "value3", "value4"]
- key1: "value"
# A random value will be selected from the list for cookie "key2" on each request
# e.g. "key2=value1"
- key2: ["value1", "value2"]
body: "body-text"
# OR
# A random body value will be selected from the list for each request
body:
- "body-text1"
- "body-text2"
- "body-text3"
proxy: "http://example.com:8080"
# OR
# A random proxy will be selected from the list for each request
proxy:
- "http://example.com:8080"
- "http://username:password@example.com:8080"
- "socks5://example.com:8080"
- "socks5h://example.com:8080"
dodo -f /path/config.yaml
# OR
dodo -f https://example.com/config.yaml
With Docker:
docker run --rm -i -v /path/to/config.yaml:/config.yaml aykhans/dodo -f /config.yaml
# OR
docker run --rm -i aykhans/dodo -f https://example.com/config.yaml
dodo -f /path/config.json
# OR
dodo -f https://example.com/config.json
With Docker:
docker run --rm -i -v /path/to/config.json:/config.json aykhans/dodo
# OR
docker run --rm -i aykhans/dodo -f https://example.com/config.json
CLI arguments override config file values:
dodo -f /path/to/config.yaml -u https://example.com -m GET -d 10 -r 1000 -o 1m -t 5s
With Docker:
docker run --rm -i -v /path/to/config.json:/config.json aykhans/dodo -f /config.json -u https://example.com -m GET -d 10 -r 1000 -o 1m -t 5s
You can find more usage examples in the EXAMPLES.md file.
If Headers
, Params
, Cookies
, Body
, or Proxy
fields have multiple values, each request will choose a random value from the list.
Parameter | config file | CLI Flag | CLI Short Flag | Type | Description | Default |
---|---|---|---|---|---|---|
Config file | -config-file | -f | String | Path to local config file or http(s) URL of the config file | - | |
Yes | yes | -yes | -y | Boolean | Answer yes to all questions | false |
URL | url | -url | -u | String | URL to send the request to | - |
Method | method | -method | -m | String | HTTP method | GET |
Dodos (Threads) | dodos | -dodos | -d | UnsignedInteger | Number of dodos (threads) to send requests in parallel | 1 |
Requests | requests | -requests | -r | UnsignedInteger | Total number of requests to send | - |
Duration | duration | -duration | -o | Time | Maximum duration for the test | - |
Timeout | timeout | -timeout | -t | Time | Timeout for canceling each request | 10s |
Params | params | -param | -p | [{String: String OR [String]}] | Request parameters | - |
Headers | headers | -header | -H | [{String: String OR [String]}] | Request headers | - |
Cookies | cookies | -cookie | -c | [{String: String OR [String]}] | Request cookies | - |
Body | body | -body | -b | String OR [String] | Request body or list of request bodies | - |
Proxy | proxies | -proxy | -x | String OR [String] | Proxy URL or list of proxy URLs | - |
Skip Verify | skip_verify | -skip-verify | Boolean | Skip SSL/TLS certificate verification | false |
Dodo supports template functions in Headers
, Params
, Cookies
, and Body
fields. These functions allow you to generate dynamic values for each request.
You can use Go template syntax to include dynamic values in your requests. Here's how to use template functions:
In CLI config:
dodo -u https://example.com -r 1 \
-header "User-Agent:{{ fakeit_UserAgent }}" \ # e.g. "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)"
-param "username={{ strings_ToUpper fakeit_Username }}" \ # e.g. "username=JOHN BOB"
-cookie "token={{ fakeit_Password true true true true true 10 }}" \ # e.g. token=1234567890abcdef1234567890abcdef
-body '{"email":"{{ fakeit_Email }}", "password":"{{ fakeit_Password true true true true true 10 }}"}' # e.g. {"email":"john.doe@example.com", "password":"12rw4d-78d"}
In YAML/YML config:
headers:
- User-Agent: "{{ fakeit_UserAgent }}" # e.g. "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)"
- "Random-Header-{{fakeit_FirstName}}": "static_value" # e.g. "Random-Header-John: static_value"
cookies:
- token: "Bearer {{ fakeit_UUID }}" # e.g. "token=Bearer 1234567890abcdef1234567890abcdef"
params:
- id: "{{ fakeit_Uint }}" # e.g. "id=1234567890"
- username: "{{ fakeit_Username }}" # e.g. "username=John Doe"
body:
- '{ "username": "{{ fakeit_Username }}", "password": "{{ fakeit_Password }}" }' # e.g. { "username": "john.doe", "password": "password123" }
- '{ "email": "{{ fakeit_Email }}", "phone": "{{ fakeit_Phone }}" }' # e.g. { "email": "john.doe@example.com", "phone": "1234567890" }
- '{{ body_FormData (dict_Str "username" fakeit_Username "password" "secret123") }}' # Creates multipart form data for form submissions, automatically sets the appropriate Content-Type header.
In JSON config:
{
"headers": [
{ "User-Agent": "{{ fakeit_UserAgent }}" }, // e.g. "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)"
],
"body": [
"{ \"username\": \"{{ strings_RemoveSpaces fakeit_Username }}\", \"password\": \"{{ fakeit_Password }}\" }", // e.g. { "username": "johndoe", "password": "password123" }
"{{ body_FormData (dict_Str \"username\" fakeit_Username \"password\" \"12345\") }}", // Creates multipart form data for form submissions, automatically sets the appropriate Content-Type header.
],
}
For the full list of template functions over 200 functions, refer to the NewFuncMap
function in utils/templates.go
.