<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Frigate on inetshell</title><link>https://inet.sh/en/tags/frigate/</link><description>Recent content in Frigate on inetshell</description><generator>Hugo</generator><language>en</language><lastBuildDate>Mon, 31 Aug 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://inet.sh/en/tags/frigate/index.xml" rel="self" type="application/rss+xml"/><item><title>Frigate with Docker Compose for your cameras</title><link>https://inet.sh/en/posts/frigate/docker-compose/</link><pubDate>Mon, 31 Aug 2026 00:00:00 +0000</pubDate><guid>https://inet.sh/en/posts/frigate/docker-compose/</guid><description>Run Frigate (object-detection NVR) with Docker Compose: the compose file, a config.yml with go2rtc restream, hardware acceleration and a detector. shm_size and internal-port traps.</description><content:encoded><![CDATA[<h2 id="tldr">TL;DR</h2>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">mkdir -p /opt/frigate/config /opt/frigate/media
</span></span><span class="line"><span class="cl"><span class="nb">cd</span> /opt/frigate
</span></span><span class="line"><span class="cl"><span class="c1"># write docker-compose.yml and config/config.yml (below)</span>
</span></span><span class="line"><span class="cl">docker compose up -d
</span></span><span class="line"><span class="cl">docker compose logs -f frigate
</span></span></code></pre></td></tr></table>
</div>
</div><p>Authenticated UI at <code>https://&lt;host&gt;:8971</code>. On first run it prints the generated <code>admin</code> password in the log.</p>
<p>Frigate is an NVR with <strong>real-time object detection</strong> (person, car, animal…) for IP cameras. It runs happily in a container: give it a <code>docker-compose.yml</code>, a <code>config.yml</code> and your cameras&rsquo; RTSP URLs. The rest is tuning shared memory and hardware acceleration.</p>
<h2 id="docker-composeyml">docker-compose.yml</h2>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">services</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">frigate</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">container_name</span><span class="p">:</span><span class="w"> </span><span class="l">frigate</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l">ghcr.io/blakeblackshear/frigate:stable</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">restart</span><span class="p">:</span><span class="w"> </span><span class="l">unless-stopped</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">stop_grace_period</span><span class="p">:</span><span class="w"> </span><span class="l">30s</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">shm_size</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;256mb&#34;</span><span class="w">            </span><span class="c"># raise it per camera count and resolution</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">devices</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">/dev/dri/renderD128     </span><span class="w"> </span><span class="c"># iGPU (VAAPI) for decoding; optional</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># - /dev/bus/usb:/dev/bus/usb   # Coral USB</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># - /dev/apex_0:/dev/apex_0     # Coral PCIe</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">volumes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">/etc/localtime:/etc/localtime:ro</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">./config:/config</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">./media:/media/frigate</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">type</span><span class="p">:</span><span class="w"> </span><span class="l">tmpfs</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">target</span><span class="p">:</span><span class="w"> </span><span class="l">/tmp/cache</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">tmpfs</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">size</span><span class="p">:</span><span class="w"> </span><span class="m">1000000000</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">ports</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="s2">&#34;8971:8971&#34;</span><span class="w">     </span><span class="c"># authenticated UI (use this one)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="s2">&#34;8554:8554&#34;</span><span class="w">     </span><span class="c"># RTSP restream (go2rtc)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="s2">&#34;8555:8555/tcp&#34;</span><span class="w"> </span><span class="c"># WebRTC</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="s2">&#34;8555:8555/udp&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">environment</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">FRIGATE_RTSP_USER</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;${FRIGATE_RTSP_USER}&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">FRIGATE_RTSP_PASSWORD</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;${FRIGATE_RTSP_PASSWORD}&#34;</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><p>Camera credentials live in a <code>.env</code> next to the compose file (never in git):</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl"><span class="c1"># /opt/frigate/.env</span>
</span></span><span class="line"><span class="cl"><span class="nv">FRIGATE_RTSP_USER</span><span class="o">=</span>viewer
</span></span><span class="line"><span class="cl"><span class="nv">FRIGATE_RTSP_PASSWORD</span><span class="o">=</span>change-me
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="configconfigyml">config/config.yml</h2>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">mqtt</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">enabled</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w">        </span><span class="c"># or point it at a mosquitto broker for Home Assistant</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">detectors</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">cpu1</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">type</span><span class="p">:</span><span class="w"> </span><span class="l">cpu          </span><span class="w"> </span><span class="c"># switch to edgetpu (Coral) or tensorrt (NVIDIA)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">ffmpeg</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">hwaccel_args: preset-vaapi   # Intel/AMD iGPU; NVIDIA</span><span class="p">:</span><span class="w"> </span><span class="l">preset-nvidia</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">go2rtc</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">streams</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">door1</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="s2">&#34;rtsp://{FRIGATE_RTSP_USER}:{FRIGATE_RTSP_PASSWORD}@camera-ip:554/stream1&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">cameras</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">door1</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">ffmpeg</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">inputs</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span>- <span class="nt">path</span><span class="p">:</span><span class="w"> </span><span class="l">rtsp://127.0.0.1:8554/door1  </span><span class="w"> </span><span class="c"># single connection via go2rtc</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">roles</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="l">detect, record]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">detect</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">width</span><span class="p">:</span><span class="w"> </span><span class="m">1280</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">height</span><span class="p">:</span><span class="w"> </span><span class="m">720</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">fps</span><span class="p">:</span><span class="w"> </span><span class="m">5</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">objects</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">track</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="l">person, car, dog]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">record</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">enabled</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">retain</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">days</span><span class="p">:</span><span class="w"> </span><span class="m">7</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">snapshots</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">enabled</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><p>Add more cameras by repeating the <code>go2rtc.streams</code> + <code>cameras</code> blocks. Reload with <code>docker compose restart frigate</code>.</p>
<h2 id="what-each-piece-does">What each piece does</h2>
<table>
  <thead>
      <tr>
          <th>Piece</th>
          <th>Purpose</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>shm_size</code></td>
          <td>Frame buffers in <code>/dev/shm</code>. Too small = cameras crash.</td>
      </tr>
      <tr>
          <td><code>go2rtc</code></td>
          <td>Repackages the camera RTSP and serves it on <code>:8554</code>. Frigate reads from there to <strong>detect and record over a single connection</strong> to the camera.</td>
      </tr>
      <tr>
          <td><code>hwaccel_args</code></td>
          <td>Offloads video decode to the GPU/iGPU. Without it the CPU melts.</td>
      </tr>
      <tr>
          <td><code>detectors</code></td>
          <td>Where inference runs: <code>cpu</code> (slow), <code>edgetpu</code> (Coral) or <code>tensorrt</code> (NVIDIA).</td>
      </tr>
      <tr>
          <td>Port <code>8971</code></td>
          <td>UI with login. This is the one you expose.</td>
      </tr>
      <tr>
          <td><code>record</code> / <code>snapshots</code></td>
          <td>Write to <code>./media</code>. Retention decides how much disk you burn.</td>
      </tr>
  </tbody>
</table>
<h2 id="traps">Traps</h2>
<ul>
<li><strong>Small <code>shm_size</code> → cameras that restart themselves.</strong> Rough per-camera rule: <code>(width*height*1.5*9 + 270480) / 1048576</code> MB; sum all cameras and leave a base. A few 1080p cameras will blow past 64–128 MB.</li>
<li><strong>Do not expose port 5000.</strong> It&rsquo;s the <strong>unauthenticated internal API</strong>. The public UI is <code>8971</code> (with login). Keep <code>5000</code> on loopback / an internal network only.</li>
<li><strong>Use the go2rtc restream.</strong> Putting the camera RTSP straight into both <code>detect</code> and <code>record</code> opens two connections to the sensor; many cheap cameras can&rsquo;t take it. Detect and record from <code>rtsp://127.0.0.1:8554/&lt;cam&gt;</code>.</li>
<li><strong>Detect at low resolution.</strong> <code>detect</code> at 1280×720 and 5 fps is plenty; record the high stream separately if your camera has two.</li>
<li><strong>Hardware acceleration or 100% CPU.</strong> <code>preset-vaapi</code> (Intel/AMD) or <code>preset-nvidia</code>; the <code>/dev/dri</code> device (or the NVIDIA runtime) must be mapped in.</li>
<li><strong>A detector isn&rsquo;t really optional.</strong> The <code>cpu</code> detector is fine to smoke-test, but past one or two cameras you want Coral or TensorRT.</li>
</ul>
<h2 id="see-also">See also</h2>
<ul>
<li>Official docs: <a href="https://docs.frigate.video/">https://docs.frigate.video/</a></li>
</ul>
]]></content:encoded></item></channel></rss>