<?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[PGR's Blog]]></title><description><![CDATA[PGR's Blog]]></description><link>https://blog.q21.in</link><generator>RSS for Node</generator><lastBuildDate>Wed, 15 Apr 2026 16:41:56 GMT</lastBuildDate><atom:link href="https://blog.q21.in/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[How to Self-Host GitLab for Free on Windows Using WSL- (Localhost)]]></title><description><![CDATA[I tried creating my own AWS account to host GitLab, but it didn't work out 😅. The free tier VM, t2.micro, couldn't support the full GitLab 😕, and the VM kept crashing 💥, so I hosted my own GitLab instead 😊.
You can also host your own GitLab with ...]]></description><link>https://blog.q21.in/how-to-self-host-gitlab-for-free-on-windows-using-wsl-localhost</link><guid isPermaLink="true">https://blog.q21.in/how-to-self-host-gitlab-for-free-on-windows-using-wsl-localhost</guid><category><![CDATA[localhost]]></category><category><![CDATA[GitLab]]></category><category><![CDATA[SelfHosting]]></category><category><![CDATA[#selfhosted]]></category><category><![CDATA[self-hosted]]></category><category><![CDATA[Local Hosting Services]]></category><category><![CDATA[Docker]]></category><category><![CDATA[Docker compose]]></category><category><![CDATA[GitLab CE]]></category><category><![CDATA[WSL]]></category><category><![CDATA[wsl ubuntu]]></category><category><![CDATA[wsl2]]></category><category><![CDATA[domain]]></category><category><![CDATA[Custom Domain]]></category><dc:creator><![CDATA[Prashanth Gowda G R]]></dc:creator><pubDate>Sun, 12 Oct 2025 20:13:14 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1760299798224/310938ea-888c-4c71-8c8e-84f5a4ee06b6.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I tried creating my own AWS account to host GitLab, but it didn't work out 😅. The free tier VM, t2.micro, couldn't support the full GitLab 😕, and the VM kept crashing 💥, so I hosted my own GitLab instead 😊.</p>
<p>You can also host your own GitLab with a custom domain. Let's get started building it! 🚀💻✨</p>
<h2 id="heading-setting-up-gitlab-ce-in-wsl-with-docker-localhosthttplocalhost-gitlabexampleinhttpgitlabq21in">Setting Up GitLab CE in WSL with Docker (<a target="_blank" href="http://Localhost">Localhost</a> → <a target="_blank" href="http://gitlab.q21.in">gitlab.example.in</a>)</h2>
<p>Setting Up GitLab CE in WSL with Docker (<a target="_blank" href="http://Localhost">Localhost</a> → <a target="_blank" href="http://gitlab.q21.in">gitlab.example.in</a>) 🎉🐳</p>
<p>The steps below will guide you through hosting <strong>GitLab Community Edition (CE)</strong> locally in <strong>WSL2</strong> using Docker and accessing it via a custom domain <a target="_blank" href="http://gitlab.q21.in"><code>gitlab.example.in</code></a> mapped to <a target="_blank" href="http://localhost">localhost</a>. We will skip HTTPS for simplicity and remove unnecessary services to keep it lightweight. 🚀🔧</p>
<p>1️⃣ Prerequisites 📋</p>
<ul>
<li><p><strong>WSL2/Ubuntu app</strong> installed on Windows 🖥️</p>
</li>
<li><p><strong>Docker installed and</strong> configured for WSL2 backend or within Ubuntu 🐋</p>
</li>
<li><p>Basic familiarity with terminal commands 💻</p>
</li>
</ul>
<p>Optional: A <strong>text editor</strong> like <code>nano</code> or <code>Vim</code>. ✏️</p>
<p>2️⃣ Map Custom Domain to <a target="_blank" href="http://Localhost">Localhost</a> 🌐</p>
<p>We want to use <code>gitlab.example.in</code> in our browser instead of <a target="_blank" href="http://localhost"><code>localhost</code></a>. 🌍</p>
<ul>
<li><p>Open the Windows hosts file: <code>C:\Windows\System32\drivers\etc\hosts</code> 📂</p>
</li>
<li><p>Add the following line: ✍️</p>
</li>
</ul>
<ul>
<li><pre><code class="lang-plaintext">  127.0.0.1 gitlab.example.in
</code></pre>
</li>
<li><p>Save the file.</p>
</li>
</ul>
<p>✅ Now, <a target="_blank" href="http://gitlab.q21.in"><code>http://gitlab.example.in</code></a> will resolve to your local WSL instance.</p>
<p>3️⃣ Create a Minimal Docker Compose File</p>
<p>Create a directory for GitLab Docker setup:</p>
<pre><code class="lang-bash">mkdir ~/gitlab-docker
<span class="hljs-built_in">cd</span> ~/gitlab-docker
</code></pre>
<p>Create a file <code>docker-compose.yml</code>:</p>
<pre><code class="lang-yaml"><span class="hljs-attr">version:</span> <span class="hljs-string">'3.8'</span>

<span class="hljs-attr">services:</span>
  <span class="hljs-attr">gitlab:</span>
    <span class="hljs-attr">image:</span> <span class="hljs-string">gitlab/gitlab-ce:latest</span>
    <span class="hljs-attr">container_name:</span> <span class="hljs-string">gitlab</span>
    <span class="hljs-attr">restart:</span> <span class="hljs-string">always</span>
    <span class="hljs-attr">hostname:</span> <span class="hljs-string">gitlab.example.in</span>
    <span class="hljs-attr">environment:</span>
      <span class="hljs-attr">GITLAB_OMNIBUS_CONFIG:</span> <span class="hljs-string">|
        external_url 'http://gitlab.example.in'       # Use HTTP only
        nginx['redirect_http_to_https'] = false   # Disable HTTPS redirect
        prometheus['enable'] = false              # Disable Prometheus
        gitlab_kas['enable'] = false              # Disable Kubernetes agent
        letsencrypt['enable'] = false             # Disable LetsEncrypt
        registry_nginx['enable'] = false          # Disable Docker registry
        gitlab_rails['gitlab_shell_ssh_port'] = 22
</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">"22:22"</span>
     <span class="hljs-comment">#- "443:443" #Keeping it commented as we are not using HTTPS which requires Certificate and </span>
                  <span class="hljs-comment">#domain registered</span>
    <span class="hljs-attr">volumes:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">./gitlab/config:/etc/gitlab</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">./gitlab/logs:/var/log/gitlab</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">./gitlab/data:/var/opt/gitlab</span>
</code></pre>
<p>✅ Explanation</p>
<ul>
<li><p><strong>external_url</strong> 🌐 → We use HTTP only (<a target="_blank" href="http://gitlab.q21.in"><code>http://gitlab.example.com</code></a>) for local testing. 🧪</p>
</li>
<li><p><strong>Disabled services</strong> 🚫 → Prometheus, KAS, Let's Encrypt, and registry are disabled to reduce memory footprint. 🧠</p>
</li>
<li><p><strong>Volumes</strong> 📦 → Persist configuration, logs, and repository data. 🗂️</p>
</li>
<li><p><strong>Ports</strong> 🔌 → HTTP on 80, SSH on 22 for Git operations. 🛠️</p>
</li>
</ul>
<p>4️⃣ Start GitLab</p>
<pre><code class="lang-bash">docker-compose up -d
</code></pre>
<ul>
<li><p>This will pull the latest GitLab CE image and start the container.</p>
</li>
<li><p>The first start may take a few minutes to download images</p>
</li>
</ul>
<p>Check container status:</p>
<pre><code class="lang-bash">docker ps
docker <span class="hljs-built_in">exec</span> -it gitlab gitlab-ctl status
</code></pre>
<p>5️⃣ Access GitLab</p>
<ul>
<li><p>Open your browser and navigate to: <a target="_blank" href="http://gitlab.q21.in"><code>http://gitlab.example.in</code></a></p>
</li>
<li><p>The first login will prompt you to <strong>enter the uname password</strong>.</p>
</li>
<li><p>In GitLab Omnibus Docker, the initial root password is automatically generated and stored in a file inside the container. You can retrieve it instead of setting it manually.</p>
</li>
<li><p>Access the GitLab container</p>
<pre><code class="lang-bash">  docker <span class="hljs-built_in">exec</span> -it gitlab /bin/bash
  cat /etc/gitlab/initial_root_password
</code></pre>
</li>
<li><p>Copy the password and log in (default username = root)</p>
</li>
<li><p>The <strong>initial_root_password</strong> file is only generated <strong>once</strong> during the first startup.</p>
</li>
<li><p>If you forget it later, you can <strong>reset the root password</strong> via:</p>
<pre><code class="lang-bash">  docker <span class="hljs-built_in">exec</span> -it gitlab gitlab-rails console
  <span class="hljs-comment"># then use: user = User.where(id: 1).first; user.password = 'newpassword'; user.save!</span>
</code></pre>
</li>
</ul>
<p>6️⃣ Push Your Local Repository</p>
<h3 id="heading-step-61-create-a-project">Step 6.1 — Create a project</h3>
<ul>
<li><p>In GitLab UI, click <strong>New Project → Create blank project</strong></p>
</li>
<li><p>Name it e.g., <code>first-repo</code></p>
</li>
</ul>
<h3 id="heading-step-62-initialize-local-repo">Step 6.2 — Initialize local repo</h3>
<pre><code class="lang-bash"><span class="hljs-built_in">cd</span> ~/first-repo
git init
git add .
git commit -m <span class="hljs-string">"Initial commit"</span>
</code></pre>
<h3 id="heading-step-63-add-gitlab-remote">Step 6.3 — Add GitLab remote</h3>
<pre><code class="lang-bash">git remote add origin http://gitlab.example.in/first-repo
</code></pre>
<h3 id="heading-step-64authenticate-using-personal-access-token-pat">Step 6.4—Authenticate using Personal Access Token (PAT)</h3>
<ol>
<li><p>Go to <strong>User Settings → Access Tokens</strong></p>
</li>
<li><p>Create token with <code>write_repository</code> scope</p>
</li>
<li><p>Use the token as a password when Git prompts during <code>git push</code>.</p>
</li>
</ol>
<h3 id="heading-step-65-push-to-gitlab">Step 6.5 — Push to GitLab</h3>
<p>If the remote is empty:</p>
<pre><code class="lang-bash">git push -u origin main
</code></pre>
<p>If the remote has a default README and you get conflicts:</p>
<pre><code class="lang-bash">git fetch origin
git rebase origin/main
<span class="hljs-comment"># Resolve any conflicts</span>
git push -u origin main
</code></pre>
<p>7️⃣ Optional: Using Nano ✏️</p>
<ul>
<li><p>During conflict resolution, Git may open files in <strong>nano</strong>. 📝</p>
</li>
<li><p>Exit nano: 🚪</p>
<ul>
<li><p><code>Ctrl + X</code> → exit ❌</p>
</li>
<li><p><code>Y</code> → save changes 💾</p>
</li>
<li><p><code>N</code> → discard changes 🚫</p>
</li>
</ul>
</li>
</ul>
<p>8️⃣ Summary 📋</p>
<ul>
<li><p>GitLab CE now runs <strong>locally in Docker on WSL</strong>. 🐳</p>
</li>
<li><p>Access via <a target="_blank" href="http://gitlab.q21.in"><code>http://gitlab.example.in</code></a>. 🌐</p>
</li>
<li><p>Minimal setup: no HTTPS, no monitoring, only essential services. 🔧</p>
</li>
<li><p>Local projects can be pushed via HTTP using <strong>Personal Access Token</strong>. 🔑</p>
</li>
<li><p>Docker volumes ensure data persistence. 📦</p>
</li>
</ul>
<p>9️⃣ Next Steps 🚀</p>
<ul>
<li><p>Add more repositories for microservices. 📂</p>
</li>
<li><p>Experiment with <strong>GitLab CI/CD</strong> using <code>.gitlab-ci.yml</code>. 🤖</p>
</li>
<li><p>Optionally enable <strong>SSH push</strong> for convenience. 🔑</p>
</li>
<li><p>Once confident, move to production VM with HTTPS &amp; monitoring enabled. 🌐🔍</p>
</li>
</ul>
<p>This setup is <strong>perfect for learning DevOps, GitLab administration, and CI/CD pipelines</strong> without worrying about certificates or resource-heavy monitoring. 🎓💻</p>
]]></content:encoded></item><item><title><![CDATA[Hosting Static website using AWS S3 and CloudFront]]></title><description><![CDATA[Prerequisites

AWS account

index.html file (You can any use example file on web)


Two parts of hosting

Static website using S3 only

Host website using both S3 and Cloudfront (CDN)


Static website hosting using just S3

Login to ASW Console and s...]]></description><link>https://blog.q21.in/hosting-static-website-using-aws-s3-and-cloudfront</link><guid isPermaLink="true">https://blog.q21.in/hosting-static-website-using-aws-s3-and-cloudfront</guid><category><![CDATA[index.html]]></category><category><![CDATA[AWS]]></category><category><![CDATA[S3]]></category><category><![CDATA[CDN]]></category><category><![CDATA[cloudfront]]></category><category><![CDATA[Static Website]]></category><category><![CDATA[hosting]]></category><category><![CDATA[HTML]]></category><category><![CDATA[cloudflare]]></category><category><![CDATA[S3-bucket]]></category><category><![CDATA[S3 static website hosting]]></category><dc:creator><![CDATA[Prashanth Gowda G R]]></dc:creator><pubDate>Tue, 16 Apr 2024 15:47:45 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1713282034087/f878b198-e60f-4126-bf26-ec1c1e3e679b.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-prerequisites"><strong>Prerequisites</strong></h2>
<ol>
<li><p>AWS account</p>
</li>
<li><p>index.html file (You can any use example file on web)</p>
</li>
</ol>
<h2 id="heading-two-parts-of-hosting">Two parts of hosting</h2>
<ol>
<li><p>Static website using S3 only</p>
</li>
<li><p>Host website using both S3 and Cloudfront (CDN)</p>
</li>
</ol>
<h3 id="heading-static-website-hosting-using-just-s3">Static website hosting using just S3</h3>
<ol>
<li><p>Login to ASW Console and search for S3</p>
</li>
<li><p>Click on create bucket and give it a unique name(This should be unique across globe)</p>
</li>
<li><p>Use <strong>General Purpose</strong> bucket type under General config.</p>
</li>
<li><p>Use ACL Disabled under Object Ownership</p>
</li>
<li><p>Uncheck <strong>Block all public access under</strong> Block Public Access settings for this bucket and acknowledge.</p>
</li>
<li><p>Let <strong>versioning</strong> be disabled and by default <strong>Encryption type</strong> will be 'Server-side encryption with Amazon S3 managed keys (SSE-S3)'</p>
</li>
<li><p>Create a bucket.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1713280255594/bf2902a9-7a0f-4c19-b9e7-879ac0f3ac99.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Upload a index.html file and save.</p>
</li>
<li><p>Go to properties and under <strong>Static website hosting</strong> enable static website hosting, set hosting type to Host a static website, index doc to "index.html" and save.</p>
</li>
<li><p>Go to permissions and under Bucket Policy paste the below code and replace &lt;bucketname&gt; with your bucket name.</p>
<pre><code class="lang-json">{
    <span class="hljs-attr">"Version"</span>: <span class="hljs-string">"2012-10-17"</span>,
    <span class="hljs-attr">"Statement"</span>: [
        {
            <span class="hljs-attr">"Effect"</span>: <span class="hljs-string">"Allow"</span>,
            <span class="hljs-attr">"Principal"</span>: <span class="hljs-string">"*"</span>,
            <span class="hljs-attr">"Action"</span>: <span class="hljs-string">"s3:GetObject"</span>,
            <span class="hljs-attr">"Resource"</span>: <span class="hljs-string">"arn:aws:s3:::&lt;bucketname&gt;/*"</span>
        }
    ]
}
</code></pre>
</li>
<li><p>Now under Permissions&gt; Static website hosting URL will be present, access it to see your website.</p>
</li>
</ol>
<hr />
<h3 id="heading-host-website-using-both-s3-and-cloudfront-cdn">Host website using both S3 and Cloudfront (CDN)</h3>
<p>This is similar to above with some changes, instead of using S3 URL directly, CDN will be configured to access website which will be useful to deliver the content of the website across world with low latency.</p>
<ol>
<li><p>In this case while creating S3 bucket, check to disable all public access (because we are using S3 as a backend and it should be accessed for all except CDN itself)</p>
</li>
<li><p>And under properties&gt; Static website hosting, disable static website hosting.</p>
</li>
<li><p>Now search for CloudFront and create Distribution.</p>
</li>
<li><p>Under origin domain, select S3 bucket with above configured.</p>
</li>
<li><p>Under origin access create a new OAC and select as below.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1713282251968/3ee6fd70-44e2-49ca-a4ca-25c1a51252fe.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Under cache behaviour&gt; Viewer protocol policy&gt; select redirect HTTP to HTTPS.</p>
</li>
<li><p>Disable WAF and set default root object to index.html and create distribution.</p>
</li>
<li><p>Copy the policy immediately after CDN is created(may take upto 5min to deploy)</p>
</li>
<li><p>Paste the copied policy json and paste it under S3&gt; Permission&gt; Bucket policy.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1713282295048/1ac457d2-fb91-4e18-8cd6-ba08306d6e55.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Now look for a "Distribution domain name" under CDN you just created under general. (Usually it will be like <a target="_blank" href="https://d1u4w2bz2wtaj4.cloudfront.net">d1u4wdfgdf2wtaj4.cloudfront.net</a>)</p>
</li>
<li><p>Browse it and you will get you static website hosted in AWS.</p>
</li>
</ol>
]]></content:encoded></item><item><title><![CDATA[Static Webpage deployment using Git-Jenkins-Docker-Nginx]]></title><description><![CDATA[Install Jenkins using the below commands for Ubuntu 22.04
  apt-get update

  apt install openjdk-11-jre

  curl -fsSL https://pkg.jenkins.io/debian/jenkins.io-2023.key | sudo tee \
    /usr/share/keyrings/jenkins-keyring.asc > /dev/null

  echo deb ...]]></description><link>https://blog.q21.in/static-webpage-deployment-using-git-jenkins-docker-nginx</link><guid isPermaLink="true">https://blog.q21.in/static-webpage-deployment-using-git-jenkins-docker-nginx</guid><category><![CDATA[Git]]></category><category><![CDATA[Jenkins]]></category><category><![CDATA[Devops]]></category><category><![CDATA[Docker]]></category><category><![CDATA[Installation]]></category><category><![CDATA[install]]></category><category><![CDATA[integration]]></category><category><![CDATA[Testing]]></category><category><![CDATA[automation]]></category><category><![CDATA[trigger]]></category><category><![CDATA[invoke]]></category><category><![CDATA[ci-cd]]></category><category><![CDATA[CI/CD pipelines]]></category><dc:creator><![CDATA[Prashanth Gowda G R]]></dc:creator><pubDate>Wed, 13 Dec 2023 15:03:44 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1702478828132/d9d7aa87-610a-4be4-9c56-f23a14f79046.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<ol>
<li><p>Install Jenkins using the below commands for Ubuntu 22.04</p>
<pre><code class="lang-bash">  apt-get update

  apt install openjdk-11-jre

  curl -fsSL https://pkg.jenkins.io/debian/jenkins.io-2023.key | sudo tee \
    /usr/share/keyrings/jenkins-keyring.asc &gt; /dev/null

  <span class="hljs-built_in">echo</span> deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] \
    https://pkg.jenkins.io/debian binary/ | sudo tee \
    /etc/apt/sources.list.d/jenkins.list &gt; /dev/null

  sudo apt-get update

  sudo apt-get install jenkins
</code></pre>
</li>
<li><p>Port 8O8O should be open to access Jenkins, if it is busy already use the below command and change the port.</p>
</li>
</ol>
<pre><code class="lang-bash">systemctl edit jenkins

[Service]
Environment=<span class="hljs-string">"JENKINS_PORT=8080"</span>
</code></pre>
<p>Change 8080 to whatever port is available.</p>
<ol>
<li><p>open http://&lt;IP&gt;:8080 and enter the Admin password which is available in the below path.</p>
<pre><code class="lang-bash"> cat /var/lib/jenkins/secrets/initialAdminPassword
</code></pre>
<ol>
<li>Install the required plugins, and pass the initial username and password.</li>
</ol>
</li>
</ol>
<p>    Install Docker using official documentation- <a target="_blank" href="https://docs.docker.com/engine/install/ubuntu/"><strong>https://docs.docker.com/engine/install/ubuntu/</strong></a></p>
<ol>
<li>Run the below commands to give access to Jenkins users to run docker commands in the server.</li>
</ol>
<pre><code class="lang-bash">     chmod 666 /var/run/docker.sock
</code></pre>
<ol>
<li><p>Now open Jenkins UI click on New Item name it a simple app and select Pipeline.</p>
</li>
<li><p>Select the GitHub project and enter the link to the repository below.</p>
</li>
</ol>
<pre><code class="lang-bash">https://github.com/prashanthgowdagr/simple-index.html-app.git
</code></pre>
<ol>
<li><p>Scroll down and select the GitHub hook trigger. This will help us to build the Jenkins job whenever the commit is made to the 'MAIN' branch of the Git repo.</p>
</li>
<li><p>To set this up go to GitHub and under repo go to settings&gt; Webhooks&gt; and paste the Jenkins server IP address with port number and end with GitHub-webhook/ (don't forget the / in the end). Select Just the push event and save the changes.</p>
</li>
<li><p>Under Pipeline select Pipeline script from SCM and select GIT as SCM.</p>
</li>
<li><p>Enter the Git repo URL and branch as main. The script path should be specified as Jenkinsfile.</p>
</li>
<li><p>Before running the job go to Manage_Jenkins&gt; Credentials&gt; system&gt; golbal&gt; name it "dockercreds" (Use same or it will throw an error/change the variable in jenkinsfile) and enter your DockerHub creds and password. If there is no DockerHub account, plz create one it's FREE!!!</p>
</li>
<li><p>Run the job now and this will pull the code from Git copy the index.html into the docker container and run it. You can access the webpage now using http://&lt;IP&gt;:80</p>
</li>
<li><p>This will also push the updated container to DockerHub with the tag 'latest' and also with the 'Jenkins Build Number'.</p>
</li>
</ol>
]]></content:encoded></item></channel></rss>