<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Linux &#8211; Erik Makes Things</title>
	<atom:link href="https://erikmakesthings.ddns.net/category/linux/feed/" rel="self" type="application/rss+xml" />
	<link>https://erikmakesthings.ddns.net</link>
	<description></description>
	<lastBuildDate>Fri, 25 Jul 2025 23:24:13 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://erikmakesthings.ddns.net/wp-content/uploads/2025/06/cropped-E-3-32x32.png</url>
	<title>Linux &#8211; Erik Makes Things</title>
	<link>https://erikmakesthings.ddns.net</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Securing passwords with Vaultwarden + Apache</title>
		<link>https://erikmakesthings.ddns.net/securing-passwords-with-vaultwarden-apache/</link>
					<comments>https://erikmakesthings.ddns.net/securing-passwords-with-vaultwarden-apache/#respond</comments>
		
		<dc:creator><![CDATA[Erik]]></dc:creator>
		<pubDate>Fri, 25 Jul 2025 23:24:13 +0000</pubDate>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[Cybersecurity]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Server]]></category>
		<guid isPermaLink="false">https://erikmakesthings.ddns.net/?p=286</guid>

					<description><![CDATA[As any cybersecurity-conscious person will tell you, password managers are one of the easiest and most effective tools for protecting your digital life. They encourage you to create long, unique, and complex passwords for every website and service, no more recycling the same weak password everywhere. Now, sure, you could use something like KeePass and [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>As any cybersecurity-conscious person will tell you, password managers are one of the easiest and most effective tools for protecting your digital life. They encourage you to create long, unique, and complex passwords for every website and service, no more recycling the same weak password everywhere.</p>



<p>Now, sure, you could use something like KeePass and keep it local to your machine. That works great if you&#8217;re mostly tied to one device. But if you&#8217;re like me—always bouncing between machines, phones, and maybe even the occasional tablet, you&#8217;ll probably want something a little more accessible.</p>



<p>That’s where <strong>Vaultwarden</strong> comes in. It’s a lightweight, self-hosted fork of Bitwarden, the open-source password manager. With Vaultwarden, you get to use the official Bitwarden mobile apps and browser extensions, but with a leaner backend that’s easier to run on your own server. It’s fast, minimal, and you keep control of your own data.</p>



<h2 class="wp-block-heading">The Setup</h2>



<p>You’ll need a few things before we  get started:</p>



<ul class="wp-block-list">
<li>A server with <strong>Docker</strong> installed</li>



<li>The <strong>Apache</strong> web server</li>



<li>A <strong>domain name</strong></li>



<li>An <strong>SSL certificate</strong> (we’ll use Let’s Encrypt)</li>



<li>Port <code>443</code> open on your firewall (or another port if you&#8217;re using a custom setup)</li>
</ul>



<p>If you’re already running services on your host’s port 443 like I am, you can remap Vaultwarden’s container to a different internal port and let Apache handle the HTTPS proxying.</p>



<h2 class="wp-block-heading">Apache</h2>



<p>Once you’ve got Docker, Apache, and your domain ready, it’s time to configure your reverse proxy.</p>



<p>Create a new config file for Vaultwarden at /etc/apache2/sites-available/vaultwarden.conf. Here is a template you can use for your setup.</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>&lt;IfModule mod_ssl.c>
&lt;VirtualHost *:80>
    ServerName your_domain
    Redirect permanent / https://your_domain/
&lt;/VirtualHost>

&lt;VirtualHost *:443>
    ServerName your_domain

    SSLEngine on
    SSLProxyEngine on

    SSLCertificateFile /etc/letsencrypt/live/your_domain/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/your_domain/privkey.pem

    ProxyPreserveHost On
    ProxyRequests Off

    ProxyPass / http://127.0.0.1:8443/
    ProxyPassReverse / http://127.0.0.1:8443/

    # WebSocket support
    RewriteEngine On
    RewriteCond %{HTTP:UPGRADE} ^(.*)$ &#91;NC&#93;
    RewriteCond %{HTTP:CONNECTION} ^(.*Upgrade.*)$ &#91;NC&#93;
    RewriteRule ^/?(.*) "ws://127.0.0.1:8443/$1" &#91;P,L&#93;

    RequestHeader set X-Forwarded-Proto "https"
    RequestHeader set X-Forwarded-Port "443"

    ErrorLog ${APACHE_LOG_DIR}/vaultwarden-error.log
    CustomLog ${APACHE_LOG_DIR}/vaultwarden-access.log combined
&lt;/VirtualHost>
&lt;/IfModule>
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">&lt;</span><span style="color: #8FBCBB">IfModule</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">mod_ssl.c&gt;</span></span>
<span class="line"><span style="color: #D8DEE9">&lt;VirtualHost</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">*:80&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">ServerName</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">your_domain</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">Redirect</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">permanent</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">/</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">https://your_domain/</span></span>
<span class="line"><span style="color: #D8DEE9">&lt;/VirtualHost&gt;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9">&lt;VirtualHost</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">*:443&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">ServerName</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">your_domain</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">SSLEngine</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">on</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">SSLProxyEngine</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">on</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">SSLCertificateFile</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">/etc/letsencrypt/live/your_domain/fullchain.pem</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">SSLCertificateKeyFile</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">/etc/letsencrypt/live/your_domain/privkey.pem</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">ProxyPreserveHost</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">On</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">ProxyRequests</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">Off</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">ProxyPass</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">/</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">http://127.0.0.1:8443/</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">ProxyPassReverse</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">/</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">http://127.0.0.1:8443/</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">#</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">WebSocket</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">support</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">RewriteEngine</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">On</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">RewriteCond</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">%{HTTP:UPGRADE}</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">^(.*)$</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">&#91;NC&#93;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">RewriteCond</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">%{HTTP:CONNECTION}</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">^(.*Upgrade.*)$</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">&#91;NC&#93;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">RewriteRule</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">^/?(.*)</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">ws://127.0.0.1:8443/$1</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">&#91;P,L&#93;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">RequestHeader</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">set</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">X-Forwarded-Proto</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">https</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">RequestHeader</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">set</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">X-Forwarded-Port</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">443</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">ErrorLog</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">${APACHE_LOG_DIR}/vaultwarden-error.log</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">CustomLog</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">${APACHE_LOG_DIR}/vaultwarden-access.log</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">combined</span></span>
<span class="line"><span style="color: #D8DEE9">&lt;/VirtualHost&gt;</span></span>
<span class="line"><span style="color: #D8DEE9">&lt;/IfModule&gt;</span></span>
<span class="line"></span></code></pre></div>



<p>Then enable the required Apache modules:</p>



<ul class="wp-block-list">
<li>a2enmod proxy</li>



<li>a2enmod proxy_http</li>



<li>a2enmod proxy_wstunnel</li>



<li>a2enmod ssl</li>



<li>a2enmod rewrite</li>
</ul>



<p>Now all you should need to do is enable your site and restart apache.</p>



<h2 class="wp-block-heading">Docker</h2>



<p>Next all you need to do is to setup the docker container. Below is a template for the command  to set it up. Once it’s running, visit <code>https://your_domain</code> in your browser. You should be greeted with the account creation screen. Go ahead and register your account. After that, <strong>be sure to disable public signups</strong> by either updating the container or setting <code>SIGNUPS_ALLOWED=false</code> in your Docker environment.</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>
sudo docker run -d   --name vaultwarden   -v /vw-data:/data   -p 8443:80   -e WEBSOCKET_ENABLED=true   -e SIGNUPS_ALLOWED=true   -e DOMAIN=https://your_domain   vaultwarden/server:latest</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"></span>
<span class="line"><span style="color: #D8DEE9">sudo</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">docker</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">run</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">d</span><span style="color: #D8DEE9FF">   </span><span style="color: #81A1C1">--</span><span style="color: #D8DEE9">name</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">vaultwarden</span><span style="color: #D8DEE9FF">   </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">v</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">vw</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">data</span><span style="color: #ECEFF4">:</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">data</span><span style="color: #D8DEE9FF">   </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">p</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">8443</span><span style="color: #D8DEE9FF">:</span><span style="color: #B48EAD">80</span><span style="color: #D8DEE9FF">   </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">e</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">WEBSOCKET_ENABLED</span><span style="color: #81A1C1">=true</span><span style="color: #D8DEE9FF">   </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">e</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">SIGNUPS_ALLOWED</span><span style="color: #81A1C1">=true</span><span style="color: #D8DEE9FF">   </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">e</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">DOMAIN</span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF">https</span><span style="color: #ECEFF4">:</span><span style="color: #616E88">//your_domain   vaultwarden/server:latest</span></span></code></pre></div>



<h2 class="wp-block-heading">Email Setup (optional)</h2>



<p>If you want features like password reset links for other accounts on your server, account verification emails, admin invites, and emergency access notifications, you’ll want to hook up SMTP.</p>



<p>Here’s how to do it with a Gmail account (you’ll need to generate an <a>App Password</a>):</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>-e SMTP_HOST=smtp.gmail.com
-e SMTP_FROM=your_account@gmail.com
-e SMTP_PORT=587
-e SMTP_USERNAME=your_account@gmail.com
-e SMTP_PASSWORD=your_gmail_app_password
-e SMTP_SECURITY=starttls</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">e</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">SMTP_HOST</span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9">smtp</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">gmail</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">com</span></span>
<span class="line"><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">e</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">SMTP_FROM</span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9">your_account</span><span style="color: #D8DEE9FF">@</span><span style="color: #D8DEE9">gmail</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">com</span></span>
<span class="line"><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">e</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">SMTP_PORT</span><span style="color: #81A1C1">=</span><span style="color: #B48EAD">587</span></span>
<span class="line"><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">e</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">SMTP_USERNAME</span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9">your_account</span><span style="color: #D8DEE9FF">@</span><span style="color: #D8DEE9">gmail</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">com</span></span>
<span class="line"><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">e</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">SMTP_PASSWORD</span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9">your_gmail_app_password</span></span>
<span class="line"><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">e</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">SMTP_SECURITY</span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9">starttls</span></span></code></pre></div>



<p>Add those to your <code>docker run</code> command or define them in a <code>.env</code> file if you’re using <code>docker-compose</code>.</p>



<p>Once email is working, you’ll be able to:</p>



<ul class="wp-block-list">
<li>Send password reset links to other users on your server</li>



<li>Verify email addresses</li>



<li>Invite users to your instance</li>



<li>Get alerts for emergency access requests</li>
</ul>



<p>It’s a small step that adds a ton of functionality.</p>



<h2 class="wp-block-heading">Enjoy Being Secure</h2>



<p>And that’s it. You’ve got a secure, open-source, cloud-accessible password manager running on your own terms, with all the modern comforts like mobile and browser integration. No monthly fees. No trusting a third-party service with your credentials. Just you, your server, and full control over your security.</p>



<p>Welcome to the self-hosted club.</p>



<figure class="wp-block-image aligncenter size-full is-resized"><img fetchpriority="high" decoding="async" width="498" height="280" src="https://erikmakesthings.ddns.net/wp-content/uploads/2025/07/pretty-cool-james-pumphrey.gif" alt="" class="wp-image-288" style="width:1140px;height:auto"/></figure>
]]></content:encoded>
					
					<wfw:commentRss>https://erikmakesthings.ddns.net/securing-passwords-with-vaultwarden-apache/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Making Reading Great Again (with Kavita)</title>
		<link>https://erikmakesthings.ddns.net/making-reading-great-again-with-kavita/</link>
					<comments>https://erikmakesthings.ddns.net/making-reading-great-again-with-kavita/#respond</comments>
		
		<dc:creator><![CDATA[Erik]]></dc:creator>
		<pubDate>Thu, 10 Jul 2025 07:35:51 +0000</pubDate>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[Kavita]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Server]]></category>
		<guid isPermaLink="false">https://erikmakesthings.ddns.net/?p=274</guid>

					<description><![CDATA[I love that reading is free, you can do it anywhere. You can do it on the train&#8230; uh, don&#8217;t do it while you&#8217;re driving &#8211; James Pumphrey When I was younger I used to avidly enjoy reading in my free time. From adventures in a galaxy far, far away (shoutout Karen Traviss), to the [&#8230;]]]></description>
										<content:encoded><![CDATA[
<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>I love that reading is free, you can do it anywhere. You can do it on the train&#8230; uh, don&#8217;t do it while you&#8217;re driving</p>
</blockquote>



<p>&#8211; James Pumphrey</p>



<p>When I was younger I used to avidly enjoy reading in my free time. From adventures in a galaxy far, far away (shoutout Karen Traviss), to the neo-Greek mythology of the Percy Jackson series, I tore through books like it was my job. However, as I’ve gotten older that’s no longer the case. Between work and school, most of my reading now consists of dry technical manuals, textbooks, and reviews for whatever power tool I want to buy next.</p>



<p>So the goal of this project is to make whatever book I’m reading:</p>



<ol class="wp-block-list">
<li>Easily accessible</li>



<li>Simple to pick up right where I left off</li>



<li>Replaceable when I’m ready to crack open the next one</li>
</ol>



<p>Join me as we <strong>Make Reading Great Again</strong> so I have no excuse not to be well-read.</p>



<figure class="wp-block-image aligncenter size-full"><img decoding="async" width="500" height="281" src="https://erikmakesthings.ddns.net/wp-content/uploads/2025/07/catreading.gif" alt="" class="wp-image-275"/></figure>



<h2 class="wp-block-heading">Picking a Platform</h2>



<p>Obviously, the first thing I could do to achieve this goal would be to open up my wallet and head to the nearest app store to get an e-reader service like Bezos’s Kindle or Google’s Shelf and start building a digital library that I don’t really own. But the easy way has some huge red flags. For example, say they lose the licensing or worse, <em>1984</em> comes to pass and certain books get banned and <em>poof</em>, there goes my book and my money.</p>



<p>Also, if you’ve read any of my posts so far you’re probably aware that I’m definitely a DIY kind of guy, and like with most things I’m going to do it myself.</p>



<p>So what are the options for self-hosting this kind of service? As you can tell from the title, I went with <strong>Kavita</strong> for its multi-user support, anywhere access, and mainly because I liked the UI the most. But there are other great options I stumbled upon that might suit your needs better:</p>



<ul class="wp-block-list">
<li><strong>Calibre</strong> for its wider format support and plugins.</li>



<li><strong>Komga</strong> if your main focus is comics and manga.</li>



<li><strong>Polar Bookshelf</strong> if you just want to install a Snap package and enjoy books locally.</li>
</ul>



<h2 class="wp-block-heading">The Set Up</h2>



<p>For this setup I’ll be using Kavita’s Docker image. There are plenty of ways to set it up, but for that I’ll refer you to their instructional page here: <a class="" href="https://wiki.kavitareader.com/getting-started/">https://wiki.kavitareader.com/getting-started/</a>.</p>



<p>I like using <strong>Portainer</strong> to set up and manage my Docker containers since it’s simple and easy. Remember to create your volume first, set your port mapping to 5000, and set the network adapter to bridge before pulling and creating the container.</p>



<p>Once it’s up and running you’re good to go to http://your-server-ip:5000, and you should be greeted with a simple sign-in screen to create your admin account. After you create your account and log in, the last thing is to load up something to read and create your libraries. Kavita supports formats like PDF, EPUB, and a variety of comic/manga formats.</p>



 [<a href="https://erikmakesthings.ddns.net/making-reading-great-again-with-kavita/">See image gallery at erikmakesthings.ddns.net</a>] 



<p>To make this all work you’ll need to create a folder and place each file in that folder. For example, my copy of <em>Pride and Prejudice</em> from <a class="" href="https://www.epubbooks.com/book/44-pride-and-prejudice">epubbooks.com</a> is mounted like this:</p>



<pre class="wp-block-code"><code>/storage/books/'Pride and Prejudice (Illustrated)'/austen-pride-and-prejudice-illustrations.epub
</code></pre>



<p>Now that you have your books loaded up, create a library by clicking on the gear icon in the top left, navigating to the Libraries tab under Server, and clicking on the <strong>Add Library</strong> button. In the popup, give it a name and point it to the folder you mounted with your media. I decided to split my libraries into books, comics, and manga.</p>



<h2 class="wp-block-heading">Mr. Worldwide </h2>



<p>You can stop here if you only want access to your e-library locally, but I decided to take it a step further. To access the library securely from anywhere in the world, I created a domain name with NO-IP, used Certbot to generate some SSL certificates, and created and enabled my .conf file.</p>



<p>That’s right, eriks-library (e-library for short) can now be accessed anywhere with an internet connection.</p>



<p>If you want to do this too, there are more detailed instructions in Kavita’s setup guide I linked earlier. Or if you’re using Apache2, you can copy, edit, and enable the slightly trimmed-down config file I made for the reverse proxy:</p>



<pre class="wp-block-code"><code>&lt;IfModule mod_ssl.c&gt;
&lt;VirtualHost *:443&gt;
    ServerName your.domain.com

    SSLEngine on
    SSLProxyEngine on
    SSLProxyCheckPeerCN off
    SSLProxyCheckPeerName off
    SSLProxyCheckPeerExpire off

    # Use Let's Encrypt certificate paths
    SSLCertificateFile /etc/letsencrypt/live/your.domain.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/your.domain.com/privkey.pem

    ErrorLog ${APACHE_LOG_DIR}/proxy-error.log
    CustomLog ${APACHE_LOG_DIR}/proxy-access.log combined

    ProxyPass / http://SERVER_IP_ADDR:5000/
    ProxyPassReverse / http://SERVER_IP_ADDR:5000/

    ProxyPreserveHost On
    ProxyRequests Off

    # WebSocket support
    RewriteEngine On
    RewriteCond %{HTTP:UPGRADE} ^.*WebSocket.*$ &#091;NC]
    RewriteCond %{HTTP:CONNECTION} ^.*Upgrade.*$ &#091;NC]
    RewriteRule .* ws://SERVER_IP_ADDR:5000%{REQUEST_URI} &#091;P]

    RequestHeader set X-Forwarded-Proto "https"
    RequestHeader set X-Forwarded-Port "443"
    RequestHeader set X-Forwarded-For "%{REMOTE_ADDR}e"
&lt;/VirtualHost&gt;
&lt;/IfModule&gt;
</code></pre>



<h2 class="wp-block-heading">On the Go</h2>



<p>The last step was figuring out how I’m going to access and enjoy my library from my phone. Currently, there’s only a third-party app called <strong>Kavita Blue</strong>, but when I tried it, it kept freezing and ruined the UI I like. So I just opened up Chrome on my phone, navigated to my domain, and set it up as a web app on my home screen. Sure, I could have paid for a Kindle subscription, but where’s the fun in that? Besides, now I get to say my library runs on Docker and that sounds way cooler at parties anyways.</p>



<figure class="wp-block-video aligncenter"><video height="1584" style="aspect-ratio: 720 / 1584;" width="720" controls src="https://erikmakesthings.ddns.net/wp-content/uploads/2025/07/webapp.mp4"></video></figure>
]]></content:encoded>
					
					<wfw:commentRss>https://erikmakesthings.ddns.net/making-reading-great-again-with-kavita/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		<enclosure url="https://erikmakesthings.ddns.net/wp-content/uploads/2025/07/webapp.mp4" length="7146987" type="video/mp4" />

			</item>
		<item>
		<title>My Home Lab</title>
		<link>https://erikmakesthings.ddns.net/my-home-lab/</link>
					<comments>https://erikmakesthings.ddns.net/my-home-lab/#respond</comments>
		
		<dc:creator><![CDATA[Erik]]></dc:creator>
		<pubDate>Sun, 18 May 2025 03:05:42 +0000</pubDate>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Network]]></category>
		<category><![CDATA[Nextcloud]]></category>
		<category><![CDATA[Plex]]></category>
		<category><![CDATA[Server]]></category>
		<category><![CDATA[Homelab]]></category>
		<category><![CDATA[LLM]]></category>
		<guid isPermaLink="false">https://erikmakesthings.ddns.net/?p=97</guid>

					<description><![CDATA[The internet is not something that you just dump something on, it’s not a big truck, it’s, it’s a series of tubes! -U.S. Senator Ted Stevens My home lab has been a fun, though sometimes time-consuming, hobby I’ve built up over the last few years. Currently, my self-hosted services include network wide ad blocking, cloud [&#8230;]]]></description>
										<content:encoded><![CDATA[
<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>The internet is not something that you just dump something on, it’s not a big truck, it’s, it’s a series of tubes!</p>
</blockquote>



<p>-U.S. Senator Ted Stevens  </p>



<p>My home lab has been a fun, though sometimes time-consuming, hobby I’ve built up over the last few years. Currently, my self-hosted services include network wide ad blocking, cloud storage, multiple websites, media streaming, smart home controls, and even a local LLM. That’s right, the post you’re reading right now is hosted <em>locally</em> from my home office! But how did I get into all of this, and is it really worth it? <em>[Cue Vsauce theme music]</em></p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe title="Hey, Vsauce Michael Here..." width="500" height="281" src="https://www.youtube.com/embed/JwYzHW_q3c4?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



<h2 class="wp-block-heading">We All Start Somewhere&#8230;</h2>



<p>Back in 2021, I started self-hosting a cloud storage solution, Nextcloud, in a virtual machine to replace my Google Drive and Photos since I was running out of space. After running it for a while and making small tweaks, I finally decided to invest in dedicated hardware, funded by selling off my DIY mining rigs. To save some cash, I sourced as many second-hand parts as possible. In total I think I have spent around  $1800 for all of the hardware, networking equipment, and battery backups.</p>



<p class="has-text-align-center"><strong>Current Parts List</strong></p>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:100%">
<ul class="wp-block-list">
<li><strong>Case:</strong> Antec case (Goodwill)</li>



<li><strong>PSU:</strong> Rosewill 1000 Watt (Recycled)</li>



<li><strong>MOBO:</strong> Asus Prime-P (Second hand)</li>



<li><strong>CPU:</strong> 5700G (New)</li>



<li><strong>GPU:</strong> Nvidia a2000 6GB (Second hand)</li>



<li><strong>RAM:</strong> 64 GB DDR4 (New)</li>



<li><strong>Cooler:</strong> be quite! (Second hand)</li>



<li><strong>Drives:</strong> Various types adding up to 15TB (New)</li>



<li><strong>Fans:</strong> 3 Noctua NF-P12 (New)</li>
</ul>
</div>
</div>



<h2 class="wp-block-heading">Current Setup and Services</h2>



<p>I’m running Ubuntu Server<strong> </strong>as the OS for my home server. It’s connected to a<strong> </strong>CyberPower 900W UPS<strong> </strong>and is configured to gracefully shut down after five minutes of power loss and automatically restart when power is restored.</p>



<p>Here’s a quick overview of what’s running:</p>



 [<a href="https://erikmakesthings.ddns.net/my-home-lab/">See image gallery at erikmakesthings.ddns.net</a>] 



<h2 class="wp-block-heading">Nextcloud</h2>



<p>Nextcloud has been my longest-running self-hosted service. I started with the Snap package, moved to the Docker container, and now run it directly on bare metal. It’s been my dedicated data storage and sharing solution for years, helping me centralize family photos and documents for sharing and safe keeping. With the addition of the Nvidia A2000 GPU, I also integrated facial recognition software to organize photos by faces and objects, all handled locally! Nextcloud is a great way to secure, share, and store your data.</p>



 [<a href="https://erikmakesthings.ddns.net/my-home-lab/">See image gallery at erikmakesthings.ddns.net</a>] 



<h2 class="wp-block-heading">WordPress</h2>



<p>WordPress is my CMS of choice for both my website and my significant other’s. It helps me create, organize, and publish content like this post! With a massive library of plugins, you can do almost anything, provided you’re willing to learn. I’m also looking forward to my web development class next semester to better customize my site using PHP!</p>



<p>If you’re thinking about doing something similar, it’s totally doable in an afternoon:</p>



<ol class="wp-block-list">
<li>Set up a LAMP server</li>



<li>Register a domain</li>



<li>Grab SSL certificates through Let’s Encrypt</li>



<li>And you’re off and running!</li>
</ol>



<h2 class="wp-block-heading">Docker</h2>



<ul class="wp-block-list"></ul>



<ul class="wp-block-list"></ul>



<p>Docker is a must-have tool for any home lab. I use Portainer to manage my containers, including Home Assistant, which runs most of my smart home, and the web portal for Ollama. Eventually, I plan to phase out my Nest Hubs and replace them with local Home Assistant voice devices. With Ollama, I’ve set up a local AI interface where I can interact with various models like R1, Ollama3, and Arena to quickly access information, all without relying on the cloud!</p>



 [<a href="https://erikmakesthings.ddns.net/my-home-lab/">See image gallery at erikmakesthings.ddns.net</a>] 



<h2 class="wp-block-heading">Plex</h2>



<p>Plex has been my go-to media streaming solution for years. I even bought the lifetime pass to support the developers and unlock hardware encoding. But lately, the Android app has become a mess, and the new UI is cluttered with freemium TV services I didn’t ask for. I’m considering switching to Emby or Jellyfin, but for now Plex still does the job for enjoying and sharing my media collection with my friends and family.</p>



<figure class="wp-block-image size-large"><img decoding="async" width="1024" height="507" src="https://erikmakesthings.ddns.net/wp-content/uploads/2025/05/Screenshot-2025-05-17-195439-1024x507.png" alt="" class="wp-image-115" srcset="https://erikmakesthings.ddns.net/wp-content/uploads/2025/05/Screenshot-2025-05-17-195439-1024x507.png 1024w, https://erikmakesthings.ddns.net/wp-content/uploads/2025/05/Screenshot-2025-05-17-195439-300x149.png 300w, https://erikmakesthings.ddns.net/wp-content/uploads/2025/05/Screenshot-2025-05-17-195439-768x381.png 768w, https://erikmakesthings.ddns.net/wp-content/uploads/2025/05/Screenshot-2025-05-17-195439-1536x761.png 1536w, https://erikmakesthings.ddns.net/wp-content/uploads/2025/05/Screenshot-2025-05-17-195439-2048x1015.png 2048w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading">The Net&#8230;</h2>



<p>I know this post is getting long, so let’s wrap it up with a quick overview of my network gear. I recently upgraded to a Ubiquiti system with the USG-MAX and U7-XGS AP. This setup lets me segment my network with VLANs, secure traffic using IPS, and enjoy blazing-fast Wi-Fi 7 speeds, up to 1300 Mbps up and down on my LAN. On top of that, I’m running a Raspberry Pi 2B as a network-wide ad blocker using Pi-hole.</p>



 [<a href="https://erikmakesthings.ddns.net/my-home-lab/">See image gallery at erikmakesthings.ddns.net</a>] 



<h2 class="wp-block-heading">That&#8217;s All Folks&#8230;</h2>



<p>Building out my home lab has been a fun and rewarding experience that’s expanded my skills and deepened my understanding of the “series of tubes” that is the internet. Self-hosting is a great way to learn, gain practical experience, and even save money in the long run. I’ll probably write more detailed posts on each of these services in the future, but for now thanks for reading! I hope this gives you some ideas for building out your own home lab.</p>



<figure class="wp-block-image aligncenter size-full"><img loading="lazy" decoding="async" width="640" height="542" src="https://erikmakesthings.ddns.net/wp-content/uploads/2025/05/ltt-linus-piggers.gif" alt="" class="wp-image-124"/></figure>



<h2 class="wp-block-heading">Links To Get Started&#8230;</h2>



<ul class="wp-block-list">
<li>Nextcloud: <a href="https://docs.nextcloud.com/server/latest/admin_manual/installation/">https://docs.nextcloud.com/server/latest/admin_manual/installation/</a></li>



<li>Plex: <a href="https://support.plex.tv/articles/200288586-installation/">https://support.plex.tv/articles/200288586-installation/</a></li>



<li>Home Assistant: <a href="https://www.home-assistant.io/getting-started">https://www.home-assistant.io/getting-started</a></li>



<li>Pi-Hole: <a href="https://pi-hole.net/">https://pi-hole.net/</a></li>



<li>Ollama: <a href="https://ollama.com/download">https://ollama.com/download</a></li>
</ul>
]]></content:encoded>
					
					<wfw:commentRss>https://erikmakesthings.ddns.net/my-home-lab/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
