23. Service Contract Reference
This page lists the rules a service's files must follow. Break an include or naming rule and enableService.sh stops the container at startup with an ERROR: line. Break a placeholder or auth rule and the container starts but the service misbehaves. For the steps, see Add a Streaming Service.
In the examples, <SERVICE> is the lowercase service name, such as youtube.
23.1 Files
| File | Pattern | Contents | Included from |
|---|---|---|---|
build/conf/nginx/http.d/apps/<SERVICE>.conf |
Simple Relay | Directives only (include http.d/auth.conf;, push ...;) |
Inside application relay |
build/conf/nginx/http.d/apps/<SERVICE>.conf |
Transformer | One application <SERVICE> { ... } block that pushes to the service |
Server level, after application relay |
build/conf/nginx/http.d/transformers/<SERVICE>.conf |
Transformer | One exec ffmpeg ...; directive that publishes to rtmp://127.0.0.1/<SERVICE>/$name |
Inside application relay |
build/scripts/pre-init.d/90_configure_<SERVICE>.sh |
Both | Startup script, executable | Run by build/scripts/run.sh |
Real examples: apps/youtube.conf (Simple Relay), and transformers/twitch.conf with apps/twitch.conf (Transformer).
Every application block must contain include http.d/auth.conf;. An application without it accepts a publish from any address.
23.2 Include Markers
build/conf/nginx/http.d/app.conf ships every service include commented out:
- Write
#includewith no space.enableService.shmatches#include <PATH>;exactly. With# include, with a space, it finds no line to enable and stops the container withERROR: No '#include <PATH>;' line in /etc/nginx/http.d/app.conf. Cannot enable <SERVICE>. - Keep the literal token
NGINX_CONFD_DIR.89_configure_app.shreplaces it with/etc/nginx/http.dbefore any90_script runs, andenableService.shmatches the replaced path. - Put each line where the Files table says it is included from.
23.3 Placeholder Tokens
- A placeholder is a bare uppercase word, named after its variable:
EXAMPLE_KEY, not{EXAMPLE_KEY}.sedreplaces the word and leaves any braces around it. sedreplaces every occurrence, including inside a longer token. If one token contains another, substitute the longer one first.90_configure_twitch.shsubstitutesTWITCH_DOUBLE_FPSbeforeTWITCH_FPSfor this reason.- Values derived from variables, such as a bitrate, are computed in the startup script and substituted like any other token. See
TWITCH_VIDEO_BITRATEin90_configure_twitch.sh. - Escape free-form values, such as stream keys, host names and paths, with
escape_for_sedbefore substituting them. Whitelisted values, such as numbers and identifiers, need no escaping.
23.4 Startup Script
build/scripts/run.sh runs every /scripts/pre-init.d/*sh in glob (alphanumeric) order, then starts nginx.
| Rule | Why |
|---|---|
Name it 90_configure_<SERVICE>.sh, so it sorts after 89_configure_app.sh |
It must run after 89_ has replaced NGINX_CONFD_DIR in app.conf. Before that, the include marker does not match and enableService.sh stops the container |
Start with set -e and source /scripts/validate_input.sh |
Any failing command stops the script |
If the required variable is empty, print <VARIABLE> is not set. Skipping <Service> configuration. and exit 0 |
The service is optional. Docs and tests grep for is not set |
| Validate every variable before using it, and exit 1 on failure | A non-zero exit makes run.sh stop the container, so a bad value never reaches nginx |
Call /scripts/enableService.sh <SERVICE> last, then print <Service> configuration complete, and service enabled. |
Docs and tests grep for service enabled |
Variables from the base image are available to every script: NGINX_CONFD_DIR (/etc/nginx/http.d), NGINX_APP_CONF_FILE (/etc/nginx/http.d/app.conf) and NGINX_RUN_USER (nginx).
23.5 enableService.sh
/scripts/enableService.sh <SERVICE>:
- Exits 1 if no argument is given, or if
apps/<SERVICE>.confdoes not exist:ERROR: /etc/nginx/http.d/apps/<SERVICE>.conf not found. Cannot enable <SERVICE>.A misspelled<SERVICE>fails this way. - Removes the
#from#include /etc/nginx/http.d/apps/<SERVICE>.conf;inapp.conf, then exits 1 ifapp.confhas no activeincludeline for that file. - If
transformers/<SERVICE>.confexists, does the same for its include line.
The startup scripts run with set -e, so any of these failures stops the script, and run.sh stops the container before nginx starts.
The argument must equal the app file's base name. Twitch partner mode uses this rule: enableService.sh twitch-partner enables apps/twitch-partner.conf.
23.6 See Also
- Add a Streaming Service - Step-by-step guide
- Test a New Service - Tests to add for a new service
- Input Validation Reference - Validation functions and what they reject
- Architecture - How the relay processes configuration