-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdeployment.html
More file actions
151 lines (149 loc) · 74.9 KB
/
Copy pathdeployment.html
File metadata and controls
151 lines (149 loc) · 74.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
<!DOCTYPE html>
<html lang="en-US" dir="ltr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Deployment | Piwi Dashboard</title>
<meta name="description" content="A modern dashboard for storing and visualising Playwright test results">
<meta name="generator" content="VitePress v1.6.4">
<link rel="preload stylesheet" href="/assets/style.BQLvV-8n.css" as="style">
<link rel="preload stylesheet" href="/vp-icons.css" as="style">
<script type="module" src="/assets/app.IV7xJp9H.js"></script>
<link rel="preload" href="/assets/inter-roman-latin.Di8DUHzh.woff2" as="font" type="font/woff2" crossorigin="">
<link rel="modulepreload" href="/assets/chunks/theme.vgHA8Ce5.js">
<link rel="modulepreload" href="/assets/chunks/framework.sV-XtlWr.js">
<link rel="modulepreload" href="/assets/deployment.md.CTMLAt2C.lean.js">
<meta property="og:type" content="website">
<meta property="og:title" content="Piwi Dashboard — A permanent home for your Playwright test results">
<meta property="og:description" content="Live dashboards, failure clustering, and flaky-test tracking for your whole team — self-hosted, no SaaS.">
<meta property="og:image" content="https://piwitests.github.io/og-image.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta property="og:url" content="https://piwitests.github.io">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Piwi Dashboard — A permanent home for your Playwright test results">
<meta name="twitter:description" content="Live dashboards, failure clustering, and flaky-test tracking for your whole team — self-hosted, no SaaS.">
<meta name="twitter:image" content="https://piwitests.github.io/og-image.png">
<script id="check-dark-mode">(()=>{const e=localStorage.getItem("vitepress-theme-appearance")||"auto",a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
<script id="check-mac-os">document.documentElement.classList.toggle("mac",/Mac|iPhone|iPod|iPad/i.test(navigator.platform));</script>
</head>
<body>
<div id="app"><div class="Layout" data-v-d8b57b2d><!--[--><!--]--><!--[--><span tabindex="-1" data-v-fcbfc0e0></span><a href="#VPContent" class="VPSkipLink visually-hidden" data-v-fcbfc0e0>Skip to content</a><!--]--><!----><header class="VPNav" data-v-d8b57b2d data-v-7ad780c2><div class="VPNavBar" data-v-7ad780c2 data-v-9fd4d1dd><div class="wrapper" data-v-9fd4d1dd><div class="container" data-v-9fd4d1dd><div class="title" data-v-9fd4d1dd><div class="VPNavBarTitle has-sidebar" data-v-9fd4d1dd data-v-9f43907a><a class="title" href="/" data-v-9f43907a><!--[--><!--]--><!----><span data-v-9f43907a>Piwi Dashboard</span><!--[--><!--]--></a></div></div><div class="content" data-v-9fd4d1dd><div class="content-body" data-v-9fd4d1dd><!--[--><!--]--><div class="VPNavBarSearch search" data-v-9fd4d1dd><!--[--><!----><div id="local-search"><button type="button" class="DocSearch DocSearch-Button" aria-label="Search"><span class="DocSearch-Button-Container"><span class="vp-icon DocSearch-Search-Icon"></span><span class="DocSearch-Button-Placeholder">Search</span></span><span class="DocSearch-Button-Keys"><kbd class="DocSearch-Button-Key"></kbd><kbd class="DocSearch-Button-Key">K</kbd></span></button></div><!--]--></div><nav aria-labelledby="main-nav-aria-label" class="VPNavBarMenu menu" data-v-9fd4d1dd data-v-afb2845e><span id="main-nav-aria-label" class="visually-hidden" data-v-afb2845e> Main Navigation </span><!--[--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/" tabindex="0" data-v-afb2845e data-v-815115f5><!--[--><span data-v-815115f5>Home</span><!--]--></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/getting-started.html" tabindex="0" data-v-afb2845e data-v-815115f5><!--[--><span data-v-815115f5>Getting started</span><!--]--></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/reporter.html" tabindex="0" data-v-afb2845e data-v-815115f5><!--[--><span data-v-815115f5>Reporter</span><!--]--></a><!--]--><!--[--><a class="VPLink link vp-external-link-icon VPNavBarMenuLink" href="https://piwitests.github.io/demo/docs" target="_blank" rel="noreferrer" tabindex="0" data-v-afb2845e data-v-815115f5><!--[--><span data-v-815115f5>API docs</span><!--]--></a><!--]--><!--[--><a class="VPLink link vp-external-link-icon VPNavBarMenuLink" href="https://piwitests.github.io/demo/" target="_blank" rel="noreferrer" tabindex="0" data-v-afb2845e data-v-815115f5><!--[--><span data-v-815115f5>Demo</span><!--]--></a><!--]--><!--]--></nav><!----><div class="VPNavBarAppearance appearance" data-v-9fd4d1dd data-v-3f90c1a5><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" title aria-checked="false" data-v-3f90c1a5 data-v-be9742d9 data-v-b4ccac88><span class="check" data-v-b4ccac88><span class="icon" data-v-b4ccac88><!--[--><span class="vpi-sun sun" data-v-be9742d9></span><span class="vpi-moon moon" data-v-be9742d9></span><!--]--></span></span></button></div><div class="VPSocialLinks VPNavBarSocialLinks social-links" data-v-9fd4d1dd data-v-ef6192dc data-v-e71e869c><!--[--><a class="VPSocialLink no-icon" href="https://github.com/PiwiTests/platform" aria-label="github" target="_blank" rel="noopener" data-v-e71e869c data-v-60a9a2d3><span class="vpi-social-github"></span></a><!--]--></div><div class="VPFlyout VPNavBarExtra extra" data-v-9fd4d1dd data-v-f953d92f data-v-bfe7971f><button type="button" class="button" aria-haspopup="true" aria-expanded="false" aria-label="extra navigation" data-v-bfe7971f><span class="vpi-more-horizontal icon" data-v-bfe7971f></span></button><div class="menu" data-v-bfe7971f><div class="VPMenu" data-v-bfe7971f data-v-20ed86d6><!----><!--[--><!--[--><!----><div class="group" data-v-f953d92f><div class="item appearance" data-v-f953d92f><p class="label" data-v-f953d92f>Appearance</p><div class="appearance-action" data-v-f953d92f><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" title aria-checked="false" data-v-f953d92f data-v-be9742d9 data-v-b4ccac88><span class="check" data-v-b4ccac88><span class="icon" data-v-b4ccac88><!--[--><span class="vpi-sun sun" data-v-be9742d9></span><span class="vpi-moon moon" data-v-be9742d9></span><!--]--></span></span></button></div></div></div><div class="group" data-v-f953d92f><div class="item social-links" data-v-f953d92f><div class="VPSocialLinks social-links-list" data-v-f953d92f data-v-e71e869c><!--[--><a class="VPSocialLink no-icon" href="https://github.com/PiwiTests/platform" aria-label="github" target="_blank" rel="noopener" data-v-e71e869c data-v-60a9a2d3><span class="vpi-social-github"></span></a><!--]--></div></div></div><!--]--><!--]--></div></div></div><!--[--><!--]--><button type="button" class="VPNavBarHamburger hamburger" aria-label="mobile navigation" aria-expanded="false" aria-controls="VPNavScreen" data-v-9fd4d1dd data-v-6bee1efd><span class="container" data-v-6bee1efd><span class="top" data-v-6bee1efd></span><span class="middle" data-v-6bee1efd></span><span class="bottom" data-v-6bee1efd></span></span></button></div></div></div></div><div class="divider" data-v-9fd4d1dd><div class="divider-line" data-v-9fd4d1dd></div></div></div><!----></header><div class="VPLocalNav has-sidebar empty" data-v-d8b57b2d data-v-2488c25a><div class="container" data-v-2488c25a><button class="menu" aria-expanded="false" aria-controls="VPSidebarNav" data-v-2488c25a><span class="vpi-align-left menu-icon" data-v-2488c25a></span><span class="menu-text" data-v-2488c25a>Menu</span></button><div class="VPLocalNavOutlineDropdown" style="--vp-vh:0px;" data-v-2488c25a data-v-6b867909><button data-v-6b867909>Return to top</button><!----></div></div></div><aside class="VPSidebar" data-v-d8b57b2d data-v-42c4c606><div class="curtain" data-v-42c4c606></div><nav class="nav" id="VPSidebarNav" aria-labelledby="sidebar-aria-label" tabindex="-1" data-v-42c4c606><span class="visually-hidden" id="sidebar-aria-label" data-v-42c4c606> Sidebar Navigation </span><!--[--><!--]--><!--[--><div class="no-transition group" data-v-51288d80><section class="VPSidebarItem level-0" data-v-51288d80 data-v-0009425e><!----><div class="items" data-v-0009425e><!--[--><div class="VPSidebarItem level-1 is-link" data-v-0009425e data-v-0009425e><div class="item" data-v-0009425e><div class="indicator" data-v-0009425e></div><a class="VPLink link link" href="/getting-started.html" data-v-0009425e><!--[--><p class="text" data-v-0009425e>Getting started</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0009425e data-v-0009425e><div class="item" data-v-0009425e><div class="indicator" data-v-0009425e></div><a class="VPLink link link" href="/comparison.html" data-v-0009425e><!--[--><p class="text" data-v-0009425e>Why Piwi? (comparison & FAQ)</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0009425e data-v-0009425e><div class="item" data-v-0009425e><div class="indicator" data-v-0009425e></div><a class="VPLink link link" href="/ui-overview.html" data-v-0009425e><!--[--><p class="text" data-v-0009425e>UI overview</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0009425e data-v-0009425e><div class="item" data-v-0009425e><div class="indicator" data-v-0009425e></div><a class="VPLink link link" href="/reporter.html" data-v-0009425e><!--[--><p class="text" data-v-0009425e>Reporter</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0009425e data-v-0009425e><div class="item" data-v-0009425e><div class="indicator" data-v-0009425e></div><a class="VPLink link link" href="/capture-fixtures.html" data-v-0009425e><!--[--><p class="text" data-v-0009425e>Capture fixtures</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="no-transition group" data-v-51288d80><section class="VPSidebarItem level-0" data-v-51288d80 data-v-0009425e><div class="item" role="button" tabindex="0" data-v-0009425e><div class="indicator" data-v-0009425e></div><h2 class="text" data-v-0009425e>Features</h2><!----></div><div class="items" data-v-0009425e><!--[--><div class="VPSidebarItem level-1 is-link" data-v-0009425e data-v-0009425e><div class="item" data-v-0009425e><div class="indicator" data-v-0009425e></div><a class="VPLink link link" href="/ai-diagnosis.html" data-v-0009425e><!--[--><p class="text" data-v-0009425e>AI diagnosis & clustering</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0009425e data-v-0009425e><div class="item" data-v-0009425e><div class="indicator" data-v-0009425e></div><a class="VPLink link link" href="/flaky-tests.html" data-v-0009425e><!--[--><p class="text" data-v-0009425e>Flaky tests & analytics</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0009425e data-v-0009425e><div class="item" data-v-0009425e><div class="indicator" data-v-0009425e></div><a class="VPLink link link" href="/timeline-markers.html" data-v-0009425e><!--[--><p class="text" data-v-0009425e>Timeline markers</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0009425e data-v-0009425e><div class="item" data-v-0009425e><div class="indicator" data-v-0009425e></div><a class="VPLink link link" href="/notifications.html" data-v-0009425e><!--[--><p class="text" data-v-0009425e>Notifications & alerts</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="no-transition group" data-v-51288d80><section class="VPSidebarItem level-0 has-active" data-v-51288d80 data-v-0009425e><div class="item" role="button" tabindex="0" data-v-0009425e><div class="indicator" data-v-0009425e></div><h2 class="text" data-v-0009425e>Configuration</h2><!----></div><div class="items" data-v-0009425e><!--[--><div class="VPSidebarItem level-1 is-link" data-v-0009425e data-v-0009425e><div class="item" data-v-0009425e><div class="indicator" data-v-0009425e></div><a class="VPLink link link" href="/configuration.html" data-v-0009425e><!--[--><p class="text" data-v-0009425e>Configuration reference</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0009425e data-v-0009425e><div class="item" data-v-0009425e><div class="indicator" data-v-0009425e></div><a class="VPLink link link" href="/configuration/generator.html" data-v-0009425e><!--[--><p class="text" data-v-0009425e>Configuration generator</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0009425e data-v-0009425e><div class="item" data-v-0009425e><div class="indicator" data-v-0009425e></div><a class="VPLink link link" href="/authentication.html" data-v-0009425e><!--[--><p class="text" data-v-0009425e>Authentication</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0009425e data-v-0009425e><div class="item" data-v-0009425e><div class="indicator" data-v-0009425e></div><a class="VPLink link link" href="/storage.html" data-v-0009425e><!--[--><p class="text" data-v-0009425e>Storage configuration</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0009425e data-v-0009425e><div class="item" data-v-0009425e><div class="indicator" data-v-0009425e></div><a class="VPLink link link" href="/deployment.html" data-v-0009425e><!--[--><p class="text" data-v-0009425e>Deployment</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="no-transition group" data-v-51288d80><section class="VPSidebarItem level-0" data-v-51288d80 data-v-0009425e><div class="item" role="button" tabindex="0" data-v-0009425e><div class="indicator" data-v-0009425e></div><h2 class="text" data-v-0009425e>Integrate</h2><!----></div><div class="items" data-v-0009425e><!--[--><div class="VPSidebarItem level-1 is-link" data-v-0009425e data-v-0009425e><div class="item" data-v-0009425e><div class="indicator" data-v-0009425e></div><a class="VPLink link vp-external-link-icon link" href="https://piwitests.github.io/demo/docs" target="_blank" rel="noreferrer" data-v-0009425e><!--[--><p class="text" data-v-0009425e>API docs (interactive)</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0009425e data-v-0009425e><div class="item" data-v-0009425e><div class="indicator" data-v-0009425e></div><a class="VPLink link link" href="/mcp.html" data-v-0009425e><!--[--><p class="text" data-v-0009425e>MCP server</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0009425e data-v-0009425e><div class="item" data-v-0009425e><div class="indicator" data-v-0009425e></div><a class="VPLink link link" href="/ide-integration.html" data-v-0009425e><!--[--><p class="text" data-v-0009425e>Open in IDE</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0009425e data-v-0009425e><div class="item" data-v-0009425e><div class="indicator" data-v-0009425e></div><a class="VPLink link link" href="/backend-logs.html" data-v-0009425e><!--[--><p class="text" data-v-0009425e>Backend logs</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><!--]--><!--[--><!--]--></nav></aside><div class="VPContent has-sidebar" id="VPContent" data-v-d8b57b2d data-v-9a6c75ad><div class="VPDoc has-sidebar has-aside" data-v-9a6c75ad data-v-e6f2a212><!--[--><!--]--><div class="container" data-v-e6f2a212><div class="aside" data-v-e6f2a212><div class="aside-curtain" data-v-e6f2a212></div><div class="aside-container" data-v-e6f2a212><div class="aside-content" data-v-e6f2a212><div class="VPDocAside" data-v-e6f2a212 data-v-cb998dce><!--[--><!--]--><!--[--><!--]--><nav aria-labelledby="doc-outline-aria-label" class="VPDocAsideOutline" data-v-cb998dce data-v-f610f197><div class="content" data-v-f610f197><div class="outline-marker" data-v-f610f197></div><div aria-level="2" class="outline-title" id="doc-outline-aria-label" role="heading" data-v-f610f197>On this page</div><ul class="VPDocOutlineItem root" data-v-f610f197 data-v-53c99d69><!--[--><!--]--></ul></div></nav><!--[--><!--]--><div class="spacer" data-v-cb998dce></div><!--[--><!--]--><!----><!--[--><!--]--><!--[--><!--]--></div></div></div></div><div class="content" data-v-e6f2a212><div class="content-container" data-v-e6f2a212><!--[--><!--]--><main class="main" data-v-e6f2a212><div style="position:relative;" class="vp-doc _deployment external-link-icon-enabled" data-v-e6f2a212><div><h1 id="deployment" tabindex="-1">Deployment <a class="header-anchor" href="#deployment" aria-label="Permalink to "Deployment""></a></h1><h2 id="docker-recommended" tabindex="-1">Docker (recommended) <a class="header-anchor" href="#docker-recommended" aria-label="Permalink to "Docker (recommended)""></a></h2><h3 id="quick-start" tabindex="-1">Quick start <a class="header-anchor" href="#quick-start" aria-label="Permalink to "Quick start""></a></h3><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-YIgKJ" id="tab-NPfqzIg" checked><label data-title="Linux / macOS" for="tab-NPfqzIg">Linux / macOS</label><input type="radio" name="group-YIgKJ" id="tab-q4iUYDO"><label data-title="Windows (PowerShell)" for="tab-q4iUYDO">Windows (PowerShell)</label></div><div class="blocks"><div class="language-bash vp-adaptive-theme active"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">docker</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> pull</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> phenx/piwitests-server:latest</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">mkdir</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -p</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> .data</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> && </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">chown</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -R</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> 1001:1001</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> .data</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> # the container runs as non-root UID 1001</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">docker</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> run</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -p</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> 3000:3000</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -v</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> $(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">pwd</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">/.data:/app/.data</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> phenx/piwitests-server:latest</span></span></code></pre></div><div class="language-powershell vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">powershell</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">docker pull phenx</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">piwitests</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">-</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">server:latest</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">docker run </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">-</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">p </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">3000</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">3000</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> -</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">v ${PWD}</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">.data:</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">app</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">.data phenx</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">piwitests</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">-</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">server:latest</span></span></code></pre></div></div></div><p>The dashboard will be available at <code>http://localhost:3000</code>.</p><blockquote><p><strong>Linux hosts:</strong> without the <code>chown</code>, Docker auto-creates <code>.data</code> owned by <code>root</code> and the container (non-root UID 1001) can't write to it. Docker Desktop on Windows/macOS handles this automatically. See <a href="#permission-issues-with-volumes">Permission issues with volumes</a> if you hit a permission error.</p></blockquote><h3 id="available-tags" tabindex="-1">Available tags <a class="header-anchor" href="#available-tags" aria-label="Permalink to "Available tags""></a></h3><table tabindex="0"><thead><tr><th>Tag</th><th>Description</th></tr></thead><tbody><tr><td><code>latest</code></td><td>Latest stable release</td></tr><tr><td><code>0.9.0</code></td><td>Specific version (semver)</td></tr><tr><td><code>0.9</code></td><td>Latest patch of a minor version</td></tr><tr><td><code>0</code></td><td>Latest release of the major version</td></tr></tbody></table><p>Pin a specific version in production; <a href="https://hub.docker.com/r/phenx/piwitests-server/tags" target="_blank" rel="noreferrer">tags on Docker Hub</a>.</p><h3 id="image-details" tabindex="-1">Image details <a class="header-anchor" href="#image-details" aria-label="Permalink to "Image details""></a></h3><table tabindex="0"><thead><tr><th>Property</th><th>Value</th></tr></thead><tbody><tr><td>Base image</td><td><code>node:24-alpine</code></td></tr><tr><td>Build type</td><td>Multistage (builder + production stages)</td></tr><tr><td>Image size</td><td>~400 MB</td></tr><tr><td>Platforms</td><td><code>linux/amd64</code>, <code>linux/arm64</code></td></tr><tr><td>Registry</td><td><code>phenx/piwitests-server</code></td></tr></tbody></table><h3 id="volumes" tabindex="-1">Volumes <a class="header-anchor" href="#volumes" aria-label="Permalink to "Volumes""></a></h3><p>Mount a volume to persist data:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">docker</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> run</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -p</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> 3000:3000</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -v</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> /path/to/data:/app/.data</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> phenx/piwitests-server:latest</span></span></code></pre></div><blockquote><p>On Windows, use a host path like <code>C:\piwi\data</code> (PowerShell) in place of <code>/path/to/data</code>.</p></blockquote><p>The <code>.data</code> directory contains:</p><ul><li><code>piwi.db</code> — SQLite database</li><li><code>storage/</code> — HTML reports and trace files</li></ul><h3 id="environment-variables" tabindex="-1">Environment variables <a class="header-anchor" href="#environment-variables" aria-label="Permalink to "Environment variables""></a></h3><table tabindex="0"><thead><tr><th>Variable</th><th>Default</th><th>Description</th></tr></thead><tbody><tr><td><code>NODE_ENV</code></td><td><code>production</code></td><td>Set automatically</td></tr><tr><td><code>HOST</code></td><td><code>0.0.0.0</code></td><td>Listen on all interfaces</td></tr><tr><td><code>PORT</code></td><td><code>3000</code></td><td>Application port</td></tr><tr><td><code>PIWI_SECRET_KEY</code></td><td>—</td><td>Master key for encrypting secrets in the database (AI API keys, SCM tokens). Recommended in all deployments. Generate with <code>node -e "console.log(require('node:crypto').randomBytes(32).toString('hex'))"</code> (or <code>openssl rand -hex 32</code>).</td></tr><tr><td><code>PIWI_AUTH_ENABLED</code></td><td>—</td><td>Enable authentication</td></tr><tr><td><code>PIWI_AUTH_SECRET</code></td><td>—</td><td>Secret for encrypting session cookies (required if auth enabled). Generate with <code>node -e "console.log(require('node:crypto').randomBytes(32).toString('hex'))"</code> (or <code>openssl rand -hex 32</code>).</td></tr><tr><td><code>PIWI_STORAGE_TYPE</code></td><td><code>local</code></td><td>Storage backend (<code>local</code> or <code>s3</code>)</td></tr><tr><td><code>PIWI_DATABASE_URL</code></td><td>—</td><td>PostgreSQL connection string (e.g. <code>postgresql://user:pass@host:5432/db</code>). When set, PostgreSQL is used instead of SQLite.</td></tr><tr><td><code>PIWI_DATABASE_PATH</code></td><td><code>.data/piwi.db</code></td><td>SQLite database path (ignored when <code>PIWI_DATABASE_URL</code> is set)</td></tr></tbody></table><h2 id="building-locally" tabindex="-1">Building locally <a class="header-anchor" href="#building-locally" aria-label="Permalink to "Building locally""></a></h2><p>Build from the repository root (the <code>Dockerfile</code> lives there):</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-esw62" id="tab-h5JEVdA" checked><label data-title="Linux / macOS" for="tab-h5JEVdA">Linux / macOS</label><input type="radio" name="group-esw62" id="tab-9LcHaBz"><label data-title="Windows (PowerShell)" for="tab-9LcHaBz">Windows (PowerShell)</label></div><div class="blocks"><div class="language-bash vp-adaptive-theme active"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">docker</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> build</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -t</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> piwi-dashboard:local</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> .</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">docker</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> run</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -p</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> 3000:3000</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -v</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> $(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">pwd</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">/.data:/app/.data</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> piwi-dashboard:local</span></span></code></pre></div><div class="language-powershell vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">powershell</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">docker build </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">-</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">t piwi</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">-</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">dashboard:local .</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">docker run </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">-</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">p </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">3000</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">3000</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> -</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">v ${PWD}</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">.data:</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">app</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">.data piwi</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">-</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">dashboard:local</span></span></code></pre></div></div></div><h2 id="docker-compose" tabindex="-1">Docker Compose <a class="header-anchor" href="#docker-compose" aria-label="Permalink to "Docker Compose""></a></h2><p>The repository ships a ready-to-use <a href="https://github.com/PiwiTests/platform/blob/main/docker-compose.yml" target="_blank" rel="noreferrer"><code>docker-compose.yml</code></a> with commented options (secret key, auth, PostgreSQL). Minimal version:</p><div class="language-yaml vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">yaml</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">services</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> piwi-dashboard</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> image</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">phenx/piwitests-server:latest</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> ports</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> - </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"3000:3000"</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> volumes</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> - </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">./.data:/app/.data</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> restart</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">unless-stopped</span></span></code></pre></div><p>Run with:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">docker</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> compose</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> up</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -d</span></span></code></pre></div><h3 id="docker-compose-with-postgresql" tabindex="-1">Docker Compose with PostgreSQL <a class="header-anchor" href="#docker-compose-with-postgresql" aria-label="Permalink to "Docker Compose with PostgreSQL""></a></h3><p>For production deployments requiring a robust relational database:</p><div class="language-yaml vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">yaml</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">services</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> postgres</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> image</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">postgres:17-alpine</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> environment</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> POSTGRES_USER</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">piwi</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> POSTGRES_PASSWORD</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">change-me</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> POSTGRES_DB</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">piwi</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> volumes</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> - </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">pg-data:/var/lib/postgresql/data</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> restart</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">unless-stopped</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> piwi-dashboard</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> image</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">phenx/piwitests-server:latest</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> ports</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> - </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"3000:3000"</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> volumes</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> - </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">./.data:/app/.data</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> # still used for report/trace file storage</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> environment</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> - </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">PIWI_DATABASE_URL=postgresql://piwi:change-me@postgres:5432/piwi</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> depends_on</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> - </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">postgres</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> restart</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">unless-stopped</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">volumes</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> pg-data</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span></span></code></pre></div><p>Run with:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">docker</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> compose</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> up</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -d</span></span></code></pre></div><h2 id="kubernetes" tabindex="-1">Kubernetes <a class="header-anchor" href="#kubernetes" aria-label="Permalink to "Kubernetes""></a></h2><p>Example deployment manifest:</p><div class="language-yaml vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">yaml</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">apiVersion</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">apps/v1</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">kind</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">Deployment</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">metadata</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> name</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">piwi-dashboard</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">spec</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> replicas</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">1</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> selector</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> matchLabels</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> app</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">piwi-dashboard</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> template</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> metadata</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> labels</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> app</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">piwi-dashboard</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> spec</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> containers</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> - </span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">name</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">piwi-dashboard</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> image</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">phenx/piwitests-server:latest</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> ports</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> - </span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">containerPort</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">3000</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> readinessProbe</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> httpGet</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> path</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">/api/health</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> port</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">3000</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> initialDelaySeconds</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">10</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> periodSeconds</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">10</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> livenessProbe</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> httpGet</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> path</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">/api/health</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> port</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">3000</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> initialDelaySeconds</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">20</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> periodSeconds</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">30</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> volumeMounts</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> - </span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">name</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">data</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> mountPath</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">/app/.data</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> volumes</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> - </span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">name</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">data</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> persistentVolumeClaim</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> claimName</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">piwi-dashboard-data</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">---</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">apiVersion</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">v1</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">kind</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">Service</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">metadata</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> name</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">piwi-dashboard</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">spec</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> selector</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> app</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">piwi-dashboard</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> ports</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> - </span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">port</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">80</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> targetPort</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">3000</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> type</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">LoadBalancer</span></span></code></pre></div><h2 id="npm-npx-quick-local-run" tabindex="-1">npm / npx (quick local run) <a class="header-anchor" href="#npm-npx-quick-local-run" aria-label="Permalink to "npm / npx (quick local run)""></a></h2><p>For a quick local run without Docker, the server is published to npm as <a href="https://www.npmjs.com/package/@piwitests/server" target="_blank" rel="noreferrer"><code>@piwitests/server</code></a>. It bundles the prebuilt server and needs only <strong>Node.js 24+</strong>:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">npx</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> @piwitests/server</span></span></code></pre></div><p>The dashboard will be available at <code>http://localhost:3000</code>.</p><p>The server creates a <code>.data/</code> directory <strong>in the current working directory</strong> for the SQLite database (<code>.data/piwi.db</code>) and file storage (<code>.data/storage/</code>) — the same data layout the Docker image mounts at <code>/app/.data</code>. Run the command from the same directory each time to keep your data.</p><p>Configuration uses the same environment variables as the Docker image (see the table above and the <a href="/configuration.html">configuration reference</a>). For example, to change the port:</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-mAQeh" id="tab-ZLv2Srq" checked><label data-title="Linux / macOS" for="tab-ZLv2Srq">Linux / macOS</label><input type="radio" name="group-mAQeh" id="tab-L6eIWt6"><label data-title="Windows (PowerShell)" for="tab-L6eIWt6">Windows (PowerShell)</label></div><div class="blocks"><div class="language-bash vp-adaptive-theme active"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">PORT</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">8080</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> npx</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> @piwitests/server</span></span></code></pre></div><div class="language-powershell vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">powershell</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">$</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">env:</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">PORT</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'8080'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">; npx @piwitests</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">server</span></span></code></pre></div></div></div><blockquote><p><strong>Docker remains the recommended path for production</strong> — it ships a pinned Node runtime, runs as a non-root user, and isolates the environment. The npm package is best for a quick local trial or environments where Docker isn't available.</p></blockquote><h2 id="production-build-from-source" tabindex="-1">Production build from source <a class="header-anchor" href="#production-build-from-source" aria-label="Permalink to "Production build from source""></a></h2><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">cd</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> application</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">npm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> install</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">npm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> run</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> app:build</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">npm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> run</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> app:preview</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> # preview the production build locally</span></span></code></pre></div><h2 id="health-checks" tabindex="-1">Health checks <a class="header-anchor" href="#health-checks" aria-label="Permalink to "Health checks""></a></h2><p><code>GET /api/health</code> verifies database connectivity and returns <code>200 {"status":"ok"}</code> when healthy, <code>503</code> otherwise — use it for load-balancer targets, uptime monitors, and container orchestration. The Docker image ships a built-in <code>HEALTHCHECK</code> against it, so <code>docker ps</code> shows <code>healthy</code>/<code>unhealthy</code> out of the box. <code>GET /api/version</code> additionally reports the running version and database backend.</p><h2 id="reverse-proxy-https" tabindex="-1">Reverse proxy (HTTPS) <a class="header-anchor" href="#reverse-proxy-https" aria-label="Permalink to "Reverse proxy (HTTPS)""></a></h2><p>Always put a TLS-terminating reverse proxy in front of the dashboard for anything beyond localhost. Two working examples — mind the <strong>upload size</strong> (trace/report uploads can reach hundreds of MB) and <strong>SSE streaming</strong> (live runs and browser notifications use long-lived <code>text/event-stream</code> responses that must not be buffered).</p><p><strong>Caddy</strong> (automatic HTTPS):</p><div class="language-text vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">text</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span>piwi.example.com {</span></span>
<span class="line"><span> reverse_proxy localhost:3000</span></span>
<span class="line"><span>}</span></span></code></pre></div><p><strong>nginx:</strong></p><div class="language-nginx vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">nginx</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">server</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> listen </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">443</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> ssl;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> server_name </span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">piwi.example.com;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> # ssl_certificate /etc/letsencrypt/live/piwi.example.com/fullchain.pem;</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> # ssl_certificate_key /etc/letsencrypt/live/piwi.example.com/privkey.pem;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> client_max_body_size </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">500m</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">; </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"># trace + report uploads</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> location</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> / </span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> proxy_pass </span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">http://127.0.0.1:3000;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> proxy_http_version </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">1.1</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> proxy_set_header </span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">Host $host;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> proxy_set_header </span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">X-Forwarded-For $proxy_add_x_forwarded_for;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> proxy_set_header </span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">X-Forwarded-Proto $scheme;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> # Live streaming + notifications use Server-Sent Events:</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> proxy_buffering </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">off</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> proxy_read_timeout </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">1h</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><p>When auth is enabled, set <code>PIWI_SITE_URL</code> to the public HTTPS URL so email links and OAuth callbacks point at the right origin.</p><h2 id="backups" tabindex="-1">Backups <a class="header-anchor" href="#backups" aria-label="Permalink to "Backups""></a></h2><p>Everything lives in two places — back both up:</p><ol><li><strong>The database</strong> — SQLite file <code>.data/piwi.db</code> (default) or your PostgreSQL database (<code>pg_dump</code>).</li><li><strong>File storage</strong> — <code>.data/storage/</code> (HTML reports, traces, attachments), unless you use <a href="/storage.html">S3 storage</a>.</li></ol><p>With the default SQLite + local storage setup, a consistent backup is simply a copy of <code>.data/</code> while the container is stopped — or use SQLite's online backup to avoid downtime:</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-62cnt" id="tab-InPb2h8" checked><label data-title="Linux / macOS" for="tab-InPb2h8">Linux / macOS</label><input type="radio" name="group-62cnt" id="tab-nhXtxH7"><label data-title="Windows (PowerShell)" for="tab-nhXtxH7">Windows (PowerShell)</label></div><div class="blocks"><div class="language-bash vp-adaptive-theme active"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"># Online, consistent SQLite backup + storage copy</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">sqlite3</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> .data/piwi.db</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> ".backup '.data/piwi-backup.db'"</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">tar</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> czf</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> piwi-backup.tar.gz</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -C</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> .data</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> piwi-backup.db</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> storage</span></span></code></pre></div><div class="language-powershell vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">powershell</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"># Stop the container first for a consistent copy, then:</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Compress-Archive</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> -</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">Path .data </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">-</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">DestinationPath piwi</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">-</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">backup.zip</span></span></code></pre></div></div></div><p>With PostgreSQL: <code>pg_dump</code> the database and copy <code>.data/storage/</code> (or rely on your S3 bucket's own durability/versioning).</p><h2 id="resource-requirements" tabindex="-1">Resource requirements <a class="header-anchor" href="#resource-requirements" aria-label="Permalink to "Resource requirements""></a></h2><p>Piwi is a single Node.js process and runs comfortably on small machines:</p><table tabindex="0"><thead><tr><th>Deployment</th><th>Guideline</th></tr></thead><tbody><tr><td>RAM</td><td>~300 MB idle; 1 GB is comfortable headroom for large uploads and AI diagnosis</td></tr><tr><td>CPU</td><td>1 vCPU is enough for a team; ingest is I/O-bound</td></tr><tr><td>Disk</td><td>The real variable — traces and HTML reports dominate. Budget by retention: e.g. ~50–200 MB per run with traces enabled. Prune old runs from <strong>Settings → Storage</strong></td></tr><tr><td>Scaling</td><td>Run a single replica. SQLite requires it; with PostgreSQL the SSE event bus is still in-process, so keep one instance</td></tr></tbody></table><h2 id="security" tabindex="-1">Security <a class="header-anchor" href="#security" aria-label="Permalink to "Security""></a></h2><p>The container runs as a non-root user (<code>nodejs:nodejs</code>, UID/GID 1001).</p><p>Security best practices:</p><ul><li>Always use HTTPS in production</li><li>Mount <code>.data/</code> on a persistent volume</li><li>Set a strong <code>PIWI_SECRET_KEY</code> (<code>node -e "console.log(require('node:crypto').randomBytes(32).toString('hex'))"</code>, or <code>openssl rand -hex 32</code>) to encrypt secrets at rest</li><li>Set a strong <code>PIWI_AUTH_SECRET</code> and enable authentication for multi-user deployments</li></ul><h2 id="troubleshooting" tabindex="-1">Troubleshooting <a class="header-anchor" href="#troubleshooting" aria-label="Permalink to "Troubleshooting""></a></h2><h3 id="permission-issues-with-volumes" tabindex="-1">Permission issues with volumes <a class="header-anchor" href="#permission-issues-with-volumes" aria-label="Permalink to "Permission issues with volumes""></a></h3><p>On <strong>Linux hosts</strong>, the bind-mounted directory must be writable by the container's UID 1001:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">mkdir</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -p</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> .data</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">chmod</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 777</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> .data</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">docker</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> run</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -p</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> 3000:3000</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -v</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> $(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">pwd</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">/.data:/app/.data</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> phenx/piwitests-server:latest</span></span></code></pre></div><blockquote><p>On Windows and macOS, Docker Desktop manages volume permissions automatically — no <code>chmod</code> is needed. Just run the container with <code>-v ${PWD}/.data:/app/.data</code> (PowerShell).</p></blockquote><h3 id="database-locked" tabindex="-1">Database locked <a class="header-anchor" href="#database-locked" aria-label="Permalink to "Database locked""></a></h3><p>SQLite doesn't support concurrent writes well. For high-concurrency deployments, run a single instance or switch to PostgreSQL by setting <code>PIWI_DATABASE_URL</code>.</p><h3 id="port-already-in-use" tabindex="-1">Port already in use <a class="header-anchor" href="#port-already-in-use" aria-label="Permalink to "Port already in use""></a></h3><p>Map to a different host port:</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-zVBq2" id="tab-WS1WAOI" checked><label data-title="Linux / macOS" for="tab-WS1WAOI">Linux / macOS</label><input type="radio" name="group-zVBq2" id="tab-ruZb7fp"><label data-title="Windows (PowerShell)" for="tab-ruZb7fp">Windows (PowerShell)</label></div><div class="blocks"><div class="language-bash vp-adaptive-theme active"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">docker</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> run</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -p</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> 8080:3000</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -v</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> $(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">pwd</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">/.data:/app/.data</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> phenx/piwitests-server:latest</span></span></code></pre></div><div class="language-powershell vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">powershell</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">docker run </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">-</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">p </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">8080</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">3000</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> -</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">v ${PWD}</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">.data:</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">app</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">.data phenx</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">piwitests</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">-</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">server:latest</span></span></code></pre></div></div></div><p>The dashboard will be available at <code>http://localhost:8080</code>.</p></div></div></main><footer class="VPDocFooter" data-v-e6f2a212 data-v-1bcd8184><!--[--><!--]--><div class="edit-info" data-v-1bcd8184><div class="edit-link" data-v-1bcd8184><a class="VPLink link vp-external-link-icon no-icon edit-link-button" href="https://github.com/PiwiTests/platform/edit/main/docs/deployment.md" target="_blank" rel="noreferrer" data-v-1bcd8184><!--[--><span class="vpi-square-pen edit-link-icon" data-v-1bcd8184></span> Edit this page on GitHub<!--]--></a></div><div class="last-updated" data-v-1bcd8184><p class="VPLastUpdated" data-v-1bcd8184 data-v-1bb0c8a8>Updated at: <time datetime="2026-07-21T11:15:20.000Z" data-v-1bb0c8a8></time></p></div></div><nav class="prev-next" aria-labelledby="doc-footer-aria-label" data-v-1bcd8184><span class="visually-hidden" id="doc-footer-aria-label" data-v-1bcd8184>Pager</span><div class="pager" data-v-1bcd8184><a class="VPLink link pager-link prev" href="/storage.html" data-v-1bcd8184><!--[--><span class="desc" data-v-1bcd8184>Previous page</span><span class="title" data-v-1bcd8184>Storage configuration</span><!--]--></a></div><div class="pager" data-v-1bcd8184><a class="VPLink link vp-external-link-icon pager-link next" href="https://piwitests.github.io/demo/docs" target="_blank" rel="noreferrer" data-v-1bcd8184><!--[--><span class="desc" data-v-1bcd8184>Next page</span><span class="title" data-v-1bcd8184>API docs (interactive)</span><!--]--></a></div></nav></footer><!--[--><!--]--></div></div></div><!--[--><!--]--></div></div><footer class="VPFooter has-sidebar" data-v-d8b57b2d data-v-566314d4><div class="container" data-v-566314d4><p class="message" data-v-566314d4>Released under the MIT License. Zero telemetry — Piwi never phones home.<br>Piwi Dashboard is not affiliated with, endorsed by, or connected to Microsoft Corporation. Playwright is a trademark of Microsoft.</p><p class="copyright" data-v-566314d4>Copyright © 2025-present Fabien Ménager</p></div></footer><!--[--><!--]--></div></div>
<script>window.__VP_HASH_MAP__=JSON.parse("{\"ai-diagnosis.md\":\"4IHUvNJt\",\"authentication.md\":\"BDju_PBF\",\"backend-logs.md\":\"CGSvp61C\",\"capture-fixtures.md\":\"DjiwINVU\",\"comparison.md\":\"F9tI9vGV\",\"configuration.md\":\"DpBH5lnO\",\"configuration_generator.md\":\"srinoLud\",\"deployment.md\":\"CTMLAt2C\",\"flaky-tests.md\":\"AqRXSSYs\",\"getting-started.md\":\"DfqG2IdX\",\"ide-integration.md\":\"CK1-Yv_Y\",\"index.md\":\"D6SM-hYd\",\"mcp.md\":\"CdcXYB1z\",\"notifications.md\":\"PLP9NvJO\",\"reporter.md\":\"2mD8jes2\",\"storage.md\":\"DP0XasEE\",\"timeline-markers.md\":\"C0xvFsIK\",\"ui-overview.md\":\"B82d-t6n\"}");window.__VP_SITE_DATA__=JSON.parse("{\"lang\":\"en-US\",\"dir\":\"ltr\",\"title\":\"Piwi Dashboard\",\"description\":\"A modern dashboard for storing and visualising Playwright test results\",\"base\":\"/\",\"head\":[],\"router\":{\"prefetchLinks\":true},\"appearance\":true,\"themeConfig\":{\"outline\":\"deep\",\"search\":{\"provider\":\"local\"},\"nav\":[{\"text\":\"Home\",\"link\":\"/\"},{\"text\":\"Getting started\",\"link\":\"/getting-started\"},{\"text\":\"Reporter\",\"link\":\"/reporter\"},{\"text\":\"API docs\",\"link\":\"https://piwitests.github.io/demo/docs\"},{\"text\":\"Demo\",\"link\":\"https://piwitests.github.io/demo/\"}],\"sidebar\":[{\"text\":\"Getting started\",\"link\":\"/getting-started\"},{\"text\":\"Why Piwi? (comparison & FAQ)\",\"link\":\"/comparison\"},{\"text\":\"UI overview\",\"link\":\"/ui-overview\"},{\"text\":\"Reporter\",\"link\":\"/reporter\"},{\"text\":\"Capture fixtures\",\"link\":\"/capture-fixtures\"},{\"text\":\"Features\",\"items\":[{\"text\":\"AI diagnosis & clustering\",\"link\":\"/ai-diagnosis\"},{\"text\":\"Flaky tests & analytics\",\"link\":\"/flaky-tests\"},{\"text\":\"Timeline markers\",\"link\":\"/timeline-markers\"},{\"text\":\"Notifications & alerts\",\"link\":\"/notifications\"}]},{\"text\":\"Configuration\",\"items\":[{\"text\":\"Configuration reference\",\"link\":\"/configuration\"},{\"text\":\"Configuration generator\",\"link\":\"/configuration/generator\"},{\"text\":\"Authentication\",\"link\":\"/authentication\"},{\"text\":\"Storage configuration\",\"link\":\"/storage\"},{\"text\":\"Deployment\",\"link\":\"/deployment\"}]},{\"text\":\"Integrate\",\"items\":[{\"text\":\"API docs (interactive)\",\"link\":\"https://piwitests.github.io/demo/docs\"},{\"text\":\"MCP server\",\"link\":\"/mcp\"},{\"text\":\"Open in IDE\",\"link\":\"/ide-integration\"},{\"text\":\"Backend logs\",\"link\":\"/backend-logs\"}]}],\"editLink\":{\"pattern\":\"https://github.com/PiwiTests/platform/edit/main/docs/:path\",\"text\":\"Edit this page on GitHub\"},\"lastUpdated\":{\"text\":\"Updated at\",\"formatOptions\":{\"dateStyle\":\"full\",\"timeStyle\":\"medium\"}},\"socialLinks\":[{\"icon\":\"github\",\"link\":\"https://github.com/PiwiTests/platform\"}],\"externalLinkIcon\":true,\"footer\":{\"message\":\"Released under the MIT License. Zero telemetry — Piwi never phones home.<br>Piwi Dashboard is not affiliated with, endorsed by, or connected to Microsoft Corporation. Playwright is a trademark of Microsoft.\",\"copyright\":\"Copyright © 2025-present Fabien Ménager\"}},\"locales\":{},\"scrollOffset\":134,\"cleanUrls\":false}");</script>
</body>
</html>