HermitBlogs/docs/owncast.nix.html

568 lines
15 KiB
HTML
Raw Normal View History

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="generator" content="pandoc" />
<meta http-equiv="X-UA-Compatible" content="IE=EDGE" />
<meta name="author" content="Hertog" />
<meta name="date" content="2023-10-27" />
<title>Setting Up Owncast with NixOS</title>
<script src="site_libs/header-attrs-2.25/header-attrs.js"></script>
<script src="site_libs/jquery-3.6.0/jquery-3.6.0.min.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link href="site_libs/bootstrap-3.3.5/css/bootstrap.min.css" rel="stylesheet" />
<script src="site_libs/bootstrap-3.3.5/js/bootstrap.min.js"></script>
<script src="site_libs/bootstrap-3.3.5/shim/html5shiv.min.js"></script>
<script src="site_libs/bootstrap-3.3.5/shim/respond.min.js"></script>
<style>h1 {font-size: 34px;}
h1.title {font-size: 38px;}
h2 {font-size: 30px;}
h3 {font-size: 24px;}
h4 {font-size: 18px;}
h5 {font-size: 16px;}
h6 {font-size: 12px;}
code {color: inherit; background-color: rgba(0, 0, 0, 0.04);}
pre:not([class]) { background-color: white }</style>
<script src="site_libs/jqueryui-1.13.2/jquery-ui.min.js"></script>
<link href="site_libs/tocify-1.9.1/jquery.tocify.css" rel="stylesheet" />
<script src="site_libs/tocify-1.9.1/jquery.tocify.js"></script>
<script src="site_libs/navigation-1.1/tabsets.js"></script>
<style type="text/css">
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
div.column{display: inline-block; vertical-align: top; width: 50%;}
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
ul.task-list{list-style: none;}
</style>
<link rel="stylesheet" href="main.css" type="text/css" />
<style type = "text/css">
.main-container {
max-width: 940px;
margin-left: auto;
margin-right: auto;
}
img {
max-width:100%;
}
.tabbed-pane {
padding-top: 12px;
}
.html-widget {
margin-bottom: 20px;
}
button.code-folding-btn:focus {
outline: none;
}
summary {
display: list-item;
}
details > summary > p:only-child {
display: inline;
}
pre code {
padding: 0;
}
</style>
<style type="text/css">
.dropdown-submenu {
position: relative;
}
.dropdown-submenu>.dropdown-menu {
top: 0;
left: 100%;
margin-top: -6px;
margin-left: -1px;
border-radius: 0 6px 6px 6px;
}
.dropdown-submenu:hover>.dropdown-menu {
display: block;
}
.dropdown-submenu>a:after {
display: block;
content: " ";
float: right;
width: 0;
height: 0;
border-color: transparent;
border-style: solid;
border-width: 5px 0 5px 5px;
border-left-color: #cccccc;
margin-top: 5px;
margin-right: -10px;
}
.dropdown-submenu:hover>a:after {
border-left-color: #adb5bd;
}
.dropdown-submenu.pull-left {
float: none;
}
.dropdown-submenu.pull-left>.dropdown-menu {
left: -100%;
margin-left: 10px;
border-radius: 6px 0 6px 6px;
}
</style>
<script type="text/javascript">
// manage active state of menu based on current page
$(document).ready(function () {
// active menu anchor
href = window.location.pathname
href = href.substr(href.lastIndexOf('/') + 1)
if (href === "")
href = "index.html";
var menuAnchor = $('a[href="' + href + '"]');
// mark the anchor link active (and if it's in a dropdown, also mark that active)
var dropdown = menuAnchor.closest('li.dropdown');
if (window.bootstrap) { // Bootstrap 4+
menuAnchor.addClass('active');
dropdown.find('> .dropdown-toggle').addClass('active');
} else { // Bootstrap 3
menuAnchor.parent().addClass('active');
dropdown.addClass('active');
}
// Navbar adjustments
var navHeight = $(".navbar").first().height() + 15;
var style = document.createElement('style');
var pt = "padding-top: " + navHeight + "px; ";
var mt = "margin-top: -" + navHeight + "px; ";
var css = "";
// offset scroll position for anchor links (for fixed navbar)
for (var i = 1; i <= 6; i++) {
css += ".section h" + i + "{ " + pt + mt + "}\n";
}
style.innerHTML = "body {" + pt + "padding-bottom: 40px; }\n" + css;
document.head.appendChild(style);
});
</script>
<!-- tabsets -->
<style type="text/css">
.tabset-dropdown > .nav-tabs {
display: inline-table;
max-height: 500px;
min-height: 44px;
overflow-y: auto;
border: 1px solid #ddd;
border-radius: 4px;
}
.tabset-dropdown > .nav-tabs > li.active:before, .tabset-dropdown > .nav-tabs.nav-tabs-open:before {
content: "\e259";
font-family: 'Glyphicons Halflings';
display: inline-block;
padding: 10px;
border-right: 1px solid #ddd;
}
.tabset-dropdown > .nav-tabs.nav-tabs-open > li.active:before {
content: "\e258";
font-family: 'Glyphicons Halflings';
border: none;
}
.tabset-dropdown > .nav-tabs > li.active {
display: block;
}
.tabset-dropdown > .nav-tabs > li > a,
.tabset-dropdown > .nav-tabs > li > a:focus,
.tabset-dropdown > .nav-tabs > li > a:hover {
border: none;
display: inline-block;
border-radius: 4px;
background-color: transparent;
}
.tabset-dropdown > .nav-tabs.nav-tabs-open > li {
display: block;
float: none;
}
.tabset-dropdown > .nav-tabs > li {
display: none;
}
</style>
<!-- code folding -->
<style type="text/css">
#TOC {
margin: 25px 0px 20px 0px;
}
@media (max-width: 768px) {
#TOC {
position: relative;
width: 100%;
}
}
@media print {
.toc-content {
/* see https://github.com/w3c/csswg-drafts/issues/4434 */
float: right;
}
}
.toc-content {
padding-left: 30px;
padding-right: 40px;
}
div.main-container {
max-width: 1200px;
}
div.tocify {
width: 20%;
max-width: 260px;
max-height: 85%;
}
@media (min-width: 768px) and (max-width: 991px) {
div.tocify {
width: 25%;
}
}
@media (max-width: 767px) {
div.tocify {
width: 100%;
max-width: none;
}
}
.tocify ul, .tocify li {
line-height: 20px;
}
.tocify-subheader .tocify-item {
font-size: 0.90em;
}
.tocify .list-group-item {
border-radius: 0px;
}
.tocify-subheader {
display: inline;
}
.tocify-subheader .tocify-item {
font-size: 0.95em;
}
</style>
</head>
<body>
<div class="container-fluid main-container">
<!-- setup 3col/9col grid for toc_float and main content -->
<div class="row">
<div class="col-xs-12 col-sm-4 col-md-3">
<div id="TOC" class="tocify">
</div>
</div>
<div class="toc-content col-xs-12 col-sm-8 col-md-9">
<div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-bs-toggle="collapse" data-target="#navbar" data-bs-target="#navbar">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="index.html">HermitCollective Blogs</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
HermitCollective
<span class="caret"></span>
</a>
<ul class="dropdown-menu" role="menu">
<li>
<a href="https://hermitcollective.net/">Main Site</a>
</li>
<li>
<a href="https://live.hermitcollective.net/">Live Streams</a>
</li>
<li>
<a href="https://cloud.hermitcollective.net/">HermitCloud</a>
</li>
<li>
<a href="https://feeds.hermitcollective.net/">HermitFeeds</a>
</li>
</ul>
</li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
Blog Posts
<span class="caret"></span>
</a>
<ul class="dropdown-menu" role="menu">
<li>
<a href="./owncast.nix.html">owncast.nix</a>
</li>
</ul>
</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li>
<a href="https://git.saragerretsen.nl/Hertog/HermitBlogs">Source</a>
</li>
</ul>
</div><!--/.nav-collapse -->
</div><!--/.container -->
</div><!--/.navbar -->
<div id="header">
<h1 class="title toc-ignore">Setting Up Owncast with NixOS</h1>
<h4 class="author"><a
href="https://hertog.hermitcollective.net">Hertog</a></h4>
<h4 class="date">2023-10-27</h4>
</div>
<div id="what-is-owncast" class="section level2">
<h2>What is Owncast?</h2>
<p><a href="https://owncast.online/">Owncast</a> is a lightweight
program to set up your own livestreaming website as an alternative to
streaming on twitch or youtube.</p>
<p>It is fully free and open source licensed under the <a
href="https://mit-license.org/">MIT license</a> and can even be linked
with the <a
href="https://en.wikipedia.org/wiki/Fediverse">fediverse!</a></p>
<p>Which to me is perfect! I really wanted to get back into
livestreaming (I used to do this on twitch allot) but I wanted a
platform without adds or corporate influence and thus owncast.</p>
</div>
<div id="as-for-nixos" class="section level2">
<h2>As for NixOS</h2>
<p>I use NixOS to selfhost everything I can (including this website!)
but I couldnt find any wiki pages or concrete owncast configurations
online, I did eventually get it working and will share my configuration
here.</p>
<div id="the-owncast-part-of-the-config" class="section level3">
<h3>The Owncast part of the config</h3>
<p>This part is the easiest it is simply enabling it setting an unused
port (the default and recommended is 8080) and then let owncast open
that part of the firewall.</p>
<pre><code>services.owncast = {
enable = true;
port = 8080;
openFirewall = true;
};</code></pre>
</div>
<div id="the-nginx-part" class="section level3">
<h3>The nginx part!</h3>
<p>Nginx is needed to setup a proxy so we can link owncast to our domain
and ensure everything will run securely. We begin by setting the
(sub)domain that we wish to point at owncast and we enable SSL and ACME.
The locations part needs to point at the port we set earlier so that
nginx knows to point at owncast. Owncast also needs websockets so we set
that to true as wel, the extra config is to ensure our proxy works.</p>
<pre><code> services.nginx.virtualHosts.&quot;live.hermitcollective.net&quot; = {
forceSSL = true;
enableACME = true;
locations.&quot;/&quot; = {
proxyPass = &quot;http://localhost:8080&quot;;
proxyWebsockets = true; # needed if you need to use WebSocket
extraConfig =
# required when the target is also TLS server with multiple hosts
&quot;proxy_ssl_server_name on;&quot; +
# required when the server wants to use HTTP Authentication
&quot;proxy_pass_header Authorization;&quot;
;
};
};</code></pre>
</div>
<div id="the-full-config-and-some-extra-information"
class="section level3">
<h3>The full config and some extra information</h3>
<p>Your entire config should look something like this now at which point
you can sudo nixos-rebuild switch!:</p>
<pre><code>{ config, pkgs, ... }:
{
services.owncast = {
enable = true;
port = 8080;
openFirewall = true;
};
# Homepages
services.nginx.virtualHosts.&quot;yourdomain.net&quot; = {
forceSSL = true;
enableACME = true;
locations.&quot;/&quot; = {
proxyPass = &quot;http://localhost:8080&quot;;
proxyWebsockets = true; # needed if you need to use WebSocket
extraConfig =
# required when the target is also TLS server with multiple hosts
&quot;proxy_ssl_server_name on;&quot; +
# required when the server wants to use HTTP Authentication
&quot;proxy_pass_header Authorization;&quot;
;
};
};
}</code></pre>
<p>We are not done yet however there is one more this that is required
on the nixos side of things and quite a few things in your owncast
webpage.</p>
<p>While we did setup nginx for this owncast we didnt do a full nginx
setup, this is because in my homeserver nginx is used for many things
and I want to avoid duplicate nix code so I have a separate nginx config
which can be found <a
href="https://git.saragerretsen.nl/Hertog/HermitCollective.nix/src/branch/main/services/nginx.nix">here</a>.</p>
<p>Now that that is done we can go into our owncast web page at <a
href="https://yourdomain.net/admin"
class="uri">https://yourdomain.net/admin</a>. Here it will ask you to
log in the default for this is Username: Admin and Password: abc123 you
want to replace this as soon as possible! Luckely there is the owncast
admin page you just logged into for that, either hit view next to
streaming keys in the home page or head to Stream Keys in Server Setup
under the Configuration tab.</p>
<p>When you are done with that open your favourite streaming application
set the livestreaming service to custom and use this link <a
href="rtmp://yourdomain.net:1935/live"
class="uri">rtmp://yourdomain.net:1935/live</a> with the streamkey you
just set!</p>
</div>
<div id="further-help" class="section level3">
<h3>Further help</h3>
<p>If you need extra configuring (and know what you are doing) more
owncast options can be found <a
href="https://search.nixos.org/options?channel=unstable&amp;from=0&amp;size=50&amp;sort=relevance&amp;type=packages&amp;query=owncast">here</a>
and the owncast documentation can be found <a
href="https://owncast.online/docs/">here</a>. Is your version not up to
date with Nix pkgs? run <code>nix-channel --update</code>. Lastely if
this guide gets out of date my current owncast config can be found <a
href="https://git.saragerretsen.nl/Hertog/HermitCollective.nix/src/branch/main/services/owncast.nix">here</a>.</p>
</div>
</div>
</div>
</div>
</div>
<script>
// add bootstrap table styles to pandoc tables
function bootstrapStylePandocTables() {
$('tr.odd').parent('tbody').parent('table').addClass('table table-condensed');
}
$(document).ready(function () {
bootstrapStylePandocTables();
});
</script>
<!-- tabsets -->
<script>
$(document).ready(function () {
window.buildTabsets("TOC");
});
$(document).ready(function () {
$('.tabset-dropdown > .nav-tabs > li').click(function () {
$(this).parent().toggleClass('nav-tabs-open');
});
});
</script>
<!-- code folding -->
<script>
$(document).ready(function () {
// temporarily add toc-ignore selector to headers for the consistency with Pandoc
$('.unlisted.unnumbered').addClass('toc-ignore')
// move toc-ignore selectors from section div to header
$('div.section.toc-ignore')
.removeClass('toc-ignore')
.children('h1,h2,h3,h4,h5').addClass('toc-ignore');
// establish options
var options = {
selectors: "h1,h2",
theme: "bootstrap3",
context: '.toc-content',
hashGenerator: function (text) {
return text.replace(/[.\\/?&!#<>]/g, '').replace(/\s/g, '_');
},
ignoreSelector: ".toc-ignore",
scrollTo: 0
};
options.showAndHide = false;
options.smoothScroll = true;
// tocify
var toc = $("#TOC").tocify(options).data("toc-tocify");
});
</script>
<!-- dynamically load mathjax for compatibility with self-contained -->
<script>
(function () {
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "https://mathjax.rstudio.com/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML";
document.getElementsByTagName("head")[0].appendChild(script);
})();
</script>
</body>
</html>