<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Static-Web-Server on blog.iankulin.com</title><link>https://blog.iankulin.com/tags/static-web-server/</link><description>Recent content in Static-Web-Server on blog.iankulin.com</description><generator>Hugo</generator><language>en-AU</language><lastBuildDate>Mon, 22 Apr 2024 00:00:00 +0000</lastBuildDate><atom:link href="https://blog.iankulin.com/tags/static-web-server/index.xml" rel="self" type="application/rss+xml"/><item><title>Virtual Hosts on "Static Web Server"</title><link>https://blog.iankulin.com/virtual-hosts-on-static-web-server/</link><pubDate>Mon, 22 Apr 2024 00:00:00 +0000</pubDate><guid>https://blog.iankulin.com/virtual-hosts-on-static-web-server/</guid><description>&lt;p&gt;I&amp;rsquo;ve been running &lt;a href="https://blog.iankulin.com/nginx-proxy-manager/"&gt;NGINX Proxy Manager&lt;/a&gt; (NPM) in my homelab for a bit, and I&amp;rsquo;ve been meaning to clean up the VPS that runs most of my websites and public facing servers, so I&amp;rsquo;m considering running NGINX Proxy Manager on that VPS. While NGINX Proxy Manager wraps up the configs in a beautiful GUI, in the process you lose some of NGINXs capabilities. In particular there&amp;rsquo;s no GUI way to serve static virtual hosts from NGINX Proxy Manager.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s a pity, since it seems like it wouldn&amp;rsquo;t be a lot of work, but in any case we can easily just run another web server and proxy to it. I guess I could run another instance of NGINX, but on $5 VPSs memory is a bit scarce, and since my sites are extremely low traffic, perhaps something a bit lighter is in order.&lt;/p&gt;
&lt;p&gt;An option mentioned in several posts for this exact situation is the very well named &lt;a href="https://static-web-server.net/"&gt;Static Web Server&lt;/a&gt;. It&amp;rsquo;s written in Rust, the docker image is less that 10MB, and it claims to be able to serve for virtual hosts. Let&amp;rsquo;s give it a try.&lt;/p&gt;
&lt;h3 id="directory-structure"&gt;Directory Structure&lt;/h3&gt;
&lt;p&gt;My routine setup now is that everything runs in docker. There&amp;rsquo;s a directory under the home directory of my user for named for the container which holds the &lt;code&gt;docker-compose.yml&lt;/code&gt;. Underneath that there&amp;rsquo;s two sub-directories: &lt;code&gt;data&lt;/code&gt; - which holds all the app data, and &lt;code&gt;config&lt;/code&gt; - which holds the app settings files.&lt;/p&gt;
&lt;p&gt;In the data directory, I want to have sub-directories for each virtual host, then inside them a &lt;code&gt;public&lt;/code&gt; directory which will hold the files to be served. This will allow me to keep config or other files for each virtual host in the directory above &lt;code&gt;public&lt;/code&gt; which should not be accessible. That seems like a good arrangement so I can manage each virtual host in git and pull the sites down from a repository into their directory without things like the &lt;code&gt;.gitignore&lt;/code&gt; being exposed to the world.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://blog.iankulin.com/images/screen-shot-2024-04-20-at-8.15.14-pm.png"&gt;&lt;img src="https://blog.iankulin.com/images/screen-shot-2024-04-20-at-8.15.14-pm.png" width="900" alt=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m running Tailscale on this VM, so it can be referred to by any of the addresses &lt;code&gt;100.124.218.26&lt;/code&gt;, &lt;code&gt;192.168.100.35&lt;/code&gt; or &lt;code&gt;ct357-sws&lt;/code&gt;. These are going to be stand- ins for the different virtual host names. The index.html files you can see are all different; I&amp;rsquo;ve edited them so each one just outputs the name of the directory it is being served from. eg:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://blog.iankulin.com/images/screen-shot-2024-04-20-at-9.20.26-pm.png"&gt;&lt;img src="https://blog.iankulin.com/images/screen-shot-2024-04-20-at-9.20.26-pm.png" width="900" alt=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="docker"&gt;Docker&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;version&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; &lt;span style="color:#a3be8c"&gt;&amp;#34;3.3&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;services&lt;span style="color:#eceff4"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; website&lt;span style="color:#eceff4"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; image&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; joseluisq&lt;span style="color:#81a1c1"&gt;/&lt;/span&gt;&lt;span style="color:#81a1c1;font-weight:bold"&gt;static&lt;/span&gt;&lt;span style="color:#81a1c1"&gt;-&lt;/span&gt;web&lt;span style="color:#81a1c1"&gt;-&lt;/span&gt;server&lt;span style="color:#eceff4"&gt;:&lt;/span&gt;&lt;span style="color:#b48ead"&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; container_name&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; &lt;span style="color:#a3be8c"&gt;&amp;#34;sws&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ports&lt;span style="color:#eceff4"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#81a1c1"&gt;-&lt;/span&gt; &lt;span style="color:#b48ead"&gt;80&lt;/span&gt;&lt;span style="color:#eceff4"&gt;:&lt;/span&gt;&lt;span style="color:#b48ead"&gt;80&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; restart&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; unless&lt;span style="color:#81a1c1"&gt;-&lt;/span&gt;stopped
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; environment&lt;span style="color:#eceff4"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#81a1c1"&gt;-&lt;/span&gt; SERVER_CONFIG_FILE&lt;span style="color:#81a1c1"&gt;=/&lt;/span&gt;etc&lt;span style="color:#81a1c1"&gt;/&lt;/span&gt;config&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;toml
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; volumes&lt;span style="color:#eceff4"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#81a1c1"&gt;-&lt;/span&gt; &lt;span style="color:#81a1c1"&gt;./&lt;/span&gt;data&lt;span style="color:#eceff4"&gt;:&lt;/span&gt;&lt;span style="color:#81a1c1"&gt;/&lt;/span&gt;&lt;span style="color:#81a1c1;font-weight:bold"&gt;var&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#81a1c1"&gt;-&lt;/span&gt; &lt;span style="color:#81a1c1"&gt;./&lt;/span&gt;config&lt;span style="color:#81a1c1"&gt;/&lt;/span&gt;config&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;toml&lt;span style="color:#eceff4"&gt;:&lt;/span&gt;&lt;span style="color:#81a1c1"&gt;/&lt;/span&gt;etc&lt;span style="color:#81a1c1"&gt;/&lt;/span&gt;config&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;toml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You&amp;rsquo;re probably familiar with docker-compose by now, but if not, the volumes lines probably need explaining. They map &amp;lsquo;real-world&amp;rsquo; directories on our server, to the internal directories &lt;em&gt;inside&lt;/em&gt; the container. This is a useful thing - we could copy our files into the container but those changes would be ephemeral, they&amp;rsquo;d be gone next time we restart the container. By creating these links, we can store the web server configs and data on our server, but from the point of view of the app, they appear inside.&lt;/p&gt;
&lt;p&gt;An example will make this more concrete, lets look at the first line:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#81a1c1"&gt;-&lt;/span&gt; &lt;span style="color:#81a1c1"&gt;./&lt;/span&gt;data&lt;span style="color:#eceff4"&gt;:&lt;/span&gt;&lt;span style="color:#81a1c1"&gt;/&lt;/span&gt;&lt;span style="color:#81a1c1;font-weight:bold"&gt;var&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is saying that the directory inside the container named &lt;code&gt;/var&lt;/code&gt; is mapped onto the external directory &lt;code&gt;./data&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Consider our file in the tree listing above &lt;code&gt;~/sws/data/100.124.218.26/public/index.html&lt;/code&gt; the web server running inside the container will see that file at &lt;code&gt;/var/100.124.218.26/public/index.html&lt;/code&gt; It seems weird at first, but you soon get used to this sort of container directory mapping maths.&lt;/p&gt;
&lt;h3 id="config"&gt;Config&lt;/h3&gt;
&lt;p&gt;There&amp;rsquo;s excellent documentation about Static Web Server on their &lt;a href="https://static-web-server.net/"&gt;web site&lt;/a&gt;, so I&amp;rsquo;m not going to go through the whole &lt;code&gt;config.toml&lt;/code&gt; file, in any case, I&amp;rsquo;ve left nearly everything on the defaults. Instead, lets scroll down to the bottom and look at the virtual hosts settings.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#eceff4"&gt;[[&lt;/span&gt;advanced&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;virtual&lt;span style="color:#81a1c1"&gt;-&lt;/span&gt;hosts&lt;span style="color:#eceff4"&gt;]]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;host &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; &lt;span style="color:#a3be8c"&gt;&amp;#34;100.124.218.26&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;root &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; &lt;span style="color:#a3be8c"&gt;&amp;#34;/var/100.124.218.26/public&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#eceff4"&gt;[[&lt;/span&gt;advanced&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;virtual&lt;span style="color:#81a1c1"&gt;-&lt;/span&gt;hosts&lt;span style="color:#eceff4"&gt;]]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;host &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; &lt;span style="color:#a3be8c"&gt;&amp;#34;ct357-sws&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;root &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; &lt;span style="color:#a3be8c"&gt;&amp;#34;/var/ct357-sws/public&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#eceff4"&gt;[[&lt;/span&gt;advanced&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;virtual&lt;span style="color:#81a1c1"&gt;-&lt;/span&gt;hosts&lt;span style="color:#eceff4"&gt;]]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;host &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; &lt;span style="color:#a3be8c"&gt;&amp;#34;192.168.100.35&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;root &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; &lt;span style="color:#a3be8c"&gt;&amp;#34;/var/192.168.100.35/public&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="it-works"&gt;It works&lt;/h3&gt;
&lt;p&gt;A quick &lt;code&gt;docker compose up -d&lt;/code&gt;, and we&amp;rsquo;re in business.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.iankulin.com/images/screen-shot-2024-04-21-at-8.52.14-pm.png" alt=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.iankulin.com/images/screen-shot-2024-04-21-at-8.57.27-pm.png" alt=""&gt;&lt;/p&gt;</description></item></channel></rss>