<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Harsh Vardhan Pandey]]></title><description><![CDATA[I am an Engineering Student From India.]]></description><link>https://blogs.theharsh.xyz</link><generator>RSS for Node</generator><lastBuildDate>Sun, 19 Apr 2026 12:29:15 GMT</lastBuildDate><atom:link href="https://blogs.theharsh.xyz/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Now You Know How to Self-Host Typesense Using Docker and Caddy — The Easy Way]]></title><description><![CDATA[Introduction
When I was assigned the task of migrating our search infrastructure from Algolia to Typesense, I took it as an opportunity to dive deep into self-hosting and managing search at scale. After exploring the setup, deployment, and optimizati...]]></description><link>https://blogs.theharsh.xyz/now-you-know-how-to-self-host-typesense-using-docker-and-caddy-the-easy-way</link><guid isPermaLink="true">https://blogs.theharsh.xyz/now-you-know-how-to-self-host-typesense-using-docker-and-caddy-the-easy-way</guid><dc:creator><![CDATA[Harsh Vardhan Pandey]]></dc:creator><pubDate>Thu, 09 Oct 2025 17:25:11 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1760031188719/d5c98262-15d2-4a9c-a9c6-22d08cd4ca9e.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="heading-introduction">Introduction</h1>
<p>When I was assigned the task of migrating our search infrastructure from <strong>Algolia to Typesense</strong>, I took it as an opportunity to dive deep into self-hosting and managing search at scale. After exploring the setup, deployment, and optimization process, I successfully migrated everything to <strong>Typesense</strong>, a fast, open-source search engine that gives you full control without the hefty costs.</p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">Our bills for Algolia were around $200-300/Month. After self hosting it came down to mere $10 VPS Cost.</div>
</div>

<p>In this blog, I’ll walk you through how I set up and self-hosted Typesense, configured it with Caddy, and got the Dashboard running securely.</p>
<p>To make things smooth, I used <a target="_blank" href="https://docs.docker.com/compose/"><strong>Docker Compose</strong></a> to manage containers and <a target="_blank" href="https://caddyserver.com/"><strong>Caddy</strong></a> as a reverse proxy for automatic SSL and routing. I also added the <a target="_blank" href="https://github.com/bfritscher/typesense-dashboard"><strong>Typesense Dashboard</strong></a> a lightweight frontend UI that makes managing collections, documents, and search queries much easier.</p>
<p>Last but not the least <strong>I Love Containers</strong>.</p>
<h2 id="heading-what-is-typesense"><strong>What is Typesense?</strong></h2>
<p><strong>Typesense</strong> is an open-source search engine optimized for instant, typo-tolerant, and developer-friendly search. It’s written in C++ and provides a clean RESTful API for indexing and querying data.</p>
<p>Some key features include:</p>
<ul>
<li><p><strong>Instant search</strong> with millisecond response times</p>
</li>
<li><p><strong>Typo tolerance</strong> and relevance ranking</p>
</li>
<li><p><strong>Simple JSON-based API</strong></p>
</li>
<li><p><strong>Built-in API key security</strong></p>
</li>
<li><p><strong>Open-source</strong> and easy to self-host</p>
</li>
</ul>
<p>By self-hosting, you get complete control over configuration, scaling, and security without the recurring costs of managed search platforms.</p>
<h2 id="heading-prerequisites"><strong>Prerequisites</strong></h2>
<p>Before starting, make sure you have the following:</p>
<ul>
<li><p><strong>Docker</strong> installed on your vps</p>
</li>
<li><p><strong>Caddy</strong> installed (for reverse proxy &amp; HTTPS)</p>
</li>
<li><p>A domain name (optional but recommended for SSL)</p>
</li>
<li><p>Basic familiarity with command line and Docker</p>
</li>
</ul>
<p>Tools used:</p>
<ul>
<li><p><strong>Docker Compose</strong> – to orchestrate the Typesense and dashboard containers</p>
</li>
<li><p><strong>Caddy</strong> – to manage SSL and reverse proxy routes automatically</p>
</li>
<li><p><strong>Typesense Dashboard</strong> – a frontend to visually manage your data</p>
</li>
<li><p><strong>VPS</strong> ( EC2, AWS LightSail, Digital Ocean Droplet and Hetzner etc.)</p>
</li>
</ul>
<hr />
<h1 id="heading-setting-up-self-hosted-typesense-with-docker-and-caddy">Setting Up Self-Hosted Typesense with Docker and Caddy</h1>
<p>Let’s now walk through the full setup step-by-step.<br />We’ll be creating three services <strong>Typesense</strong>, <strong>Dashboard</strong>, and <strong>Caddy</strong> all orchestrated using <strong>Docker Compose</strong>.</p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">The Env Config is in the Summary Section</div>
</div>

<h2 id="heading-step-1-setting-up-typesense-with-docker-compose"><strong>Step: 1 - Setting Up Typesense with Docker Compose</strong></h2>
<p>We’ll start by running <strong>Typesense</strong> inside a Docker container.<br />This will be our core search engine backend.</p>
<pre><code class="lang-yaml">  <span class="hljs-attr">typesense:</span>
    <span class="hljs-attr">image:</span> <span class="hljs-string">typesense/typesense:29.0</span>
    <span class="hljs-attr">restart:</span> <span class="hljs-string">on-failure</span>
    <span class="hljs-attr">env_file:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">.env</span>
    <span class="hljs-attr">expose:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">"8108"</span>
    <span class="hljs-attr">volumes:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">./typesense-data:/data</span>
    <span class="hljs-attr">command:</span> <span class="hljs-string">"--data-dir /data --api-key=${TYPESENSE_API_KEY} --enable-cors"</span>
    <span class="hljs-attr">networks:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">typesense-network</span>
</code></pre>
<p><strong>Explanation:</strong></p>
<ul>
<li><p><code>image: typesense/typesense:29.0</code> — uses the official Typesense Docker image.</p>
</li>
<li><p><code>env_file</code> — loads environment variables like <code>TYPESENSE_API_KEY</code> from your <code>.env</code> file.</p>
</li>
<li><p><code>volumes</code> — mounts a local directory <code>./typesense-data</code> to persist indexed data.</p>
</li>
<li><p><code>command</code> — sets the data directory, enables CORS, and provides the API key.</p>
</li>
<li><p><code>expose: 8108</code> — <strong>exposes the internal port</strong> for the reverse proxy (not public).</p>
</li>
</ul>
<p>After this step, Typesense will run internally and listen on port <strong>8108</strong> within the Docker network.</p>
<h2 id="heading-step-2-setting-up-typesense-dashboard-frontend"><strong>Step: 2 - Setting Up Typesense Dashboard Frontend</strong></h2>
<p>Next, we’ll set up the <strong>Typesense Dashboard</strong> a web-based interface to interact with your Typesense instance visually.</p>
<pre><code class="lang-yaml">  <span class="hljs-attr">dashboard:</span>
    <span class="hljs-attr">image:</span> <span class="hljs-string">bfritscher/typesense-dashboard:2.1</span>
    <span class="hljs-attr">restart:</span> <span class="hljs-string">unless-stopped</span>
    <span class="hljs-attr">volumes:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">dashboard_data:/srv</span>
    <span class="hljs-attr">expose:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">"80"</span>
    <span class="hljs-attr">env_file:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">.env</span>
    <span class="hljs-attr">depends_on:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">typesense</span>
    <span class="hljs-attr">networks:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">typesense-network</span>
</code></pre>
<p><strong>Explanation:</strong></p>
<ul>
<li><p><code>bfritscher/typesense-dashboard</code> — lightweight open-source dashboard for Typesense(You can choose the latest version tag).</p>
</li>
<li><p>Uses the same <code>.env</code> file for configuration (so it knows which Typesense host and API key to connect to).</p>
</li>
<li><p><code>depends_on</code> ensures the dashboard starts only after the Typesense service is ready.</p>
</li>
<li><p><code>dashboard_data</code> is mounted as a volume to persist the dashboard’s static files.</p>
</li>
</ul>
<p>After setup, the dashboard runs on <strong>port 80</strong> internally, which we’ll expose securely through Caddy.</p>
<h2 id="heading-step-3-setting-up-caddy-as-a-reverse-proxy"><strong>Step: 3 - Setting Up Caddy as a Reverse Proxy</strong></h2>
<p>Finally, we’ll use <strong>Caddy</strong> to serve both the Typesense API and the Dashboard over HTTPS with automatic SSL certificates from Let’s Encrypt.</p>
<pre><code class="lang-yaml">  <span class="hljs-attr">caddy:</span>
    <span class="hljs-attr">image:</span> <span class="hljs-string">caddy:2.7-alpine</span>
    <span class="hljs-attr">restart:</span> <span class="hljs-string">unless-stopped</span>
    <span class="hljs-attr">ports:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">"80:80"</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">"443:443"</span>
    <span class="hljs-attr">volumes:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">./Caddyfile:/etc/caddy/Caddyfile:ro</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">caddy_data:/data</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">caddy_config:/config</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">dashboard_data:/srv:ro</span>
    <span class="hljs-attr">networks:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">typesense-network</span>
    <span class="hljs-attr">depends_on:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">typesense</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">dashboard</span>
</code></pre>
<p><strong>Explanation:</strong></p>
<ul>
<li><p>The Caddy container automatically handles <strong>HTTP → HTTPS redirection</strong> and SSL certificates.</p>
</li>
<li><p>The <code>Caddyfile</code> defines how traffic is routed to both services.</p>
</li>
<li><p><code>depends_on</code> ensures Caddy starts only after both the backend and dashboard are ready.</p>
</li>
</ul>
<hr />
<h1 id="heading-caddyfile-configuration">Caddyfile Configuration</h1>
<p>Create a <a target="_blank" href="https://caddyserver.com/docs/caddyfile">Caddyfile</a> in the root of your directory</p>
<h2 id="heading-recommended-configuration">Recommended Configuration</h2>
<p>I recommend using a subdomain for your Typesense API, for example, typesense-api.yourdomain.com.</p>
<p>Here’s how you can adjust your Caddyfile to accomplish this:</p>
<h3 id="heading-step-1-update-dns"><strong>Step: 1 - Update DNS</strong></h3>
<p><strong>First, ensure you have DNS "A" records for both the dashboard and the API pointing to your VPS's IP address.</strong></p>
<ul>
<li><p>dashboard.yourdomain.com -&gt; YOUR_VPS_IP</p>
</li>
<li><p>typesense-api.yourdomain.com -&gt; YOUR_VPS_IP</p>
</li>
</ul>
<h3 id="heading-step-2-update-your-caddyfile"><strong>Step: 2 - Update your Caddyfile</strong></h3>
<p>Replace the contents of your Caddyfile with something like this. This will configure Caddy to route traffic for the dashboard and the Typesense API to the correct containers.</p>
<p>Here’s your <strong>Caddyfile</strong> configuration:</p>
<pre><code class="lang-yaml"><span class="hljs-comment"># Caddyfile</span>

<span class="hljs-comment"># Route traffic for the dashboard</span>
<span class="hljs-string">dashboard.yourdomain.com</span> {
    <span class="hljs-comment"># Proxy requests to the dashboard container on its internal port 80</span>
    <span class="hljs-string">reverse_proxy</span> <span class="hljs-string">dashboard:80</span>
}

<span class="hljs-comment"># Route traffic for the Typesense API</span>
<span class="hljs-string">typesense-api.yourdomain.com</span> {
    <span class="hljs-comment"># Proxy requests to the typesense container on its internal port 8108</span>
    <span class="hljs-string">reverse_proxy</span> <span class="hljs-string">typesense:8108</span>
}
</code></pre>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text"><strong>Remember to replace </strong><a target="_self" href><strong>dashboard.yourdomain.com</strong></a><strong> and typesense-api.yourdomain.com with your actual domains.</strong></div>
</div>

<blockquote>
<p><strong>Caddy will automatically handle provisioning and renewing TLS certificates for both subdomains.</strong></p>
</blockquote>
<h3 id="heading-step-3-connect-from-the-dashboard"><strong>Step: 3 - Connect from the Dashboard</strong></h3>
<p>After you restart your services with docker compose up -d, you can now connect from the dashboard UI using:</p>
<ul>
<li><p><strong>Typesense Host:</strong> https://typesense-api.yourdomain.com</p>
</li>
<li><p><strong>Port:</strong> 443</p>
</li>
<li><p><strong>Protocol:</strong> https</p>
</li>
<li><p><strong>API Key:</strong> Your TYPESENSE_API_KEY</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760030405678/b1217f3f-8cc4-4c32-b5ac-3c1f3a2b9626.png" alt class="image--center mx-auto" /></p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">Leave the Path field empty just fill the all other fields and you’re good to go!</div>
</div>

<p>By default the <strong>API key</strong> is set to <strong>xyz,</strong> for <strong>generating your own api key use this curl command.</strong></p>
<pre><code class="lang-bash">curl <span class="hljs-string">'http://localhost:8108/keys'</span> \
    -X POST \
    -H <span class="hljs-string">"X-TYPESENSE-API-KEY: <span class="hljs-variable">${TYPESENSE_API_KEY}</span>"</span> \
    -H <span class="hljs-string">'Content-Type: application/json'</span> \
    -d <span class="hljs-string">'{"description":"Admin key.","actions": ["*"], "collections": ["*"]}'</span>
</code></pre>
<hr />
<h1 id="heading-deploying-on-your-vps">Deploying on Your VPS</h1>
<p>If Docker isn’t already installed, run the following commands on your VPS:</p>
<p>Now that we’ve written our configuration files, it’s time to <strong>deploy everything on a VPS</strong> (Virtual Private Server).</p>
<h2 id="heading-step-1-install-docker-and-docker-compose">Step: 1 - Install Docker and Docker Compose</h2>
<p>If Docker isn’t already installed, run the following commands on your VPS:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Update system packages</span>
sudo apt update -y

<span class="hljs-comment"># Install Docker</span>
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

<span class="hljs-comment"># Install Docker Compose plugin</span>
sudo apt install docker-compose-plugin -y
</code></pre>
<p>Once installed, verify everything is working:</p>
<pre><code class="lang-bash">docker --version
docker compose version
</code></pre>
<p>You should see version numbers printed that means Docker is ready to go.</p>
<h2 id="heading-step-2-clone-your-project">Step: 2 - Clone Your Project</h2>
<p>Next, <strong>clone your project repository</strong> that contains the <code>docker-compose.yml</code> and <code>Caddyfile</code>.</p>
<pre><code class="lang-bash">git <span class="hljs-built_in">clone</span> https://github.com/&lt;your-username&gt;/&lt;your-repo&gt;.git
<span class="hljs-built_in">cd</span> &lt;your-repo&gt;
</code></pre>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">Make sure your <code>.env</code> file is also present in the root directory</div>
</div>

<h2 id="heading-step-3-running-the-setup">Step: 3 - Running the Setup</h2>
<p>Once everything is in place, just run:</p>
<pre><code class="lang-bash">sudo docker compose up -d
</code></pre>
<p>Docker will automatically pull the images for <strong>Typesense</strong>, <strong>Dashboard</strong>, and <strong>Caddy</strong>, and start all three services in the background.</p>
<p>You can check if everything is running with:</p>
<pre><code class="lang-bash">sudo docker ps
</code></pre>
<p>You should see three containers running one each for:</p>
<ul>
<li><p><code>typesense</code></p>
</li>
<li><p><code>dashboard</code></p>
</li>
<li><p><code>caddy</code></p>
</li>
</ul>
<h2 id="heading-step-4-access-your-setup">Step: 4 - Access Your Setup</h2>
<p>Once the setup is live:</p>
<p>Then open:</p>
<ul>
<li><p><strong>Dashboard:</strong> dashboard.yourdomain.com → to access the dashboard UI</p>
</li>
<li><p><strong>API Endpoint:</strong> typesense-api.yourdomain.com/health → to check if Typesense is up (<code>{"ok": true}</code>)</p>
</li>
</ul>
<p>If everything’s configured correctly, Caddy will automatically issue SSL certificates, and you’ll have a fully functional, secure, and visual self-hosted <strong>Typesense setup</strong>.</p>
<hr />
<h1 id="heading-summary">Summary</h1>
<h2 id="heading-final-docker-compose-file"><strong>Final Docker Compose File</strong></h2>
<pre><code class="lang-yaml"><span class="hljs-attr">services:</span>
  <span class="hljs-attr">caddy:</span>
    <span class="hljs-attr">image:</span> <span class="hljs-string">caddy:2.7-alpine</span>
    <span class="hljs-attr">restart:</span> <span class="hljs-string">unless-stopped</span>
    <span class="hljs-attr">ports:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">"80:80"</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">"443:443"</span>
    <span class="hljs-attr">volumes:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">./Caddyfile:/etc/caddy/Caddyfile:ro</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">caddy_data:/data</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">caddy_config:/config</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">dashboard_data:/srv:ro</span>
    <span class="hljs-attr">networks:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">typesense-network</span>
    <span class="hljs-attr">depends_on:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">typesense</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">dashboard</span>

  <span class="hljs-attr">dashboard:</span>
    <span class="hljs-attr">image:</span> <span class="hljs-string">bfritscher/typesense-dashboard:2.1</span>
    <span class="hljs-attr">restart:</span> <span class="hljs-string">unless-stopped</span>
    <span class="hljs-attr">volumes:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">dashboard_data:/srv</span>
    <span class="hljs-attr">expose:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">"80"</span>
    <span class="hljs-attr">env_file:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">.env</span>
    <span class="hljs-attr">depends_on:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">typesense</span>
    <span class="hljs-attr">networks:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">typesense-network</span>

  <span class="hljs-attr">typesense:</span>
    <span class="hljs-attr">image:</span> <span class="hljs-string">typesense/typesense:29.0</span>
    <span class="hljs-attr">restart:</span> <span class="hljs-string">on-failure</span>
    <span class="hljs-attr">env_file:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">.env</span>
    <span class="hljs-attr">expose:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">"8108"</span>
    <span class="hljs-attr">volumes:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">./typesense-data:/data</span>
    <span class="hljs-attr">command:</span> <span class="hljs-string">"--data-dir /data --api-key=${TYPESENSE_API_KEY} --enable-cors"</span>
    <span class="hljs-attr">networks:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">typesense-network</span>

<span class="hljs-attr">networks:</span>
  <span class="hljs-attr">typesense-network:</span>
    <span class="hljs-attr">driver:</span> <span class="hljs-string">bridge</span>

<span class="hljs-attr">volumes:</span>
  <span class="hljs-attr">caddy_data:</span>
  <span class="hljs-attr">caddy_config:</span>
  <span class="hljs-attr">dashboard_data:</span>
</code></pre>
<h2 id="heading-caddyfile">Caddyfile</h2>
<pre><code class="lang-yaml"><span class="hljs-comment"># Caddyfile</span>

<span class="hljs-comment"># Route traffic for the dashboard</span>
<span class="hljs-string">dashboard.yourdomain.com</span> {
    <span class="hljs-comment"># Proxy requests to the dashboard container on its internal port 80</span>
    <span class="hljs-string">reverse_proxy</span> <span class="hljs-string">dashboard:80</span>
}

<span class="hljs-comment"># Route traffic for the Typesense API</span>
<span class="hljs-string">typesense-api.yourdomain.com</span> {
    <span class="hljs-comment"># Proxy requests to the typesense container on its internal port 8108</span>
    <span class="hljs-string">reverse_proxy</span> <span class="hljs-string">typesense:8108</span>
}
</code></pre>
<h2 id="heading-env-file">Env File</h2>
<pre><code class="lang-yaml"><span class="hljs-string">TYPESENSE_API_KEY=YOUR_KEY</span>
<span class="hljs-string">PUBLIC_PATH=/dashboard</span>
<span class="hljs-string">TYPESENSE_HOST=typesense</span>
<span class="hljs-string">TYPESENSE_PORT=8108</span>
<span class="hljs-string">TYPESENSE_PROTOCOL=http</span>
</code></pre>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text"><strong>Replace the typesense api key with your generated admin api key or by default it is xyz.</strong></div>
</div>

<h2 id="heading-example-template-repository">Example Template Repository</h2>
<ul>
<li>Visit this link: <a target="_blank" href="https://github.com/geekyharsh05/typesense-self-hosted-example">https://github.com/geekyharsh05/typesense-self-hosted-example</a></li>
</ul>
<hr />
<h1 id="heading-best-practices-amp-maintenance"><strong>Best Practices &amp; Maintenance</strong></h1>
<p>A few things I learned while running this setup:</p>
<ul>
<li><p><strong>Use persistent volumes</strong> for <code>/data</code> so you don’t lose indexed data on container restart.</p>
</li>
<li><p><strong>Keep your API key secret</strong>, especially if exposing it to the web.</p>
</li>
<li><p><strong>Regularly update images</strong> to stay on the latest Typesense version.</p>
</li>
<li><p><strong>Backup your data</strong> periodically by copying the <code>/data</code> directory.</p>
</li>
<li><p><strong>Monitor logs</strong> via <code>docker logs typesense</code> for any indexing or query errors.</p>
</li>
</ul>
<hr />
<h1 id="heading-conclusion"><strong>Conclusion</strong></h1>
<p>Self-hosting Typesense is surprisingly simple specially with <strong>Docker</strong> and <strong>Caddy</strong>.<br />In a few steps, you can have a fully functional, secure, and visually manageable search engine running on your own infrastructure.</p>
<p>It gives you complete control, scalability, and transparency without the high cost of managed search platforms.<br />If you’re building search into your product, <strong>Typesense</strong> is absolutely worth exploring.</p>
<p>Special Thanks to <a target="_blank" href="https://www.fritscher.ch/">Boris Fritscher</a> the creator of <a target="_blank" href="https://github.com/bfritscher/typesense-dashboard">typesense dashboard</a>.</p>
<p><strong>If you found this guide helpful, follow me on</strong> <a target="_blank" href="https://x.com/geekyharsh_05">X</a><strong>.</strong> for more developer insights and subscribe for future posts about self-hosted tools, open-source stacks, and dev workflows.</p>
]]></content:encoded></item><item><title><![CDATA[Zod parse vs safeParse: Key Differences and When to Use]]></title><description><![CDATA[Zod is a powerful schema validation library that offers two primary methods to validate data: .parse and .safeParse. Both can be used synchronously or asynchronously (.parseAsync and .safeParseAsync), depending on your needs.
Define A Schema:
We’ll c...]]></description><link>https://blogs.theharsh.xyz/zod-parse-vs-safeparse-key-differences-and-when-to-use</link><guid isPermaLink="true">https://blogs.theharsh.xyz/zod-parse-vs-safeparse-key-differences-and-when-to-use</guid><category><![CDATA[safeParse]]></category><category><![CDATA[zod]]></category><category><![CDATA[TypeScript]]></category><category><![CDATA[schema]]></category><category><![CDATA[Validation]]></category><category><![CDATA[Parse]]></category><dc:creator><![CDATA[Harsh Vardhan Pandey]]></dc:creator><pubDate>Wed, 11 Sep 2024 09:48:41 GMT</pubDate><content:encoded><![CDATA[<p>Zod is a powerful schema validation library that offers two primary methods to validate data: <code>.parse</code> and <code>.safeParse</code>. Both can be used synchronously or asynchronously (<code>.parseAsync</code> and <code>.safeParseAsync</code>), depending on your needs.</p>
<h2 id="heading-define-a-schema">Define A Schema:</h2>
<p>We’ll create a schema for a product, which includes a name, price, stock quantity, and a category.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { z } <span class="hljs-keyword">from</span> <span class="hljs-string">'zod'</span>;

<span class="hljs-keyword">const</span> productSchema = z.object({
  name: z.string(),
  price: z.number().positive(),
  stock: z.number().int().nonnegative(),
  category: z.enum([<span class="hljs-string">'Electronics'</span>, <span class="hljs-string">'Books'</span>, <span class="hljs-string">'Clothing'</span>, <span class="hljs-string">'Toys'</span>]),
});
</code></pre>
<h2 id="heading-zod-parse">Zod Parse:</h2>
<h4 id="heading-parse-immediate-error-throwing"><code>.parse</code>: Immediate Error Throwing</h4>
<p>The <code>.parse</code> method is straightforward—it throws an error if the data doesn’t match the schema. This is useful when you want the program to halt immediately upon invalid input, such as when validating input in middleware or inside a <code>try-catch</code> block</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">try</span> {
  <span class="hljs-keyword">const</span> productData = productSchema.parse({
    name: <span class="hljs-string">"Laptop"</span>,
    price: <span class="hljs-number">-1200</span>, <span class="hljs-comment">// Invalid: price should be positive</span>
    stock: <span class="hljs-number">10</span>,
    category: <span class="hljs-string">"Electronics"</span>,
  });
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Validated Product:"</span>, productData);
} <span class="hljs-keyword">catch</span> (error) {
  <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"Error:"</span>, error.errors);
}
</code></pre>
<h3 id="heading-output">Output:</h3>
<pre><code class="lang-bash">Error: [
  {
    <span class="hljs-string">"message"</span>: <span class="hljs-string">"Number must be greater than 0"</span>,
    <span class="hljs-string">"path"</span>: [<span class="hljs-string">"price"</span>],
    <span class="hljs-string">"code"</span>: <span class="hljs-string">"too_small"</span>
  }
]
</code></pre>
<p>In this example, the <code>price</code> field is invalid because it's negative, so <code>.parse</code> throws an error and halts the execution. This is helpful if you're validating data at an API endpoint and want to reject the request immediately if it's invalid.</p>
<h2 id="heading-zod-safeparse">Zod safeParse:</h2>
<h4 id="heading-safeparse-graceful-error-handling"><code>.safeParse</code>: Graceful Error Handling</h4>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> result = productSchema.safeParse({
  name: <span class="hljs-string">"Laptop"</span>,
  price: <span class="hljs-number">-1200</span>, <span class="hljs-comment">// Invalid: price should be positive</span>
  stock: <span class="hljs-number">10</span>,
  category: <span class="hljs-string">"Electronics"</span>,
});

<span class="hljs-keyword">if</span> (!result.success) {
  <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"Validation failed:"</span>, result.error.errors);
} <span class="hljs-keyword">else</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Validated Product:"</span>, result.data);
}
</code></pre>
<h3 id="heading-output-1">Output:</h3>
<pre><code class="lang-bash">Validation failed: [
  {
    <span class="hljs-string">"message"</span>: <span class="hljs-string">"Number must be greater than 0"</span>,
    <span class="hljs-string">"path"</span>: [<span class="hljs-string">"price"</span>],
    <span class="hljs-string">"code"</span>: <span class="hljs-string">"too_small"</span>
  }
]
</code></pre>
<p>In this case, <code>.safeParse</code> doesn’t throw an error, but it returns an object indicating whether validation succeeded. The rest of your code can continue running even when validation fails.</p>
<h2 id="heading-conclusion">Conclusion:</h2>
<ul>
<li><p><code>.parse</code>: Useful for strict validation where you need to throw an error and stop execution when the data is invalid, such as in API requests.</p>
</li>
<li><p><code>.safeParse</code>: Provides a non-throwing validation method, ideal for cases where you want to handle errors gracefully, like in form validation or non-blocking flows.</p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Creating an EC2 Instance on AWS: A Step-by-Step Guide for Beginners]]></title><description><![CDATA[What is AWS?
AWS is Amazon’s Cloud Service.
It let’s you

Rent servers

Upload objects (mp4 files, jpegs, mp3s …)

Autoscale servers

Create k8s clusters


 The offering we will be focusing on today is Renting servers.
Prerequisites: Before we dive i...]]></description><link>https://blogs.theharsh.xyz/creating-an-ec2-instance-on-aws-a-step-by-step-guide-for-beginners</link><guid isPermaLink="true">https://blogs.theharsh.xyz/creating-an-ec2-instance-on-aws-a-step-by-step-guide-for-beginners</guid><category><![CDATA[AWS]]></category><category><![CDATA[Cloud]]></category><category><![CDATA[EC2 instance]]></category><category><![CDATA[Amazon Web Services]]></category><dc:creator><![CDATA[Harsh Vardhan Pandey]]></dc:creator><pubDate>Mon, 04 Mar 2024 11:03:20 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1709546473959/6f10566b-77a8-4db1-a388-c205b0f524cf.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="heading-what-is-aws">What is AWS?</h1>
<p>AWS is Amazon’s Cloud Service.</p>
<p>It let’s you</p>
<ol>
<li><p>Rent servers</p>
</li>
<li><p>Upload objects (mp4 files, jpegs, mp3s …)</p>
</li>
<li><p>Autoscale servers</p>
</li>
<li><p>Create k8s clusters</p>
</li>
</ol>
<p> The offering we will be focusing on today is <code>Renting servers.</code></p>
<p>Prerequisites: Before we dive in, ensure you have the following:</p>
<ol>
<li><p><a target="_blank" href="https://aws.amazon.com/">An AWS account.</a></p>
</li>
<li><p>SSH key pair for accessing your EC2 instance.</p>
</li>
</ol>
<hr />
<h1 id="heading-what-is-an-ec2-instance">What is an EC2 instance?</h1>
<p>Virtual Machines on AWS are called EC2 (Elastic Compute Cloud).</p>
<ol>
<li><p><strong>Elastic</strong>: As the name suggests, we can increase/decrease the size of the machine.</p>
</li>
<li><p><strong>Compute</strong>: It is a machine.</p>
</li>
</ol>
<p>You can fire up a new EC2 instance from the AWS dashboard.</p>
<p><img src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F085e8ad8-528e-47d7-8922-a23dc4016453%2Ff0ee3fa6-e989-4982-a580-e8039c48ae62%2FScreenshot_2024-02-11_at_6.33.46_AM.png?table=block&amp;id=3dc2315f-4c68-4d34-995e-c56ba0d08feb&amp;cache=v2" alt="notion image" /></p>
<hr />
<h1 id="heading-creating-a-new-ec2-instance">Creating a new EC2 instance</h1>
<ol>
<li>Click on <code>Launch Instances.</code></li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1709547522959/d0e91219-d7ec-4118-b6ea-329d68b1de91.png" alt class="image--center mx-auto" /></p>
<ol start="2">
<li>Give a name to your instance.</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1709547913500/6e625b3d-6fb6-4852-957c-65fe5fc71d31.png" alt class="image--center mx-auto" /></p>
<ol start="3">
<li>Select an Operating System (OS).</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1709548119877/48c94b75-0cb6-49b8-ae23-eba93c973552.png" alt class="image--center mx-auto" /></p>
<ol start="4">
<li>Select Size</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1709548262698/003d0772-34f3-4a3f-96e7-31606ac8beb3.png" alt class="image--center mx-auto" /></p>
<ol start="5">
<li>Create a new key pair.</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1709548374126/ad6f55be-0db3-48d2-ac76-7d270acac5da.png" alt class="image--center mx-auto" /></p>
<p>Now create a new key pair by providing a name, then click on <code>create key pair.</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1709548452626/fba4dce0-851c-4207-8aa1-e4420c919243.png" alt class="image--center mx-auto" /></p>
<p>Now it'll download a <code>test101.pem</code> file.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1709548537083/7de728fd-a59a-4991-aab4-f8895a764cf9.png" alt class="image--center mx-auto" /></p>
<ol start="6">
<li>Select Storage Size</li>
</ol>
<p><img src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F085e8ad8-528e-47d7-8922-a23dc4016453%2F4f28c0ac-7f35-4200-a0e6-21df5ac982b3%2FScreenshot_2024-02-11_at_6.38.05_AM.png?table=block&amp;id=f32975d3-a6ee-4a3b-a666-33eb338ff4fe&amp;cache=v2" alt="notion image" /></p>
<ol start="7">
<li>Allow traffic on <strong>http/https.</strong></li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1709548863721/ad7b20d4-304e-459f-9f19-d4b91700b85b.png" alt class="image--center mx-auto" /></p>
<ol start="8">
<li>Launch the instance</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1709549228434/5e45c68e-e672-4adc-a06c-48c9947a086c.png" alt class="image--center mx-auto" /></p>
<hr />
<h1 id="heading-connection-using-ssh-into-instance">Connection using SSH into instance</h1>
<p>First open your terminal and then navigate to the folder where your <code>test101.pem</code> has been downloaded.</p>
<pre><code class="lang-bash"><span class="hljs-built_in">cd</span> Downloads
</code></pre>
<ol>
<li>Give SSH Key Permissions.</li>
</ol>
<pre><code class="lang-bash">chmod 700 test101.pem
</code></pre>
<ol start="2">
<li>SSH into machine</li>
</ol>
<p>Copy the IP address of the instance.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1709549487594/b731cf36-03ae-4137-95cc-42a62ace7a86.png" alt class="image--center mx-auto" /></p>
<pre><code class="lang-bash">ssh -i test101.pem ubuntu@54.89.21.166
</code></pre>
<ol start="3">
<li>It's Done!</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1709549702146/b0d24c17-59d0-4e5f-a320-fea8206b727b.png" alt class="image--center mx-auto" /></p>
<p>As you can see our Linux server is running.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1709549709996/532b3b38-bd7f-4e60-9117-35340ff6e0eb.png" alt class="image--center mx-auto" /></p>
<p>Congratulations! You've successfully created your first EC2 instance on AWS. You can now start using it for various purposes such as hosting websites, running applications, or conducting experiments in a sandbox environment.</p>
<hr />
<h1 id="heading-conclusion">Conclusion</h1>
<p>Creating an EC2 instance on AWS is a straightforward process, especially with this step-by-step guide for beginners. By following these steps, you can quickly set up your own virtual server in the cloud and start exploring the vast possibilities of cloud computing with AWS. So, what are you waiting for? Dive in and start building your cloud infrastructure today!</p>
]]></content:encoded></item><item><title><![CDATA[Cloud Computing 101: A Beginner's Roadmap]]></title><description><![CDATA[“Computing Can be sold as a Utility, like Water and Electricity.” - John McCarthy

In today's digital landscape, cloud computing has become a cornerstone of modern technology. From fledgling startups to global enterprises, organizations of all sizes ...]]></description><link>https://blogs.theharsh.xyz/cloud-computing-101-a-beginners-roadmap</link><guid isPermaLink="true">https://blogs.theharsh.xyz/cloud-computing-101-a-beginners-roadmap</guid><category><![CDATA[Cloud Computing]]></category><category><![CDATA[Cloud]]></category><category><![CDATA[AWS]]></category><category><![CDATA[Azure]]></category><category><![CDATA[cloudflare]]></category><dc:creator><![CDATA[Harsh Vardhan Pandey]]></dc:creator><pubDate>Fri, 16 Feb 2024 14:10:07 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1708092489778/6c6c930f-5cc0-420e-8af9-6b93d7536fd9.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote>
<p>“Computing Can be sold as a Utility, like Water and Electricity.” - <a target="_blank" href="https://en.wikipedia.org/wiki/John_McCarthy_(computer_scientist)">John McCarthy</a></p>
</blockquote>
<p>In today's digital landscape, cloud computing has become a cornerstone of modern technology. From fledgling startups to global enterprises, organizations of all sizes are harnessing its power. For newcomers to the tech world, understanding cloud computing can feel like navigating uncharted territory. Assume you're a small business owner eager to streamline your operations. Instead of investing in expensive on-site servers and IT infrastructure, you opt for cloud computing.</p>
<h2 id="heading-what-is-cloud-computing">What is Cloud Computing?</h2>
<p>Cloud Computing is a means of storing and accessing programs and data through the internet, rather than using your own computer hard drives.</p>
<blockquote>
<p>Cloud Computing is based on the "Pay-as-you-go" model.</p>
</blockquote>
<h2 id="heading-why-to-use-cloud-computing-what-are-the-benefits-of-cloud-computing">Why To Use Cloud Computing? What Are the Benefits of Cloud Computing?</h2>
<p>Cloud computing offers numerous benefits to individuals and businesses, some of which are listed below:</p>
<ul>
<li><p><strong>Cost-effective</strong> – Reduce the cost of software, equipment, and technology services by utilizing a cloud provider’s hardware infrastructure.</p>
</li>
<li><p><strong>Rapidly Scalable</strong> – Scale your business up or down as needed by using the computing power and storage of the cloud provider.</p>
</li>
<li><p><strong>Always Accessible</strong> – You can access your data if your internet connection works.</p>
</li>
<li><p><strong>Collaboration</strong> – Work in real-time on shared files and documents with team members.</p>
</li>
<li><p><strong>Security</strong> – Cloud providers employ various security measures to prevent data breaches and protect user privacy.</p>
</li>
</ul>
<h2 id="heading-what-are-the-types">What are the Types?</h2>
<p>There are four main types of cloud computing:</p>
<ul>
<li><p><strong>Public Cloud</strong> – Data storage and computing resources are shared between multiple clients on the provider’s cloud.</p>
</li>
<li><p><strong>Private Cloud</strong> – Data storage and computing resources are completely exclusive to a single client.</p>
</li>
<li><p><strong>Hybrid Cloud</strong> – A mix of using both private and public cloud resources.</p>
</li>
<li><p><strong>Community Cloud</strong> - Tailored collaboration for specific industries.</p>
</li>
</ul>
<h2 id="heading-top-cloud-computing-platforms">Top Cloud Computing Platforms</h2>
<p>The top cloud computing platforms include:</p>
<ul>
<li><p><a target="_blank" href="https://aws.amazon.com/">Amazon Web Services (AWS)</a></p>
</li>
<li><p><a target="_blank" href="https://azure.microsoft.com/en-in">Microsoft Azure</a></p>
</li>
<li><p><a target="_blank" href="https://cloud.google.com/?hl=en">Google Cloud Platform</a></p>
</li>
<li><p><a target="_blank" href="https://www.ibm.com/cloud">IBM Cloud</a></p>
</li>
</ul>
<h2 id="heading-top-cloud-computing-services">Top Cloud Computing Services</h2>
<p>The cloud computing services offered differ across platforms but majorly consist of <strong>Infrastructure as a service (IaaS), Platform as a service (PaaS), and Software as a service (SaaS).</strong></p>
<ul>
<li><p><strong>IaaS</strong> focuses on delivering computing infrastructure, such as servers, storage, networking, and operating systems, to businesses. Some top examples of IaaS include Amazon EC2, Google Compute Engine and Microsoft Azure Virtual Machines.</p>
</li>
<li><p><strong>PaaS</strong> provides pre-built tools and applications to developers, enabling them to create customized software. Some examples of PaaS include Vercel, Netlify, and Google App Engine.</p>
</li>
<li><p><strong>SaaS</strong> delivers on-demand software applications to end-users over the internet. Some examples of SaaS include Salesforce, Zoom and Google Workspace.</p>
</li>
</ul>
<h2 id="heading-getting-started-with-cloud-computing">Getting Started with Cloud Computing</h2>
<ol>
<li><p><strong>Choose a Cloud Service Provider:</strong> Research different providers and their offerings to find the one that best suits your needs and budget.</p>
</li>
<li><p><strong>Explore Documentation and Tutorials:</strong> Most cloud providers offer extensive documentation, tutorials, and training resources to help you get started.</p>
</li>
<li><p><strong>Hands-On Practice:</strong> Dive into hands-on exercises and projects to solidify your understanding of cloud concepts and services.</p>
</li>
<li><p><strong>Stay Updated:</strong> Cloud computing is a rapidly evolving field, so stay informed about the latest trends, technologies, and best practices.</p>
</li>
</ol>
<h2 id="heading-real-world-examples-and-use-cases">Real-World Examples and Use Cases</h2>
<p>Cloud computing has numerous practical applications, such as:</p>
<ul>
<li><p>Video streaming services like <a target="_blank" href="https://www.netflix.com/in/">Netflix</a> and <a target="_blank" href="https://www.hotstar.com/">Hotstar</a>.</p>
</li>
<li><p>E-commerce websites such as <a target="_blank" href="https://www.amazon.in/">Amazon</a> and <a target="_blank" href="https://www.flipkart.com/">Flipkart</a>.</p>
</li>
</ul>
<h2 id="heading-conclusion">Conclusion</h2>
<p>As technology continues to advance, cloud computing will undoubtedly play an increasingly vital role in shaping the future of IT. By mastering the basics of cloud computing, you'll not only expand your skill set but also position yourself for success in an ever-changing digital landscape. So, embrace the cloud, explore its possibilities, and unleash your potential in the world of computing. Happy cloud computing!</p>
]]></content:encoded></item></channel></rss>