Skip to content
streamneo.
Setup Guides12 min read

YouTube Stream Key in Docker FFmpeg: Environment Variable Setup

Pass YouTube's current stream key to Docker FFmpeg safely by matching your image's variable, building the output URL and checking RTMPS.

sn.
StreamNeoPublished 4 October 2026
Worth sharing?

To pass a YouTube stream key to FFmpeg in Docker, retrieve the current ingestion URL and key from YouTube Live Control Room, then pass them into the container under names that its image or startup script expects. Docker, FFmpeg and YouTube do not define one universal environment-variable name for this purpose; the command that starts FFmpeg must read the configured value and use it in the output destination.

The important detail is the hand-off: a variable in a Compose file does not configure FFmpeg by itself. Your image, wrapper or entrypoint has to consume it, combine it with the correct current destination, and keep the credential out of files and logs that other people can see.

Get the current YouTube URL and key

Open the live setup for the channel in YouTube Live Control Room and copy the current stream key and ingestion URL shown for the stream. YouTube’s RTMPS help instructions direct you to retrieve the RTMPS URL there as well. Do not rely on a URL copied from an old tutorial: account settings, stream configuration and the destination selected for an encoder can change.

A stream key is entered by an encoder as part of the publishing destination. Treat it like a credential: someone who has access to it may be able to publish to the associated stream. Do not paste a working value into an issue report, a public code sample or a committed configuration file. Use placeholders in documentation and examples.

If you use the YouTube Live Streaming API rather than copying values in the interface, its LiveStreams reference describes ingestion information including the ingestion URL and stream name. Those fields can be represented separately in an encoder, or combined when the encoder expects one destination. Follow the actual values and format supplied for your stream, not a static endpoint from a sample.

It helps to record the non-secret parts separately from the key: which channel or broadcast you are configuring, whether you selected a primary or backup address, and whether the encoder expects a separate name/key field or a combined destination. This makes it easier to diagnose a mismatch without copying the credential into notes or a terminal transcript.

Why Docker FFmpeg has no universal key variable

An environment variable is simply a named value available to a process. Docker can pass environment values into a container, and a process inside the container can read them, but neither mechanism assigns a meaning such as “this is the YouTube stream key”. FFmpeg accepts an output destination through its command line; it does not make every arbitrary container variable part of that destination automatically.

The interface is chosen by the software packaging FFmpeg. One image might provide a startup script with documented variables. A Compose project might define a value and expand it into a command. A custom wrapper could use entirely different names, or accept the URL and key as command arguments. A variable named STREAM_KEY only has meaning if something in that particular setup reads it.

This is why copying a variable name from an unrelated image can appear to work while leaving FFmpeg pointed at an incomplete address. The container may start successfully, but the startup command may ignore the value. Conversely, an image may accept a complete destination URL and have no separate key variable at all. Check the documentation or entrypoint for the exact image and tag you run.

The distinction matters when you update an image, replace a wrapper, or move a configuration between machines. A Compose file can be syntactically valid while its variable name no longer matches what the new entrypoint expects. If you are weighing a continuously running encoder against other ways to operate a channel, the practical context in costs of running a 24/7 FFmpeg stream on a NAS can help you think through the machine and maintenance side separately from this credential mapping.

Find the variable expected by your image or wrapper

Start with the image’s own usage instructions and the exact tag or version you plan to deploy. Look for its documented environment-variable names, command examples, entrypoint behaviour and whether it expects a full output URL or separate URL and key values. If you maintain the wrapper yourself, inspect the script that constructs the FFmpeg command and make its input contract explicit.

Then trace the value through each layer. A useful mental model is: a private value source supplies a variable to Compose or docker run; Docker makes it available in the container; the entrypoint reads it; the entrypoint forms FFmpeg’s destination; FFmpeg opens the connection. If any link is missing, defining the variable alone cannot fix it.

For instance, the following is only a schematic Compose pattern, not a universally recognised image setting:

services:
  broadcaster:
    image: example-image:chosen-tag
    environment:
      YOUTUBE_STREAM_KEY: ${YOUTUBE_STREAM_KEY}

The variable name here is illustrative. The host-side substitution and the container-side name both need to match your own deployment, and the image still needs a command that reads the value. Keep the real value out of the YAML committed to a shared repository. Choose a private runtime injection method that fits how you deploy; this is an operational choice for your environment, not a YouTube-prescribed Docker method.

For a custom wrapper, keep the mapping understandable and avoid logging the assembled command if it contains a credential. A script can read the variable and construct a destination at startup, but the precise shell quoting and FFmpeg syntax depend on how the destination is represented. Test the wrapper with placeholders or a non-publishing validation path before supplying the current key. If you do not own the image or script, do not assume that adding a similarly named variable changes its behaviour.

Map configuration into the FFmpeg output URL

The output sent to FFmpeg must contain the correct ingestion destination and stream name/key in the form expected by the encoder. The API documentation describes the URL and stream name as distinct fields; depending on the encoder, they can be entered separately or joined as STREAM_URL/STREAM_NAME. Check whether your selected FFmpeg wrapper expects a complete destination or builds one from separate inputs. Do not append the key twice.

A safe way to reason about the command is to name the parts without showing a credential: current RTMPS ingestion URL, separator if the documented format requires one, and current stream name/key. Then compare the resulting shape with the image’s example. An illustrative shell construction might look like this:

DESTINATION="${INGEST_URL}/${YOUTUBE_STREAM_KEY}"
exec ffmpeg [your input and encoding options] "$DESTINATION"

This is a pattern to explain the mapping, not a tested command. Some ingestion URLs may already include the relevant path or expect a separate field, so confirm the documented format before adding a separator. The exact FFmpeg input, encoding and output options depend on the media source and the image. The important point is that the wrapper passes the completed destination to FFmpeg; a declaration in Compose does not do that work by itself.

Prefer the current RTMPS ingestion address when your encoder supports it. YouTube describes RTMPS as RTMP over a TLS/SSL connection, which encrypts the connection. Google’s RTMPS implementation guide specifies the rtmps URL scheme, port 443 and hostname use for SNI authentication. The guide was last updated 2026-09-14 UTC, so check it and the current Live Control Room values when troubleshooting protocol details.

Choice What changes Practical check
RTMPS rather than RTMP RTMPS carries RTMP over TLS/SSL; the endpoint and connection requirements differ. Use the current RTMPS address, confirm the rtmps scheme and ensure the client supports it.
Separate URL and key/name The wrapper passes fields independently if the encoder supports that form. Confirm which field is the ingestion URL and which is the stream name/key.
Combined destination The wrapper joins the URL and name/key into one output destination. Check whether the address already includes a path or name; avoid joining the key twice.

The choice is not a matter of inventing a “Docker format”. Use the representation your selected image or FFmpeg command expects, while keeping the address current and the credential private. If your stream is a long-running music or devotional loop, the encoder configuration is only one part of a reliable setup; for media preparation, see the guide to reducing ProRes files to H.264 for YouTube streaming.

Keep credentials out of public files and logs

Avoid putting a working stream key directly into a Compose file that is committed to a repository, pasted into a public gist, or sent in a support screenshot. Use a placeholder in examples and supply the real value through a private mechanism appropriate to your deployment. The exact mechanism depends on your host, orchestration and access model; the official YouTube material cited here explains stream setup and transport, not Docker secret-management practices.

Environment variables can be convenient, but do not treat a variable as invisible merely because it is not written inline in the YAML. People with access to the host, deployment configuration or container inspection may be able to see configuration values. Limit who can view and change the deployment, and keep copies of the key out of shell history, chat, logs and backup files where practical.

Be particularly careful with diagnostic output. Some wrappers print the complete FFmpeg command on startup, and a complete destination can include the key. Configure diagnostics to show the protocol, host and non-secret context without echoing the credential. Before sharing logs, inspect them for a URL containing the stream name/key and redact it. Avoid using shell tracing for a command that expands a credential, because tracing can print the expanded arguments.

If the key has been exposed in a public place or handed to someone who should no longer publish to that stream, use the current Live Control Room controls to change or replace it, then update the private runtime configuration. Do not assume deleting the visible copy removes it from repository history, caches or logs. This is general credential hygiene, not a guarantee that every copy can be withdrawn.

Check the destination and connection

When FFmpeg cannot connect, first compare the destination assembled by the wrapper with the current values from Live Control Room. Check for a stale URL, a missing path, an extra separator, a blank variable, or a key appended where the address already contains the stream name. Do not paste the full destination into a public terminal transcript while diagnosing it.

For RTMPS, check the scheme, hostname and application path, port 443 and TLS connection. Google’s guide notes the role of the hostname in SNI authentication; a mismatch can lead to TLS errors. YouTube Help advises checking that the URL uses rtmps rather than only rtmp, and suggests specifying port 443 if the address looks right but an SSL error persists. If the encoder times out, verify that the chosen FFmpeg build or wrapper supports RTMPS rather than assuming the key is the cause.

Separate connection failure from stream health. A connection may be established while the incoming stream still has configuration issues. The LiveStreams API health representation includes categories such as low or high bitrate, frame-rate mismatch, absent audio or video, and audio or video codec problems. If you use the API, inspect status and health information; otherwise use the live controls and encoder diagnostics to check whether YouTube receives the expected media.

If you are using a primary and backup ingestion address, do not silently substitute one for the other in a generic script. Keep the selected address explicit and follow the current configuration for your stream. For other FFmpeg publishing issues, the reconnect-error checklist for YouTube live streams is relevant after you have confirmed the destination and protocol are correct.

Test changes without exposing the key

Before a live run, verify the configuration path with placeholders. Confirm that the expected variable reaches the container, that the entrypoint reads it, and that the command it constructs places the destination in the correct FFmpeg output position. You can inspect the non-secret parts of the command and print whether a value is present, rather than printing the value itself. Do not treat a successful placeholder check as proof that YouTube will accept the actual stream.

Make one controlled test using the current values through your private runtime configuration. Watch both the container’s connection result and the YouTube live interface for incoming video and audio. If you need to capture a diagnostic, filter or redact the destination before storing or sharing it. After changing the image, wrapper, URL or variable mapping, repeat the path check; a deployment that used to work can break when one layer changes its expected interface.

A small checklist makes handovers less error-prone:

  • The URL and key were copied from the current stream configuration.
  • The variable name is documented by this image or wrapper, not borrowed from a different example.
  • The startup command consumes the value and passes the correct destination to FFmpeg.
  • The output format does not omit or duplicate the stream name/key.
  • Logs and shared files do not expose the assembled destination.
  • The encoder can use the selected RTMPS endpoint, and the live interface receives the intended audio and video.

This does not guarantee approval, uninterrupted delivery or a healthy stream. It gives you a way to find a broken hand-off without turning a credential leak into part of the debugging process. If you are planning the operational side of a channel beyond the command itself, the discussion of continuous streaming software on a low-cost PC in India can help frame what running an encoder locally involves.

Before committing, compare the operating options on the pricing page. When the file and channel are ready, start free — 24-hour trial, no card.

FAQ

What environment variable should I use for a YouTube stream key?

Use the variable name documented by your Docker image, Compose setup or wrapper script. YouTube and FFmpeg do not provide a universal Docker variable name, and a variable only has an effect if the startup command reads it.

Can I put the stream key in a Compose file?

Avoid committing a working key in a Compose file or public example. Supply it through a private runtime method appropriate to your deployment, and remember that access to host or container configuration may expose environment values.

Should I append the key to the ingestion URL?

That depends on the encoder’s expected destination format. Some accept URL and stream name separately; others expect them joined, so check the current YouTube values and the image’s documentation to avoid omitting or duplicating the name/key.

Why does FFmpeg connect but YouTube still report a problem?

Connection status and stream health are different checks. YouTube’s stream health information can report media issues such as bitrate, frame rate, missing audio or codec configuration even after a connection is established.

YOU’VE REACHED THE END

Keep the ideas coming.

More guides, useful tools and a little help for your next broadcast.

Back to the journal ↗
YOUR NEXT READ

A little more to explore.

More Setup Guides guides ↗ · All topics ↗