screentinker/frontend/guides/self-hosted-digital-signage.html
ScreenTinker 25ab1c485b SEO: add meta tags, sitemap, robots.txt, comparison pages, guides, internal linking
Landing page (frontend/landing.html):
- Title now includes "Self-Hosted" for that keyword
- Description appended "MIT licensed."
- Keywords aligned to spec (digital signage raspberry pi, digital
  signage android tv, video wall software, kiosk software, etc.)
- SoftwareApplication JSON-LD: added applicationSubCategory
  "DigitalSignage", license URL, refreshed description
- Image alt text + og:image:alt + twitter:image:alt now include
  "open-source digital signage"
- New Resources section above the CTA with 6 cards linking to all
  new guides and comparison pages
- Footer rewritten as a 5-column grid (Brand / Guides / Compare /
  Project / Legal) with the new internal links

New SEO pages, all dark-themed, mobile-responsive, ASCII-only:
- frontend/css/seo-page.css (shared nav/footer/article/table styles)
- frontend/compare/yodeck-alternative.html
- frontend/compare/screencloud-alternative.html
- frontend/compare/optisigns-alternative.html
- frontend/guides/raspberry-pi-digital-signage.html
- frontend/guides/digital-signage-android-tv.html
- frontend/guides/self-hosted-digital-signage.html

Each new page has unique title/description/canonical, OG and Twitter
card tags, BreadcrumbList JSON-LD, single h1, proper h2/h3 nesting,
visible breadcrumb, comparison table or step-by-step ordered list,
"Related guides" cross-link block, and a CTA.

Sitemap (frontend/sitemap.xml): added all 6 new URLs with appropriate
priority (0.8 for compare pages, 0.9 for guides). Existing landing
(1.0) and legal pages preserved.

Robots (frontend/robots.txt): allow /compare/ and /guides/, disallow
/player (was previously allowed by mistake).

Server (server/server.js): added explicit GET /sitemap.xml and
GET /robots.txt routes ahead of the static middleware so the
Content-Type is guaranteed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 20:54:32 -05:00

197 lines
11 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Self-Hosted Digital Signage Software - Complete Guide (2026) | ScreenTinker</title>
<meta name="description" content="Why and how to self-host your digital signage CMS. Data privacy, cost control, and no recurring fees. Complete deployment guide using ScreenTinker - open source, MIT licensed.">
<meta name="keywords" content="self hosted digital signage, on premise digital signage, self hosted signage cms, open source signage server, deploy signage on premise, private digital signage">
<meta name="robots" content="index, follow">
<link rel="canonical" href="https://screentinker.com/guides/self-hosted-digital-signage.html">
<meta property="og:type" content="article">
<meta property="og:url" content="https://screentinker.com/guides/self-hosted-digital-signage.html">
<meta property="og:title" content="Self-Hosted Digital Signage Software - Complete Guide (2026)">
<meta property="og:description" content="Why and how to self-host your digital signage CMS. Data privacy, cost control, no recurring fees.">
<meta property="og:image" content="https://screentinker.com/assets/dashboard-preview.png">
<meta property="og:site_name" content="ScreenTinker">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Self-Hosted Digital Signage Software - Complete Guide (2026)">
<meta name="twitter:description" content="Why and how to self-host your digital signage CMS. Data privacy, cost control, no recurring fees.">
<meta name="twitter:image" content="https://screentinker.com/assets/dashboard-preview.png">
<meta name="theme-color" content="#111827">
<link rel="icon" href="/assets/icon-192.png">
<link rel="apple-touch-icon" href="/assets/icon-192.png">
<link rel="stylesheet" href="/css/seo-page.css">
</head>
<body>
<nav>
<div class="nav-inner">
<div class="nav-logo">
<a href="/" style="display:flex;align-items:center;gap:10px">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="2" y="3" width="20" height="14" rx="2"/><line x1="8" y1="21" x2="16" y2="21"/><line x1="12" y1="17" x2="12" y2="21"/></svg>
<span class="nav-logo-text">ScreenTinker</span>
</a>
</div>
<div class="nav-links">
<a href="/#features">Features</a>
<a href="/#pricing">Pricing</a>
<a href="/#compare">Compare</a>
<a href="/app#/login" class="btn btn-outline" style="margin-left:16px">Sign In</a>
<a href="/app#/login" class="btn btn-primary" style="margin-left:8px">Try Free</a>
</div>
</div>
</nav>
<main class="article">
<nav class="breadcrumb" aria-label="Breadcrumb">
<a href="/">Home</a>
<span>/</span>
<a href="/#features">Guides</a>
<span>/</span>
<span>Self-Hosted Digital Signage</span>
</nav>
<h1>Self-Hosted Digital Signage Software: Complete Guide (2026)</h1>
<p class="lead">Why you might want to self-host your digital signage CMS, what you need to do it well, and how to deploy ScreenTinker on your own server.</p>
<h2>Why self-host digital signage?</h2>
<p>Most digital signage products are cloud-only. That works for many businesses, but there are real reasons to keep the server in-house:</p>
<ul>
<li><strong>Data sovereignty.</strong> Healthcare, finance, government, and education often cannot put internal information into a third-party cloud. Self-hosting keeps content, schedules, and access logs on your network.</li>
<li><strong>Cost control.</strong> Per-screen monthly fees stack up fast. Self-hosting trades that for a fixed server cost - typically $5 to $50 per month for a small VPS that can run hundreds of screens.</li>
<li><strong>Network isolation.</strong> Some deployments live on private LANs with no internet access at all. Self-hosting is the only way to manage signage in those environments.</li>
<li><strong>No vendor lock-in.</strong> If the cloud vendor disappears, raises prices 3x, or pivots away from your use case, your deployment goes with them. Self-hosters control their own roadmap.</li>
<li><strong>Customization.</strong> Open source self-hosted means you can fork the code, add a custom widget, or wire it into your existing systems.</li>
</ul>
<h2>What you need</h2>
<h3>Hardware / VPS</h3>
<p>A modest Linux server is enough for most deployments:</p>
<ul>
<li><strong>Up to 25 displays:</strong> 1 vCPU, 1 GB RAM, 20 GB disk. ~$5/month on Hetzner, DigitalOcean, or Vultr.</li>
<li><strong>25-100 displays:</strong> 2 vCPU, 2 GB RAM, 40 GB disk. ~$12-20/month.</li>
<li><strong>100+ displays:</strong> 4+ vCPU, 4+ GB RAM, faster disk. Plan for content storage at ~50-200 MB per screen depending on media volume.</li>
</ul>
<p>An on-prem VM works just as well as a cloud VPS - in fact, on-prem is often the whole point.</p>
<h3>Software prerequisites</h3>
<ul>
<li>Ubuntu 22.04 or 24.04 LTS (Debian 12 also works)</li>
<li>Node.js 18 or newer</li>
<li>A domain name pointed at your server (or just an internal hostname / IP for LAN deployments)</li>
<li>SSL certificate (Let's Encrypt is free; or self-signed for LAN)</li>
</ul>
<h2>Deploying ScreenTinker</h2>
<p>Detailed setup is in the <a href="https://github.com/screentinker/screentinker" target="_blank" rel="noopener">GitHub README</a>. Quick version:</p>
<pre><code>git clone https://github.com/screentinker/screentinker.git
cd screentinker/server
npm install
cp .env.example .env
# edit .env with your domain, JWT_SECRET, and SELF_HOSTED=true
node server.js</code></pre>
<p>Set <code>SELF_HOSTED=true</code> in the env. This unlocks the enterprise plan for your account, disables subscription expiry checks, and skips Stripe entirely. It is meant for the operator-controlled deployment case.</p>
<h2>Reverse proxy and TLS</h2>
<p>ScreenTinker listens on HTTP/HTTPS directly, but in production you typically front it with nginx or Caddy for TLS termination, gzip, and rate limiting. A minimal Caddyfile:</p>
<pre><code>signage.example.com {
reverse_proxy localhost:3001
}</code></pre>
<p>Caddy handles Let's Encrypt automatically. nginx works too if your team prefers it.</p>
<h2>Running as a service</h2>
<p>Use systemd to keep the process alive across reboots. A unit file at <code>/etc/systemd/system/screentinker.service</code>:</p>
<pre><code>[Unit]
Description=ScreenTinker Digital Signage Server
After=network.target
[Service]
WorkingDirectory=/opt/screentinker/server
ExecStart=/usr/bin/node server.js
EnvironmentFile=/opt/screentinker/.env
Restart=always
User=screentinker
[Install]
WantedBy=multi-user.target</code></pre>
<p>Enable with <code>systemctl enable --now screentinker</code>.</p>
<h2>Backups</h2>
<p>The state lives in two places:</p>
<ul>
<li><code>server/db/remote_display.db</code> - SQLite database of users, devices, playlists, schedules</li>
<li><code>server/uploads/</code> - uploaded media (images, videos, thumbnails)</li>
</ul>
<p>A nightly tarball of those two paths gives you a full restore point. Pair with offsite sync (rclone, restic) for disaster recovery.</p>
<h2>Self-hosted vs cloud-hosted comparison</h2>
<div class="compare-table-wrap">
<table class="compare-table">
<thead>
<tr><th>Concern</th><th>ScreenTinker self-hosted</th><th>Cloud-only signage products</th></tr>
</thead>
<tbody>
<tr><td>Data location</td><td>Your server</td><td>Vendor's cloud</td></tr>
<tr><td>Recurring per-screen cost</td><td>None</td><td>$5-15/screen/month</td></tr>
<tr><td>Server cost</td><td>$5-50/month flat</td><td>None (included)</td></tr>
<tr><td>Internet required for management</td><td>No (LAN works)</td><td>Yes</td></tr>
<tr><td>Source code access</td><td>Yes (MIT)</td><td>Closed</td></tr>
<tr><td>Air-gapped deployment</td><td>Possible</td><td>Not possible</td></tr>
<tr><td>Vendor lock-in risk</td><td>None (you own it)</td><td>High</td></tr>
<tr><td>Update / patch responsibility</td><td>Yours</td><td>Vendor</td></tr>
<tr><td>Initial setup time</td><td>~1 hour</td><td>~5 minutes</td></tr>
</tbody>
</table>
</div>
<h2>When the cloud is the right answer</h2>
<p>Self-hosting is not free of cost - it requires someone who can run a Linux server, monitor it, and apply security updates. If your screen count is small (under ~10) and you do not have IT capacity, the managed cloud version is probably the right choice. ScreenTinker's hosted plans start at $39/mo for 5 devices.</p>
<div class="related">
<h2>Related guides</h2>
<ul>
<li><a href="/guides/raspberry-pi-digital-signage.html">How to set up digital signage on a Raspberry Pi</a></li>
<li><a href="/guides/digital-signage-android-tv.html">Free digital signage for Android TV and Fire TV</a></li>
<li><a href="/compare/yodeck-alternative.html">Compare: ScreenTinker vs Yodeck</a></li>
<li><a href="/compare/screencloud-alternative.html">Compare: ScreenTinker vs ScreenCloud</a></li>
<li><a href="/compare/optisigns-alternative.html">Compare: ScreenTinker vs OptiSigns</a></li>
</ul>
</div>
<div class="cta">
<h2>Try the cloud version first</h2>
<p>Use the hosted version to get familiar, then deploy on your own server when you are ready.</p>
<a href="/app#/login" class="btn btn-primary" style="padding:14px 28px;font-size:16px">Start Free</a>
<a href="https://github.com/screentinker/screentinker" target="_blank" rel="noopener" class="btn btn-outline" style="padding:14px 28px;font-size:16px;margin-left:12px">View on GitHub</a>
</div>
</main>
<footer>
<div style="color:var(--dim);font-size:13px">&copy; 2026 ScreenTinker. All rights reserved.</div>
<div class="links">
<a href="https://github.com/screentinker/screentinker" target="_blank" rel="noopener">GitHub</a>
<a href="https://discord.gg/JHWQRPaG" target="_blank" rel="noopener">Discord</a>
<a href="/legal/terms.html">Terms</a>
<a href="/legal/privacy.html">Privacy</a>
<a href="/legal/third-party.html">Licenses</a>
<a href="/app#/login">Sign In</a>
</div>
</footer>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [
{ "@type": "ListItem", "position": 1, "name": "Home", "item": "https://screentinker.com/" },
{ "@type": "ListItem", "position": 2, "name": "Guides", "item": "https://screentinker.com/#features" },
{ "@type": "ListItem", "position": 3, "name": "Self-Hosted Digital Signage", "item": "https://screentinker.com/guides/self-hosted-digital-signage.html" }
]
}
</script>
</body>
</html>