<?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>Apache &#8211; Erik Makes Things</title>
	<atom:link href="https://erikmakesthings.ddns.net/category/apache/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>Apache &#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>
	</channel>
</rss>
