summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorValery Piashchynski <[email protected]>2024-10-29 15:42:16 +0100
committerGitHub <[email protected]>2024-10-29 15:42:16 +0100
commit3911515b4514caa8ca32f16711a854c527916fac (patch)
tree65e46f92dafc790af94b25594cdb82efe5c944bb
parent460433eb41db7c93876f846f1bd0f4c8ef64f22b (diff)
parentdfe53b98553f3dd249b1755d5cce365d323d5f40 (diff)
[#2035]: feature: Reference plugin JSON schemas
-rw-r--r--.github/workflows/schema.yaml38
-rw-r--r--.github/workflows/tests.yml18
-rw-r--r--.gitignore1
-rw-r--r--.rr.yaml187
-rw-r--r--schemas/config/3.0.schema.json1566
-rw-r--r--schemas/package-lock.json108
-rw-r--r--schemas/package.json16
-rw-r--r--schemas/readme.md10
-rw-r--r--schemas/test.js39
9 files changed, 325 insertions, 1658 deletions
diff --git a/.github/workflows/schema.yaml b/.github/workflows/schema.yaml
new file mode 100644
index 00000000..ed029b38
--- /dev/null
+++ b/.github/workflows/schema.yaml
@@ -0,0 +1,38 @@
+name: rr_json_schema_validation
+
+on:
+ push:
+ branches:
+ - master
+ - stable
+ paths:
+ - '.rr*'
+ - 'schemas/**'
+ - '.github/workflows/schema.yaml'
+ pull_request:
+ paths:
+ - '.rr*'
+ - 'schemas/**'
+ - '.github/workflows/schema.yaml'
+
+jobs:
+ validate-json-schema:
+ name: Validate JSON Schema files
+ runs-on: ubuntu-latest
+ defaults:
+ run:
+ working-directory: ./schemas
+ steps:
+ - name: Check out code
+ uses: actions/checkout@v4
+
+ - name: Setup nodejs
+ uses: actions/setup-node@v4
+ with:
+ node-version: "20"
+
+ - name: Install Test Script Dependencies
+ run: npm install
+
+ - name: Run Script
+ run: node test.js
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index aa10b71a..6236891c 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -8,24 +8,6 @@ on:
pull_request:
jobs:
- validate-config-file:
- name: Validate config file
- runs-on: ubuntu-latest
- steps:
- - name: Check out code
- uses: actions/checkout@v4
-
- - name: Setup nodejs
- uses: actions/setup-node@v4
- with:
- node-version: "14"
-
- - name: Install linter
- run: npm install -g ajv-cli # Package page: <https://www.npmjs.com/package/ajv-cli>
-
- - name: Run linter
- run: ajv validate --all-errors --verbose -s ./schemas/config/3.0.schema.json --spec=draft2019 -d ./.rr.yaml
-
golangci-lint:
name: Golang-CI (lint)
runs-on: ubuntu-latest
diff --git a/.gitignore b/.gitignore
index 162cc609..f3b3d97b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -24,3 +24,4 @@ rr.exe
.vscode
.DS_Store
**/.DS_Store
+**/node_modules
diff --git a/.rr.yaml b/.rr.yaml
index a9842968..e50f5717 100644
--- a/.rr.yaml
+++ b/.rr.yaml
@@ -4,7 +4,6 @@
# MORE DOCS CAN BE FOUND HERE: <https://roadrunner.dev/docs/intro-config> #
######################################################################################
-$schema: "./schemas/config/3.0.schema.json"
# Production usage guide: https://roadrunner.dev/docs/app-server-production/2.x/en
# Hint: RR will replace any config options using reference to environment variables,
@@ -47,7 +46,7 @@ server:
# Username (not UID) of the user from whom the on_init command is executed. An empty value means to use the RR process user.
#
# Default: ""
- user: ""
+ # user: ""
# Worker starting command, with any required arguments.
#
@@ -57,12 +56,12 @@ server:
# Username (not UID) for the worker processes. An empty value means to use the RR process user.
#
# Default: ""
- user: ""
+ # user: ""
# Group name (not GID) for the worker processes. An empty value means to use the RR process group.
#
# Default: ""
- group: ""
+ # group: ""
# Environment variables for the worker processes.
#
@@ -104,12 +103,12 @@ logs:
# Output can be file (eg.: "/var/log/rr_errors.log"), "stderr" or "stdout".
#
# Default: "stderr"
- output: stderr
+ output: [ stderr ]
# Errors only output can be file (eg.: "/var/log/rr_errors.log"), "stderr" or "stdout".
#
# Default: "stderr"
- err_output: stderr
+ err_output: [ stderr ]
# File logger options
#
@@ -150,20 +149,20 @@ logs:
mode: development
level: panic
encoding: console
- output: stdout
- err_output: stderr
+ output: [ stdout ]
+ err_output: [ stderr ]
server:
mode: production
level: info
encoding: json
- output: stdout
- err_output: stdout
+ output: [ stdout ]
+ err_output: [ stdout ]
rpc:
mode: raw
level: debug
encoding: console
- output: stderr
- err_output: stdout
+ output: [ stderr ]
+ err_output: [ stdout ]
# Workflow and activity mesh service.
#
@@ -188,65 +187,52 @@ temporal:
# Default: default
namespace: default
+
# Temporal metrics
#
# Optional section
metrics:
- # ---- Prometheus
-
# Metrics driver to use
- #
# Optional, default: prometheus. Available values: prometheus, statsd
driver: prometheus
- # Server metrics address
- #
- # Required for the production. Default: 127.0.0.1:9091, for the metrics 127.0.0.1:9091/metrics
- address: 127.0.0.1:9091
- # Metrics type
- #
- # Default: "summary". Supported values: summary, histogram
- type: "summary"
- # Temporal metrics prefix
- #
- # Default: (empty)
- prefix: "foobar"
+ # ---- Prometheus
+ prometheus:
+ # Server metrics address
+ # Required for the production. Default: 127.0.0.1:9091, for the metrics 127.0.0.1:9091/metrics
+ address: 127.0.0.1:9091
+ # Metrics type
+ type: "summary"
+ # Temporal metrics prefix
+ # Default: (empty)
+ prefix: "foobar"
# ---- Statsd (uncomment)
-
- # Metrics driver to use
- #
- # Optional, default: prometheus. Available values: prometheus, statsd
- # driver: statsd
-
# Statsd host and port
- #
- # Optional, default: 127.0.0.1:8125
- # host_port: "127.0.0.1:8125"
-
- # Prefix for the metrics
- #
- # Optional, default: empty
- # prefix: "samples"
-
- # Flush interval is the maximum interval for sending packets.
- #
- # Optional, default: 1s
- # flush_interval: 1s
-
- # Flush bytes specifies the maximum udp packet size you wish to send.
- # If FlushBytes is unspecified, it defaults to 1432 bytes, which is
- # considered safe for local traffic
- #
- # Optional, default: 1432
- # flush_bytes: 1432
-
- # Tags passed to the statsd on init
- #
- # Optional, default: empty
+ #statsd:
+ # Optional
+ # default: 127.0.0.1:8125
+ # host_port: "127.0.0.1:8125"
+ #
+ # Prefix for the metrics
+ # Optional, default: empty
+ # prefix: "samples"
+ #
+ # Flush interval is the maximum interval for sending packets.
+ # Optional, default: 1s
+ # flush_interval: 1s
+ #
+ # Flush bytes specifies the maximum udp packet size you wish to send.
+ # If FlushBytes is unspecified, it defaults to 1432 bytes, which is
+ # considered safe for local traffic
+ # Optional, default: 1432
+ # flush_bytes: 1432
+ #
+ # Tags passed to the statsd on init
+ # Optional, default: empty
#tags:
- # - foo: bar
+ # foo: bar
# Temporal TLS configuration
#
@@ -456,7 +442,7 @@ kv:
#
# Default: none
driver: memory
- config: {}
+ config: { }
# Service plugin settings
service:
@@ -560,25 +546,25 @@ otel:
# https://github.com/open-telemetry/opentelemetry-specification/blob/v1.25.0/specification/resource/semantic_conventions/README.md
resource:
- # User's service name
- #
- # Default: RoadRunner
- service_name: "rr_test"
+ # User's service name
+ #
+ # Default: RoadRunner
+ service_name: "rr_test"
- # User's service version
- #
- # Default: RoadRunner
- service_version: "1.0.0"
+ # User's service version
+ #
+ # Default: RoadRunner
+ service_version: "1.0.0"
- # User's service namespace
- #
- # Default: RoadRunner
- service_namespace: "RR-Shop"
+ # User's service namespace
+ #
+ # Default: RoadRunner
+ service_namespace: "RR-Shop"
- # User's service instance id
- #
- # Default: Generated UUID
- service_instance_id: "UUID"
+ # User's service instance id
+ #
+ # Default: Generated UUID
+ service_instance_id: "UUID"
# Use insecure endpoint (http) or insecure gRPC
#
# Default: false
@@ -602,7 +588,7 @@ otel:
# Used for the http client to override the default URL
#
# Default: empty
- custom_url: ""
+ # custom_url: ""
# Consumer's endpoint
#
@@ -976,15 +962,19 @@ metrics:
# Application-specific metrics (published using an RPC connection to the server).
collect:
- app_metric:
- type: histogram
- help: "Custom application metric"
+ app_metric_summary:
+ type: summary
+ help: "Custom summary application metric"
labels: [ "type" ]
- buckets: [ 0.1, 0.2, 0.3, 1.0 ]
# Objectives defines the quantile rank estimates with their respective absolute error (for summary only).
objectives:
- - 1.4: 2.3
- - 2.0: 1.4
+ 0.1: 2.3
+ 1.0: 1.4
+ app_metric_histogram:
+ type: histogram
+ help: "Custom histogram application metric"
+ labels: [ "type" ]
+ buckets: [ 0.1, 0.2, 0.3, 1.0 ]
# Health check endpoint (docs: https://roadrunner.dev/docs/app-server-health/2.x/en). If response code is 200 - it means at
# least one worker ready to serve requests. 500 - there are no workers ready to service requests.
@@ -1133,7 +1123,7 @@ kafka:
# Kafka brokers addresses
#
# Required to use Kafka driver
- brokers: ["127.0.0.1:9092", "127.0.0.1:9002"]
+ brokers: [ "127.0.0.1:9092", "127.0.0.1:9002" ]
# SSL/TLS configuration
#
@@ -1372,11 +1362,6 @@ jobs:
# If the job has priority set to 0, it will inherit the pipeline's priority. Default: 10.
priority: 1
- # Consume any payload type (not only Jobs structured)
- #
- # Default: false
- consume_all: false
-
# Durable queue
#
# Default: false
@@ -1476,11 +1461,6 @@ jobs:
# Default: 1
tube_priority: 1
- # Consume any payload type (not only Jobs structured)
- #
- # Default: false
- consume_all: false
-
# Tube name
#
# Default: default
@@ -1512,11 +1492,6 @@ jobs:
# Default: 10
prefetch: 10
- # Consume any payload type (not only Jobs structured)
- #
- # Default: false
- consume_all: false
-
# Get queue URL only
#
# Default: false
@@ -1578,11 +1553,6 @@ jobs:
# Messages to read into the channel
prefetch: 100
- # Consume any payload type (not only Jobs structured)
- #
- # Default: false
- consume_all: false
-
# NATS subject
#
# Default: default
@@ -1951,18 +1921,17 @@ tcp:
# Default: CRLF (\r\n)
delimiter: "\r\n"
- # Chunks that RR uses to read the data. In MB. If you expect big payloads on a TCP server, to reduce `read` syscalls, would be a good practice to use a fairly big enough buffer.
- #
- # Default: 1MB
- read_buf_size: 1
server2:
addr: 127.0.0.1:8811
- read_buf_size: 10
server3:
addr: 127.0.0.1:8812
delimiter: "\r\n"
- read_buf_size: 1
+ # Chunks that RR uses to read the data. In MB. If you expect big payloads on a TCP server, to reduce `read` syscalls, would be a good practice to use a fairly big enough buffer.
+ #
+ # Default: 1MB
+ read_buf_size: 10
+ # The worker pool to use for the TCP service.
pool:
# Debug mode for the pool. In this mode, pool will not pre-allocate the worker. Worker (only 1, num_workers ignored) will be allocated right after the request arrived.
#
diff --git a/schemas/config/3.0.schema.json b/schemas/config/3.0.schema.json
index 5f135d52..185c79d9 100644
--- a/schemas/config/3.0.schema.json
+++ b/schemas/config/3.0.schema.json
@@ -2,9 +2,11 @@
"$id": "https://raw.githubusercontent.com/roadrunner-server/roadrunner/refs/heads/master/schemas/config/3.0.schema.json",
"$schema": "https://json-schema.org/draft/2019-09/schema",
"title": "RoadRunner Main Configuration File",
- "description": "This is your main RoadRunner configuration file. It contains all the plugins you want to load and their configuration.",
+ "description": "This is your main RoadRunner configuration file. It should contain all the plugins you want to load and their configuration.",
"type": "object",
- "minProperties": 1,
+ "required": [
+ "version"
+ ],
"properties": {
"version": {
"description": "RoadRunner configuration file version.",
@@ -14,1483 +16,71 @@
"3"
]
},
+ "amqp": {
+ "$ref": "https://raw.githubusercontent.com/roadrunner-server/amqp/refs/heads/master/schema.json#/definitions/driver"
+ },
+ "beanstalk": {
+ "$ref": "https://raw.githubusercontent.com/roadrunner-server/beanstalk/refs/heads/master/schema.json#/definitions/driver"
+ },
"centrifuge": {
- "description": "Centrifugo server plugin. See https://centrifugal.dev/docs",
- "type": "object",
- "additionalProperties": false,
- "properties": {
- "proxy_address": {
- "description": "The address of the Centrifugo proxy server.",
- "type": "string",
- "default": "tcp://127.0.0.1:30000"
- },
- "grpc_api_address": {
- "description": "The address/port of the gRPC server API.",
- "type": "string",
- "default": "tcp://127.0.0.1:30000"
- },
- "use_compressor": {
- "description": "Whether to use gRPC gzip compressor.",
- "type": "boolean",
- "default": false
- },
- "version": {
- "description": "Your application version.",
- "type": "string",
- "default": "v1.0.0"
- },
- "name": {
- "description": "Your application name",
- "type": "string",
- "default": "roadrunner"
- },
- "pool": {
- "$ref": "#/definitions/WorkersPool"
- },
- "tls": {
- "description": "TLS settings",
- "type": "object",
- "additionalProperties": false,
- "properties": {
- "cert": {
- "$ref": "#/definitions/TLSCertFile"
- },
- "key": {
- "$ref": "#/definitions/TLSKeyFile"
- }
- },
- "required": [
- "cert",
- "key"
- ]
- }
- }
+ "$ref": "https://raw.githubusercontent.com/roadrunner-server/centrifuge/refs/heads/master/schema.json"
},
- "rpc": {
- "type": "object",
- "additionalProperties": false,
- "properties": {
- "listen": {
- "description": "The address and port for the RPC server to bind to.",
- "type": "string",
- "default": "tcp://127.0.0.1:6001",
- "examples": [
- "tcp://127.0.0.1:6001"
- ],
- "pattern": "^tcp:\/\/[0-9a-zA-Z_.-]+:[0-9]{1,5}$"
- }
- }
+ "fileserver": {
+ "$ref": "https://raw.githubusercontent.com/roadrunner-server/fileserver/refs/heads/master/schema.json"
},
- "server": {
- "type": "object",
- "additionalProperties": false,
- "properties": {
- "on_init": {
- "description": "Arbitrary command to execute before RR starts allocating workers.",
- "type": "object",
- "additionalProperties": false,
- "required": [
- "command"
- ],
- "properties": {
- "command": {
- "description": "Command to execute. It can be any script or binary.",
- "type": "string",
- "examples": [
- "php not-worker.php",
- "sh script.sh",
- "start script.bat"
- ]
- },
- "exec_timeout": {
- "description": "Script execution timeout.",
- "$ref": "#/definitions/Duration",
- "default": "60s"
- },
- "user": {
- "description": "Username (not UID) of the user from whom the on_init command is executed. The RR process user will be used if not provided.",
- "type": "string",
- "examples": [
- "www-data"
- ]
- },
- "env": {
- "description": "Environment variables for the executed command.",
- "$ref": "#/definitions/HashmapString"
- }
- }
- },
- "command": {
- "description": "The command used to start workers, including any required arguments.",
- "type": "string",
- "examples": [
- "php psr-worker.php"
- ]
- },
- "user": {
- "description": "User name (not UID) for the worker processes. The RR process user will be used if not provided.",
- "type": "string",
- "examples": [
- "www-data"
- ]
- },
- "group": {
- "description": "Group name (not GID) for the worker processes. The RR process user group will be used if not provided.",
- "type": "string",
- "examples": [
- "www-data"
- ]
- },
- "env": {
- "description": "Environment variables for the worker processes.",
- "$ref": "#/definitions/HashmapString"
- },
- "relay": {
- "description": "Worker relay method. Can be 'pipes', a TCP address (e.g. tcp://127.0.0.1:6002) or a socket (e.g. unix:///var/run/rr.sock).",
- "type": "string",
- "default": "pipes",
- "examples": [
- "pipes",
- "tcp://127.0.0.1:6002",
- "unix:///var/run/rr.sock"
- ]
- }
- },
- "required": [
- "command"
- ]
+ "grpc": {
+ "$ref": "https://raw.githubusercontent.com/roadrunner-server/grpc/refs/heads/master/schema.json"
},
- "logs": {
- "type": "object",
- "additionalProperties": false,
- "properties": {
- "mode": {
- "$ref": "#/definitions/LogMode",
- "default": "development"
- },
- "level": {
- "$ref": "#/definitions/LogLevel",
- "default": "debug"
- },
- "line_ending": {
- "$ref": "#/definitions/LogLineEnding"
- },
- "encoding": {
- "$ref": "#/definitions/LogEncoding",
- "default": "console"
- },
- "output": {
- "description": "Output",
- "$ref": "#/definitions/LogOutput",
- "default": "stderr"
- },
- "err_output": {
- "description": "Errors only output",
- "$ref": "#/definitions/LogOutput",
- "default": "stderr"
- },
- "channels": {
- "description": "You can configure logging for each plugin individually. The key is the plugin name and the value is logging options in same format as the parent.",
- "type": "object",
- "additionalProperties": {
- "type": "object",
- "additionalProperties": false,
- "properties": {
- "mode": {
- "$ref": "#/definitions/LogMode"
- },
- "level": {
- "$ref": "#/definitions/LogLevel"
- },
- "line_ending": {
- "$ref": "#/definitions/LogLineEnding"
- },
- "encoding": {
- "$ref": "#/definitions/LogEncoding"
- },
- "output": {
- "$ref": "#/definitions/LogOutput"
- },
- "err_output": {
- "$ref": "#/definitions/LogOutput"
- }
- }
- }
- },
- "file_logger_options": {
- "description": "File logger options.",
- "type": "object",
- "additionalProperties": false,
- "properties": {
- "log_output": {
- "type": "string",
- "description": "Path to the log file. Uses <processname>-lumberjack.log and the OS temp (i.e. `/tmp`) directory if empty."
- },
- "max_size": {
- "type": "integer",
- "description": "Maximum file size in MB.",
- "minimum": 0,
- "default": 100
- },
- "max_age": {
- "type": "integer",
- "description": "The maximum number of days to retain old log files based on the timestamp encoded in their filename.",
- "default": 1
- },
- "max_backups": {
- "type": "integer",
- "description": "The maximum number of old log files to retain. Set to zero to retain all log files.",
- "default": 5
- },
- "compress": {
- "type": "boolean",
- "description": "Whether to compress log files.",
- "default": false
- }
- }
- }
- }
+ "http": {
+ "$ref": "https://raw.githubusercontent.com/roadrunner-server/http/refs/heads/master/schema.json"
},
- "temporal": {
- "description": "Workflow and activity mesh service. See https://docs.temporal.io/docs/php/introduction/",
- "type": "object",
- "additionalProperties": false,
- "properties": {
- "address": {
- "description": "Address of the Temporal server.",
- "type": "string",
- "default": "127.0.0.1:7233"
- },
- "cache_size": {
- "description": "Sticky cache size. Sticky workflow execution is the affinity between workflow tasks of a specific workflow execution to a specific worker. The benefit of sticky execution is that the workflow does not have to reconstruct state by replaying history from the beginning. The cache is shared between workers running within same process. This must be called before any worker is started. If not called, the default size of 10K (which may change) will be used.",
- "type": "integer",
- "default": 10000
- },
- "namespace": {
- "description": "Namespace name for this client to work with.",
- "type": "string",
- "default": "default"
- },
- "metrics": {
- "description": "Temporal metrics.",
- "type": "object",
- "default": null,
- "properties": {
- "driver": {
- "description": "Metrics driver to use.",
- "type": "string",
- "enum": [
- "prometheus",
- "statsd"
- ],
- "default": "prometheus"
- }
- },
- "anyOf": [
- {
- "type": "object",
- "properties": {
- "address": {
- "description": "Server metrics address",
- "type": "string",
- "default": "127.0.0.1:9091"
- },
- "type": {
- "type": "string",
- "description": "Metrics type",
- "anyOf": [
- {
- "type": "string",
- "examples": [
- "summary",
- "histogram"
- ]
- }
- ]
- },
- "prefix": {
- "description": "Temporal metrics prefix",
- "type": "string",
- "default": null
- }
- }
- },
- {
- "properties": {
- "host_port": {
- "description": "The host and port of the statsd server",
- "type": "string",
- "default": "127.0.0.1:8125"
- },
- "prefix": {
- "description": "The prefix to use in reporting to statsd",
- "type": "string",
- "default": null
- },
- "flush_interval": {
- "description": "FlushInterval is the maximum interval for sending packets",
- "type": "string",
- "default": "1s"
- },
- "flush_bytes": {
- "description": "FlushBytes specifies the maximum udp packet size you wish to send. If FlushBytes is unspecified, it defaults to 1432 bytes, which is considered safe for local traffic.",
- "type": "integer",
- "default": 1432
- },
- "tags": {
- "description": "Hashmap with tag:value values",
- "$ref": "#/definitions/HashmapString"
- },
- "tag_prefix": {
- "description": "Prefix for the tag",
- "type": "string",
- "default": null
- },
- "tag_separator": {
- "description": "TagSeparator allows tags to be appended with a separator. If not specified tag keys and values are embedded to the stat name directly.",
- "type": "string",
- "default": null
- }
- }
- }
- ]
- },
- "activities": {
- "description": "Activities pool settings",
- "type": "object",
- "$ref": "#/definitions/WorkersPool"
- },
- "tls": {
- "description": "Temporal TLS configuration",
- "type": "object",
- "required": [
- "key",
- "cert"
- ],
- "properties": {
- "key": {
- "$ref": "#/definitions/TLSKeyFile"
- },
- "cert": {
- "$ref": "#/definitions/TLSCertFile"
- },
- "root_ca": {
- "$ref": "#/definitions/TLSCAFile"
- },
- "client_auth_type": {
- "$ref": "#/definitions/TLSClientAuthType"
- },
- "server_name": {
- "description": "ServerName is used to verify the hostname on the returned certificates unless InsecureSkipVerify is given. It is also included in the client's handshake to support virtual hosting unless it is an IP address.",
- "type": "string"
- }
- }
- }
- }
+ "jobs": {
+ "$ref": "https://raw.githubusercontent.com/roadrunner-server/jobs/refs/heads/master/schema.json"
+ },
+ "kafka": {
+ "$ref": "https://raw.githubusercontent.com/roadrunner-server/kafka/refs/heads/master/schema.json#/definitions/driver"
},
"kv": {
"$ref": "https://raw.githubusercontent.com/roadrunner-server/kv/refs/heads/master/schema.json"
},
- "service": {
- "description": "Service plugin settings",
- "type": "object",
- "patternProperties": {
- "^[a-zA-Z0-9._-]+$": {
- "description": "User defined services",
- "type": "object",
- "$ref": "#/definitions/Service"
- }
- }
+ "logs": {
+ "$ref": "https://raw.githubusercontent.com/roadrunner-server/logger/refs/heads/master/schema.json"
},
- "otel": {
- "description": "OpenTelemetry configuration",
- "type": "object",
- "additionalProperties": false,
- "properties": {
- "resource": {
- "type": "object",
- "additionalProperties": false,
- "properties": {
- "service_name": {
- "description": "The name of the service.",
- "type": "string",
- "default": "RoadRunner",
- "minLength": 1
- },
- "service_version": {
- "type": "string",
- "description": "The version of the service.",
- "default": "1.0.0",
- "minLength": 1
- },
- "service_namespace": {
- "type": "string",
- "description": "The namespace of the service.",
- "default": "RoadRunner",
- "minLength": 1
- },
- "service_instance_id": {
- "type": "string",
- "description": "The service instance ID. If not provided or empty, a UUID is generated.",
- "minLength": 1
- }
- }
- },
- "insecure": {
- "description": "Use insecure endpoint",
- "type": "boolean",
- "default": false
- },
- "compress": {
- "description": "Use gzip compressor",
- "type": "boolean",
- "default": false
- },
- "exporter": {
- "description": "Provides functionality to emit telemetry to consumers",
- "type": "string",
- "enum": [
- "zipkin",
- "stdout",
- "stderr",
- "otlp",
- "jaeger",
- "jaeger_agent"
- ]
- },
- "custom_url": {
- "description": "Used for the http client to override the default URL, if provided.",
- "type": "string"
- },
- "endpoint": {
- "description": "Consumer's endpoint",
- "type": "string",
- "default": "127.0.0.1:4318"
- },
- "client": {
- "description": "Client to send the spans",
- "type": "string",
- "enum": [
- "http",
- "grpc"
- ]
- },
- "service_name": {
- "description": "User's service name",
- "type": "string",
- "default": "RoadRunner"
- },
- "service_version": {
- "description": "User's service version",
- "type": "string",
- "default": "1.0.0"
- },
- "headers": {
- "description": "User defined headers",
- "$ref": "#/definitions/HashmapString"
- }
- }
+ "metrics": {
+ "$ref": "https://raw.githubusercontent.com/roadrunner-server/metrics/refs/heads/master/schema.json"
},
- "http": {
- "type": "object",
- "additionalProperties": false,
- "properties": {
- "address": {
- "description": "Host and port to listen on.",
- "$ref": "#/definitions/HostAndPort",
- "examples": [
- "127.0.0.1:8080",
- ":8080"
- ]
- },
- "internal_error_code": {
- "description": "The HTTP status code to use for internal roadrunner errors.",
- "type": "integer",
- "default": 500,
- "minimum": 100,
- "maximum": 599
- },
- "max_request_size": {
- "description": "Maximal incoming request size in MB. Zero means no limit.",
- "type": "integer",
- "minimum": 0,
- "default": 0
- },
- "raw_body": {
- "description": "Whether to send the raw, encoded body for application/x-www-form-urlencoded content. By default, PHP workers will receive decoded content of this type.",
- "type": "boolean",
- "default": false
- },
- "access_logs": {
- "description": "Whether to enable HTTP access logs.",
- "type": "boolean",
- "default": false
- },
- "middleware": {
- "description": "Middlewares to load for the HTTP plugin. The order determines the order in which the middlewares are executed.",
- "type": "array",
- "minItems": 1,
- "items": {
- "type": "string",
- "enum": [
- "headers",
- "gzip",
- "static",
- "sendfile",
- "http_metrics",
- "cache",
- "proxy_ip_parser",
- "otel"
- ]
- }
- },
- "trusted_subnets": {
- "description": "Allow incoming requests only from the provided subnets. Defaults to the usual private network ranges (192.168.*, 10.0.* and 172.16.*) as well as local/loopback interfaces (127.*).",
- "type": "array",
- "items": {
- "type": "string",
- "examples": [
- "10.0.0.0/8",
- "127.0.0.0/8"
- ]
- },
- "default": [
- "10.0.0.0/8",
- "127.0.0.0/8",
- "172.16.0.0/12",
- "192.168.0.0/16",
- "::1/128",
- "fc00::/7",
- "fe80::/10"
- ]
- },
- "uploads": {
- "type": "object",
- "additionalProperties": false,
- "properties": {
- "dir": {
- "description": "Directory for file uploads. Empty/undefined value means the OS default temporary directory ($TEMP) will be used, i.e. `/tmp`.",
- "type": "string",
- "examples": [
- "/tmp"
- ]
- },
- "forbid": {
- "description": "Disallow upload of files with the provided extensions.",
- "type": "array",
- "items": {
- "type": "string",
- "minLength": 1,
- "examples": [
- ".php",
- ".exe"
- ]
- },
- "default": [
- ".php",
- ".exe",
- ".bat"
- ]
- },
- "allow": {
- "description": "Allow only upload of files with the provided extensions. Empty/undefined value means all files except explicitly disallowed (`forbid`) files are allowed.",
- "type": "array",
- "items": {
- "type": "string",
- "examples": [
- ".html",
- ".go"
- ]
- }
- }
- }
- },
- "headers": {
- "description": "HTTP headers map",
- "type": "object",
- "additionalProperties": false,
- "properties": {
- "cors": {
- "description": "Controls which CORS headers are returned. Additional headers `Vary: Origin`, `Vary: Access-Control-Request-Method` and `Vary: Access-Control-Request-Headers` will be added to responses. Omit this section to disable CORS headers.",
- "type": "object",
- "properties": {
- "allowed_origin": {
- "description": "Controls the value of 'Access-Control-Allow-Origin'.",
- "type": "string",
- "examples": [
- "*"
- ]
- },
- "allowed_origin_regex": {
- "description": "Controls the value of 'Access-Control-Allow-Origin' header value, but evaluated as regex.",
- "type": "string",
- "examples": [
- "^https://foo"
- ]
- },
- "allowed_headers": {
- "description": "Controls the value of 'Access-Control-Allow-Headers'.",
- "type": "string",
- "examples": [
- "*"
- ]
- },
- "allowed_methods": {
- "description": "Controls the value of 'Access-Control-Allow-Methods'. Provide a comma-separated string of HTTP verbs.",
- "type": "string",
- "examples": [
- "GET,POST,PUT,DELETE"
- ]
- },
- "allow_credentials": {
- "description": "Controls the value of 'Access-Control-Allow-Credentials'.",
- "type": "boolean",
- "default": false
- },
- "exposed_headers": {
- "description": "Controls the value of 'Access-Control-Expose-Headers'. Provide a comma-separated list of HTTP headers.",
- "type": "string",
- "examples": [
- "Cache-Control,Content-Language,Content-Type,Expires,Last-Modified,Pragma"
- ]
- },
- "max_age": {
- "description": "Controls the value of 'Access-Control-Max-Age' (in seconds).",
- "type": "integer",
- "examples": [
- 600
- ],
- "default": 0
- }
- }
- },
- "request": {
- "description": "Headers to add to every request passed to PHP.",
- "$ref": "#/definitions/HashmapString"
- },
- "response": {
- "description": "Headers added to every response.",
- "$ref": "#/definitions/HashmapString"
- }
- }
- },
- "static": {
- "description": "Configuratin options for serving static files.",
- "type": "object",
- "additionalProperties": false,
- "properties": {
- "dir": {
- "description": "Path to the directory with static assets. Defaults to the current working directory. Empty/undefined and `.` are equal and are both treated as current directory.",
- "type": "string",
- "examples": [
- ".",
- "/var/www/html"
- ]
- },
- "forbid": {
- "description": "File extensions of files that must not be served. Empty/undefined disallows no files. If files are specified in both `forbid` and `allow`, they will be disallowed. Defaults to an empty array, disallowing no files.",
- "type": "array",
- "items": {
- "type": "string",
- "minLength": 1,
- "examples": [
- ".php",
- ".htaccess",
- ".sh"
- ]
- }
- },
- "allow": {
- "description": "File extensions of files that may be served. Empty/undefined allows all files, except files specified in `forbid`.",
- "type": "array",
- "items": {
- "type": "string",
- "minLength": 1,
- "examples": [
- ".jpg",
- ".png",
- ".css",
- ".js"
- ]
- }
- },
- "calculate_etag": {
- "description": "Whether to enable ETag computation for static files.",
- "type": "boolean",
- "default": false
- },
- "weak": {
- "description": "Whether to use a weak generator (/W), which uses only the filename to generate a CRC32 sum for et ETag. Disable to use the file contents.",
- "type": "boolean",
- "default": false
- },
- "response": {
- "description": "Custom HTTP headers to add to responses to requests for static files.",
- "$ref": "#/definitions/HashmapString"
- },
- "request": {
- "description": "Custom HTTP headers to add to requests for static files.",
- "$ref": "#/definitions/HashmapString"
- }
- }
- },
- "pool": {
- "description": "Settings for workers in the HTTP pool.",
- "$ref": "#/definitions/WorkersPool"
- },
- "ssl": {
- "title": "SSL/TLS (HTTPS) Configuration",
- "description": "Settings required to set up manual or automatic HTTPS for your server. Either `key` and `cert` *or* `acme` is required, but not both.",
- "type": "object",
- "additionalProperties": false,
- "not": {
- "anyOf": [
- {
- "required": [
- "key",
- "acme"
- ]
- },
- {
- "required": [
- "cert",
- "acme"
- ]
- },
- {
- "required": [
- "root_ca",
- "acme"
- ]
- },
- {
- "required": [
- "client_auth_type",
- "acme"
- ]
- }
- ]
- },
- "anyOf": [
- {
- "required": [
- "acme"
- ]
- },
- {
- "required": [
- "key",
- "cert"
- ]
- }
- ],
- "properties": {
- "address": {
- "description": "Host address (or port) to bind to.",
- "$ref": "#/definitions/HostAndPort",
- "examples": [
- "127.0.0.1:443",
- ":8443"
- ]
- },
- "acme": {
- "description": "ACME certificates provider (Let's encrypt). Do not specify this parameter if you use `key` and `cert`.",
- "type": "object",
- "additionalProperties": false,
- "properties": {
- "certs_dir": {
- "description": "Directory to use for certificates, private keys, Let's Encrypt configuration etc.",
- "type": "string",
- "default": "rr_cache"
- },
- "email": {
- "description": "User email used to create a Let's Encrypt account. This is required.",
- "type": "string",
- "examples": [
- ]
- },
- "alt_http_port": {
- "description": "Alternate port for the HTTP challenge. Challenge traffic should be redirected to this port if overridden. See https://letsencrypt.org/docs/challenge-types/#http-01-challenge",
- "type": "integer",
- "default": 80
- },
- "alt_tlsalpn_port": {
- "description": "Alternate port for the TLS-ALPN-01 challenge. Challenge traffic should be redirected to this port if overridden. See https://letsencrypt.org/docs/challenge-types/#tls-alpn-01",
- "type": "integer",
- "default": 443
- },
- "challenge_type": {
- "type": "string",
- "enum": [
- "http-01",
- "tlsalpn-01"
- ],
- "description": "Challenge types",
- "default": "http-01"
- },
- "use_production_endpoint": {
- "description": "Whether to use the production endpoint. We recommend you use the staging endpoint to make sure everything works correctly before you deploy your certificate.",
- "type": "boolean",
- "default": false
- },
- "domains": {
- "type": "array",
- "minItems": 1,
- "items": {
- "type": "string",
- "examples": [
- "example.com"
- ]
- },
- "description": "List of domains to obtain certificates for. At least one domain is required."
- }
- },
- "required": [
- "domains",
- "email"
- ]
- },
- "redirect": {
- "description": "Whether to automatically redirect from HTTP to HTTPS.",
- "type": "boolean",
- "default": false
- },
- "cert": {
- "$ref": "#/definitions/TLSCertFile"
- },
- "key": {
- "$ref": "#/definitions/TLSKeyFile"
- },
- "root_ca": {
- "$ref": "#/definitions/TLSCAFile"
- },
- "client_auth_type": {
- "$ref": "#/definitions/TLSClientAuthType"
- }
- },
- "required": [
- "address"
- ]
- },
- "fcgi": {
- "description": "FastCGI frontend support",
- "type": "object",
- "additionalProperties": false,
- "properties": {
- "address": {
- "description": "FastCGI connection DSN. Supports TCP and Unix sockets. An empty value disables this.",
- "type": "string",
- "examples": [
- "tcp://0.0.0.0:7921"
- ]
- }
- },
- "required": [
- "address"
- ]
- },
- "http2": {
- "description": "HTTP/2 settings",
- "type": "object",
- "additionalProperties": false,
- "properties": {
- "h2c": {
- "description": "Use HTTP/2 over non-encrypted TCP connection using H2C",
- "type": "boolean",
- "default": false
- },
- "max_concurrent_streams": {
- "description": "Maximal concurrent streams.",
- "type": "integer",
- "default": 128,
- "minimum": 0
- }
- }
- }
- },
- "required": [
- "address"
- ]
+ "nats": {
+ "$ref": "https://raw.githubusercontent.com/roadrunner-server/nats/refs/heads/master/schema.json#/definitions/driver"
+ },
+ "otel": {
+ "$ref": "https://raw.githubusercontent.com/roadrunner-server/otel/refs/heads/master/schema.json"
},
"redis": {
"$ref": "https://raw.githubusercontent.com/roadrunner-server/redis/refs/heads/master/schema.json"
},
- "metrics": {
- "description": "Application metrics in Prometheus format (docs: https://roadrunner.dev/docs/beep-beep-metrics)",
- "type": "object",
- "properties": {
- "address": {
- "description": "Prometheus client address (path /metrics added automatically).",
- "type": "string",
- "default": "127.0.0.1:2112"
- },
- "collect": {
- "description": "Application-specific metrics (published using an RPC connection to the server)",
- "type": "object",
- "patternProperties": {
- "^[a-zA-Z0-9._-]+$": {
- "type": "object",
- "properties": {
- "type": {
- "type": "string",
- "enum": [
- "histogram",
- "gauge",
- "counter",
- "summary"
- ]
- },
- "help": {
- "type": "string",
- "description": "Help message"
- },
- "labels": {
- "type": "array",
- "minItems": 1,
- "description": "Metrics labels"
- },
- "buckets": {
- "type": "array",
- "items": {
- "type": "number"
- }
- },
- "objectives": {
- "title": "map[float]float",
- "type": "array",
- "items": {
- "type": "object",
- "additionalProperties": {
- "type": "number"
- }
- }
- }
- }
- }
- }
- }
- }
- },
- "status": {
- "description": "Health check endpoint (docs: https://roadrunner.dev/docs/beep-beep-health). If response code is 200 - it means at least one worker ready to serve requests. 500 - there are no workers ready to service requests.",
- "type": "object",
- "properties": {
- "address": {
- "description": "Host and port to listen on (eg.: `127.0.0.1:2114`). Use the following URL: http://127.0.0.1:2114/health?plugin=http. Multiple plugins must be separated using & - http://127.0.0.1:2114/health?plugin=http&plugin=rpc where http and rpc are active (connected) plugins.",
- "type": "string",
- "examples": [
- "127.0.0.1:2114"
- ]
- },
- "unavailable_status_code": {
- "description": "Response status code if a requested plugin not ready to handle requests. Valid for both /health and /ready endpoints",
- "type": "integer",
- "default": 503
- }
- },
- "required": [
- "address"
- ]
- },
- "reload": {
- "description": "Automatically detect PHP file changes and reload connected services",
- "type": "object",
- "properties": {
- "interval": {
- "description": "Sync interval",
- "$ref": "#/definitions/Duration",
- "default": "1s"
- },
- "patterns": {
- "description": "Global patterns to sync",
- "type": "array",
- "items": {
- "type": "string",
- "examples": [
- ".php",
- ".json"
- ]
- },
- "default": [
- ".php"
- ]
- },
- "services": {
- "description": "List of included for sync services (this is a map, where key name is a plugin name)",
- "type": "object",
- "minProperties": 0,
- "patternProperties": {
- "^[a-zA-Z0-9._-]+$": {
- "type": "object",
- "properties": {
- "dirs": {
- "description": "Directories to sync. If recursive is set to true, recursive sync will be applied only to the directories in 'dirs' section. Dot (.) means 'current working directory'",
- "type": "array",
- "default": [],
- "items": {
- "type": "string",
- "examples": [
- ".",
- "/app/src"
- ],
- "minLength": 1
- }
- },
- "recursive": {
- "description": "Recursive search for file patterns to add",
- "type": "boolean",
- "default": false
- },
- "ignore": {
- "description": "Ignored folders",
- "type": "array",
- "default": [],
- "items": {
- "type": "string",
- "examples": [
- "vendor",
- "/app/logs"
- ],
- "minLength": 1
- }
- },
- "patterns": {
- "description": "Service specific file pattens to sync",
- "type": "array",
- "default": [],
- "items": {
- "type": "string",
- "examples": [
- ".php",
- ".go",
- ".md"
- ],
- "minLength": 1
- }
- }
- }
- }
- },
- "additionalProperties": false
- }
- }
- },
- "nats": {
- "$ref": "https://raw.githubusercontent.com/roadrunner-server/nats/refs/heads/master/schema.json#/definitions/driver"
+ "rpc": {
+ "$ref": "https://raw.githubusercontent.com/roadrunner-server/rpc/refs/heads/master/schema.json"
},
- "kafka": {
- "$ref": "https://raw.githubusercontent.com/roadrunner-server/kafka/refs/heads/master/schema.json#/definitions/driver"
+ "server": {
+ "$ref": "https://raw.githubusercontent.com/roadrunner-server/server/refs/heads/master/schema.json"
},
- "amqp": {
- "$ref": "https://raw.githubusercontent.com/roadrunner-server/amqp/refs/heads/master/schema.json#/definitions/driver"
+ "service": {
+ "$ref": "https://raw.githubusercontent.com/roadrunner-server/service/refs/heads/master/schema.json"
},
- "beanstalk": {
- "$ref": "https://raw.githubusercontent.com/roadrunner-server/beanstalk/refs/heads/master/schema.json#/definitions/driver"
+ "status": {
+ "$ref": "https://raw.githubusercontent.com/roadrunner-server/status/refs/heads/master/schema.json"
},
"sqs": {
"$ref": "https://raw.githubusercontent.com/roadrunner-server/sqs/refs/heads/master/schema.json#/definitions/driver"
},
- "jobs": {
- "$ref": "https://raw.githubusercontent.com/roadrunner-server/jobs/refs/heads/master/schema.json"
+ "temporal": {
+ "$ref": "https://raw.githubusercontent.com/temporalio/roadrunner-temporal/refs/heads/master/schema.json"
},
"tcp": {
- "type": "object",
- "description": "Plugin to handle RAW TCP packets.",
- "additionalProperties": false,
- "properties": {
- "servers": {
- "description": "TCP servers to allocate",
- "type": "object",
- "minProperties": 1,
- "patternProperties": {
- "^[a-zA-Z0-9._-]+$": {
- "$ref": "#/definitions/TCPServers"
- }
- }
- },
- "pool": {
- "$ref": "#/definitions/WorkersPool"
- }
- }
- },
- "grpc": {
- "description": "GRPC plugin",
- "type": "object",
- "additionalProperties": false,
- "required": [
- "proto"
- ],
- "properties": {
- "listen": {
- "description": "GRPC address to listen on.",
- "type": "string",
- "$ref": "#/definitions/HostAndPortWithTCP"
- },
- "proto": {
- "type": "array",
- "description": "Proto file to use. Multiple files are supported. Wildcards are allowed in the proto field.",
- "items": {
- "type": "string",
- "examples": [
- "*.proto",
- "first.proto",
- "second.proto"
- ]
- }
- },
- "tls": {
- "description": "GRPC TLS configuration",
- "type": "object",
- "additionalProperties": false,
- "properties": {
- "key": {
- "$ref": "#/definitions/TLSKeyFile"
- },
- "cert": {
- "$ref": "#/definitions/TLSCertFile"
- },
- "root_ca": {
- "$ref": "#/definitions/TLSCAFile"
- },
- "client_auth_type": {
- "$ref": "#/definitions/TLSClientAuthType"
- }
- },
- "required": [
- "key",
- "cert"
- ]
- },
- "max_send_msg_size": {
- "type": "integer",
- "description": "Maximum send message size in MB.",
- "default": 50
- },
- "max_recv_msg_size": {
- "description": "Maximum receive message size in MB.",
- "default": 50,
- "type": "integer"
- },
- "max_connection_idle": {
- "description": " MaxConnectionIdle is a duration for the amount of time after which an idle connection would be closed by sending a GoAway. Idle duration is defined by the most recent time the number of outstanding RPCs became zero or since the connection was established.",
- "$ref": "#/definitions/Duration"
- },
- "max_connection_age": {
- "description": "The maximum duration a connection may exist before it will be closed by sending a GoAway. A random jitter of +/-10% will be added to MaxConnectionAge to spread out connection storms.",
- "$ref": "#/definitions/Duration"
- },
- "max_connection_age_grace": {
- "description": "The duration after MaxConnectionAge after which the connection will be forcibly closed.",
- "$ref": "#/definitions/Duration"
- },
- "max_concurrent_streams": {
- "description": "The maximum number of concurrent streams.",
- "type": "integer",
- "default": 10
- },
- "ping_time": {
- "description": "Duration of no activity after which the server pings the client to see if the transport is still alive. If set below 1s, a minimum value of 1s will be used instead.",
- "$ref": "#/definitions/Duration",
- "default": "2h"
- },
- "timeout": {
- "description": "The duration to wait for a response to a keepalive check, after which the connection is closed.",
- "$ref": "#/definitions/Duration",
- "default": "20s"
- },
- "pool": {
- "description": "GRPC workers pool",
- "type": "object",
- "$ref": "#/definitions/WorkersPool"
- }
- }
- },
- "fileserver": {
- "description": "File server to serve static files.",
- "type": "object",
- "additionalProperties": false,
- "properties": {
- "address": {
- "description": "The address to listen on.",
- "type": "string",
- "examples": [
- "127.0.0.1:10101"
- ]
- },
- "calculate_etag": {
- "description": "Whether to calculate ETag for the file and add the ETag header. See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag",
- "type": "boolean",
- "default": false
- },
- "weak": {
- "description": "Whether to use only the filename when calculating the ETag value. If `false`, the entire file content is used.",
- "default": false
- },
- "stream_request_body": {
- "type": "boolean",
- "description": "Whether to stream files larger than 4KB.",
- "default": false
- },
- "serve": {
- "description": "The URL prefixes to serve as static files. At least one entry is required.",
- "type": "array",
- "minItems": 1,
- "items": {
- "type": "object",
- "properties": {
- "prefix": {
- "description": "Files matching this prefix will be served with this configuration.",
- "type": "string",
- "examples": [
- "/img",
- "/assets"
- ]
- },
- "root": {
- "description": "Directory to serve these files from. Defaults to the root of the RR application directory.",
- "default": ".",
- "type": "string"
- },
- "compress": {
- "description": "When set to true, the server attempts to minimize CPU usage by caching compressed files.",
- "type": "boolean",
- "default": false
- },
- "cache_duration": {
- "description": "Expiration duration for inactive file handlers, given in seconds. Use any negative number (-1) to disable.",
- "type": "integer",
- "default": 10
- },
- "max_age": {
- "description": "The value for the Cache-Control HTTP-header, given in seconds.",
- "type": "integer",
- "default": 10
- },
- "bytes_range": {
- "description": "Enable range requests. See https://developer.mozilla.org/en-US/docs/Web/HTTP/Range_requests",
- "type": "boolean",
- "default": false
- }
- },
- "required": [
- "prefix"
- ]
- }
- }
- }
+ "$ref": "https://raw.githubusercontent.com/roadrunner-server/tcp/refs/heads/master/schema.json"
}
},
- "required": [
- "version"
- ],
"definitions": {
- "TLSCAFile": {
- "description": "Path to the CA certificate, if required. Always required for mTLS. Omit this option if unused.",
- "type": "string",
- "minLength": 1,
- "examples": [
- "/ssl/server/ca.crt"
- ]
- },
- "TLSCertFile": {
- "description": "Path to the public certificate file.",
- "type": "string",
- "minLength": 1,
- "examples": [
- "/ssl/server/cert.crt"
- ]
- },
- "TLSKeyFile": {
- "description": "Path to the private key for the certificate.",
- "type": "string",
- "minLength": 1,
- "examples": [
- "/ssl/server/key.pem"
- ]
- },
- "TLSClientAuthType": {
- "description": "Authorization method for mTLS.",
- "type": "string",
- "default": "no_client_certs",
- "enum": [
- "request_client_cert",
- "require_any_client_cert",
- "verify_client_cert_if_given",
- "no_client_certs",
- "require_and_verify_client_cert"
- ]
- },
- "Service": {
- "type": "object",
- "description": "User defined service",
- "additionalProperties": false,
- "properties": {
- "command": {
- "description": "Command to execute. Can be any command here which can be executed.",
- "type": "string"
- },
- "env": {
- "description": "Environment variables for the process.",
- "type": "object",
- "$ref": "#/definitions/HashmapString"
- },
- "timeout_stop_sec": {
- "description": "Timeout for the process stop operation. If it takes longer for this duration for the process to stop, it will be killed.",
- "type": "integer",
- "default": 5
- },
- "process_num": {
- "description": "Number of copies (processes) to start per command execution.",
- "type": "integer",
- "default": 1
- },
- "exec_timeout": {
- "description": "The maximum duration the service is allowed to run before RR will kill it. Default/zero means unlimited.",
- "type": "string",
- "$ref": "#/definitions/Duration",
- "default": "0s"
- },
- "remain_after_exit": {
- "description": "Whether to restart the process if it exists, regardless of the exit code.",
- "type": "boolean",
- "default": false
- },
- "restart_sec": {
- "description": "Number of seconds to wait before process restart",
- "type": "integer",
- "default": 30
- },
- "service_name_in_log": {
- "description": "Whether to include the name of the service in logs (e.g. service.some_service_1).",
- "type": "boolean",
- "default": false
- }
- },
- "required": [
- "command"
- ]
- },
- "WorkersPool": {
- "description": "Static pool with PHP workers.",
- "type": "object",
- "additionalProperties": false,
- "properties": {
- "debug": {
- "description": "Pool debug mode. A worker will be created right before RR passes a request to it.",
- "type": "boolean",
- "default": false
- },
- "command": {
- "type": "string",
- "description": "Command to use for the pool. If provided, this will override the value of server.command for the pool."
- },
- "num_workers": {
- "description": "The number of worker processes to start. Default/zero means the number of logical CPUs.",
- "type": "integer",
- "minimum": 0,
- "default": 0
- },
- "max_jobs": {
- "description": "The maximum number of executions a worker is allowed to perform. Zero (or nothing) means no limit. When this value is reached, the worker is terminated and a new is created.",
- "type": "integer",
- "minimum": 0,
- "default": 0
- },
- "max_queue_size": {
- "description": "Maximum size of the internal request queue. After reaching this limit, additional requests will be rejected with an error.",
- "type": "integer",
- "minimum": 0,
- "default": 0
- },
- "allocate_timeout": {
- "description": "Timeout for worker allocation. Default/zero means 60s.",
- "$ref": "#/definitions/Duration",
- "default": "60s"
- },
- "reset_timeout": {
- "description": "Timeout for the pool.Reset operation (./rr reset). Default/zero means 60s.",
- "$ref": "#/definitions/Duration",
- "default": "60s"
- },
- "stream_timeout": {
- "description": "Timeout for stream cancellation. Default/zero means 60s.",
- "$ref": "#/definitions/Duration",
- "default": "60s"
- },
- "destroy_timeout": {
- "description": "Timeout when destroying a worker. If the worker has stopped within this timeout, its process will be killed. Default/zero means 60s.",
- "$ref": "#/definitions/Duration",
- "default": "60s"
- },
- "supervisor": {
- "description": "Supervisor is used to control HTTP workers, such as restarting them and limiting their memory consumption or execution time.",
- "type": "object",
- "additionalProperties": false,
- "properties": {
- "watch_tick": {
- "description": "How often to check the state of the workers. Defaults to 1 second.",
- "$ref": "#/definitions/Duration",
- "default": "1s"
- },
- "ttl": {
- "description": "The maximum time the worker is allowed to live (soft limit). Default/zero means no limit. If the worker is processing a request while this expires, it will be restarted after it has completed its work.",
- "$ref": "#/definitions/Duration",
- "default": "0s"
- },
- "idle_ttl": {
- "description": "How long worker can spend in idle mode after its first request (soft limit). Default/zero means no limit.",
- "$ref": "#/definitions/Duration",
- "default": "0s"
- },
- "max_worker_memory": {
- "description": "The maximum amount of memory a worker is allowed to allocate in MB (soft limit). If a worker exceeds this limit during a request, it will be terminated and restarted once the request ends. Default/zero means no limit.",
- "type": "integer",
- "minimum": 0,
- "default": 0,
- "examples": [
- 256
- ]
- },
- "exec_ttl": {
- "description": "The maximum time a request may take in seconds (hard limit). Default/zero means no limit.",
- "$ref": "#/definitions/Duration",
- "default": "0s"
- }
- }
- }
- }
- },
- "TCPServers": {
- "description": "TCP server",
- "type": "object",
- "additionalProperties": false,
- "properties": {
- "addr": {
- "description": "Address to listen on.",
- "type": "string",
- "pattern": "^[0-9a-zA-Z_.-]+:[0-9]{1,5}$",
- "examples": [
- "127.0.0.1:7778"
- ]
- },
- "delimiter": {
- "description": "Data packet delimiter. Every send should end with either EOF or this delimiter.",
- "type": "string",
- "default": "\r\n"
- },
- "read_buf_size": {
- "description": "Size of the chunks that RR reads data in, in MB. If you expect big payloads on a TCP server, you may reduce `read` system calls by using a big buffer.",
- "type": "integer",
- "minimum": 1,
- "maximum": 100,
- "default": 1
- }
- },
- "required": [
- "addr"
- ]
- },
"Duration": {
"description": "Time duration",
"type": "string",
@@ -1505,78 +95,6 @@
"300ms",
"1h3m40s500ms"
]
- },
- "HostAndPortWithTCP": {
- "description": "Host and port with tcp:// prefix",
- "type": "string",
- "pattern": "^(((tcp://[0-9a-zA-Z_.-]+|)|\\$\\{([^}]+)\\}):([0-9]{1,5}|\\$\\{([^}]+)\\}))|\\$\\{([^}]+)\\}$",
- "examples": [
- "tcp://127.0.0.1:443",
- "${TCP:-tcp://127.0.0.1:443}",
- "tcp://127.0.0.1:${TCP_PORT}"
- ]
- },
- "HostAndPort": {
- "description": "Host and port",
- "type": "string",
- "pattern": "^((([0-9a-zA-Z_.-]+|)|\\$\\{([^}]+)\\}):([0-9]{1,5})|\\$\\{([^}]+)\\})|\\$\\{([^}]+)\\}$",
- "examples": [
- "127.0.0.1:443",
- ":8080",
- "0.0.0.0:${HTTP_PORT:-8080}",
- "${HTTP_HOST:-127.0.0.1:8000}"
- ]
- },
- "LogMode": {
- "description": "Logging mode",
- "type": "string",
- "enum": [
- "development",
- "production",
- "raw"
- ]
- },
- "LogLevel": {
- "description": "Logging level",
- "type": "string",
- "enum": [
- "debug",
- "info",
- "warn",
- "error",
- "panic"
- ]
- },
- "LogEncoding": {
- "description": "Encoding format",
- "type": "string",
- "enum": [
- "console",
- "json"
- ]
- },
- "LogLineEnding": {
- "description": "Line-ending to use for logging.",
- "type": "string",
- "default": "\n"
- },
- "LogOutput": {
- "type": "string",
- "examples": [
- "stdout",
- "stderr",
- "/var/log/rr_errors.log"
- ]
- },
- "HashmapString": {
- "description": "A hash map that only allows string values.",
- "type": "object",
- "patternProperties": {
- "^[a-zA-Z0-9._-]+$": {
- "type": "string"
- }
- },
- "additionalProperties": false
}
}
}
diff --git a/schemas/package-lock.json b/schemas/package-lock.json
new file mode 100644
index 00000000..b7da7f75
--- /dev/null
+++ b/schemas/package-lock.json
@@ -0,0 +1,108 @@
+{
+ "name": "roadrunner-schema-tests",
+ "version": "1.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "roadrunner-schema-tests",
+ "version": "1.0.0",
+ "license": "ISC",
+ "dependencies": {
+ "@apidevtools/json-schema-ref-parser": "^11.7.2",
+ "ajv": "^8.17.1",
+ "js-yaml": "^4.1.0"
+ }
+ },
+ "node_modules/@apidevtools/json-schema-ref-parser": {
+ "version": "11.7.2",
+ "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-11.7.2.tgz",
+ "integrity": "sha512-4gY54eEGEstClvEkGnwVkTkrx0sqwemEFG5OSRRn3tD91XH0+Q8XIkYIfo7IwEWPpJZwILb9GUXeShtplRc/eA==",
+ "license": "MIT",
+ "dependencies": {
+ "@jsdevtools/ono": "^7.1.3",
+ "@types/json-schema": "^7.0.15",
+ "js-yaml": "^4.1.0"
+ },
+ "engines": {
+ "node": ">= 16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/philsturgeon"
+ }
+ },
+ "node_modules/@jsdevtools/ono": {
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz",
+ "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==",
+ "license": "MIT"
+ },
+ "node_modules/@types/json-schema": {
+ "version": "7.0.15",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
+ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
+ "license": "MIT"
+ },
+ "node_modules/ajv": {
+ "version": "8.17.1",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
+ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3",
+ "fast-uri": "^3.0.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "license": "Python-2.0"
+ },
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "license": "MIT"
+ },
+ "node_modules/fast-uri": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.3.tgz",
+ "integrity": "sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/js-yaml": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+ "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/json-schema-traverse": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+ "license": "MIT"
+ },
+ "node_modules/require-from-string": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
+ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ }
+ }
+}
diff --git a/schemas/package.json b/schemas/package.json
new file mode 100644
index 00000000..92c25eb3
--- /dev/null
+++ b/schemas/package.json
@@ -0,0 +1,16 @@
+{
+ "name": "roadrunner-schema-tests",
+ "version": "1.0.0",
+ "main": "test.js",
+ "type": "module",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "author": "",
+ "license": "ISC",
+ "dependencies": {
+ "@apidevtools/json-schema-ref-parser": "^11.7.2",
+ "ajv": "^8.17.1",
+ "js-yaml": "^4.1.0"
+ }
+}
diff --git a/schemas/readme.md b/schemas/readme.md
index 43dff920..656a7788 100644
--- a/schemas/readme.md
+++ b/schemas/readme.md
@@ -4,13 +4,9 @@ This directory contains public schemas for the most important parts of applicati
**Do not rename or remove this directory or any file or directory inside.**
-- You can validate existing config file using the following command:
+- You can validate existing config file using the following command from the project root.
```bash
-docker run --rm -v "$(pwd):/src" -w "/src" node:20-alpine sh -c \
- "npm install -g ajv-cli && \
- ajv validate --all-errors --verbose \
- -s ./schemas/config/3.0.schema.json \
- --spec=draft2019 \
- -d ./.rr*.y*ml"
+docker run --rm -v "$(pwd):/src" -w "/src" node:22-alpine sh -c \
+ "cd schemas && npm install && node test.js"
```
diff --git a/schemas/test.js b/schemas/test.js
new file mode 100644
index 00000000..cd469c3a
--- /dev/null
+++ b/schemas/test.js
@@ -0,0 +1,39 @@
+import $RefParser from "@apidevtools/json-schema-ref-parser";
+import Ajv2019 from "ajv/dist/2019.js"
+import fs from 'fs';
+import yaml from 'js-yaml';
+
+function stripIds(schema, first) {
+ if (schema !== null && typeof schema === 'object') {
+ if (!first) {
+ // Every referenced schema we pull in should have its $id and $schema stripped, or ajv complains
+ // Skip the root object, as that should retain the $schema and $id
+ delete schema.$id;
+ delete schema.$schema;
+ }
+ for (const key in schema) {
+ if (Object.hasOwn(schema, key)) {
+ stripIds(schema[key], false);
+ }
+ }
+ }
+}
+
+// Load the main schema and all its referenced schemas
+const dereferenced = await $RefParser.dereference('./config/3.0.schema.json');
+
+// Remove $id and $schema from anything but the root
+stripIds(dereferenced, true);
+
+const ajv = new Ajv2019({strict: true, allErrors: true})
+const validator = ajv.compile(dereferenced)
+
+const data = fs.readFileSync('../.rr.yaml', 'utf-8');
+const schema = yaml.load(data);
+
+// Validate the file
+if (!validator(schema)) {
+ throw new Error(JSON.stringify(validator.errors, null, 2))
+} else {
+ console.log('No errors found in schemas.')
+}