<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ishmam Abir | イシュマム・アビル</title>
    <description>The latest articles on DEV Community by Ishmam Abir | イシュマム・アビル (@ishmam_abir).</description>
    <link>https://dev.to/ishmam_abir</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1057771%2F0df06a4d-35e0-4c45-9f6c-c3ac2ea5d056.jpeg</url>
      <title>DEV Community: Ishmam Abir | イシュマム・アビル</title>
      <link>https://dev.to/ishmam_abir</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ishmam_abir"/>
    <language>en</language>
    <item>
      <title>CI/CD on Local Gitlab server| Setup GitLab Runner | Self-hosted GitLab</title>
      <dc:creator>Ishmam Abir | イシュマム・アビル</dc:creator>
      <pubDate>Sat, 15 Nov 2025 08:43:47 +0000</pubDate>
      <link>https://dev.to/ishmam_abir/cicd-on-local-gitlab-server-setup-gitlab-runner-self-hosted-gitlab-37nf</link>
      <guid>https://dev.to/ishmam_abir/cicd-on-local-gitlab-server-setup-gitlab-runner-self-hosted-gitlab-37nf</guid>
      <description>&lt;p&gt;Hello again! In &lt;a href="https://dev.to/ishmam_abir/set-up-your-own-local-gitlab-server-self-hosted-gitlab-4d1"&gt;Part 1&lt;/a&gt; of &lt;strong&gt;Git on Localhost | Self-hosted GitLab&lt;/strong&gt; series, we successfully installed our own self-hosted GitLab server in &lt;code&gt;localhost&lt;/code&gt; using Docker. You may have even gone ahead, created your first project, and added a &lt;code&gt;.gitlab-ci.yml&lt;/code&gt; file, only to see your pipeline get "stuck" with a pending status.&lt;/p&gt;

&lt;p&gt;If not, try setting up a project from your project list: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: If you already setup a project and a pipeline to your local server, then skip the setup part &amp;amp; directly move to the next part. &lt;/p&gt;

&lt;p&gt;⚠ Though its a &lt;code&gt;part 2&lt;/code&gt; article, but I mistakenly wrote 'part 3' in the Cover image! Sorry for that! 🙏🏻&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;first create a repository with a name &lt;code&gt;Go CI Test&lt;/code&gt;,then add some code there from your pc:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuygmgqpl3uy5hkhrkg1a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuygmgqpl3uy5hkhrkg1a.png" alt="New Project" width="800" height="536"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;project_folder
git init &lt;span class="nt"&gt;--initial-branch&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;main
git remote add origin http://localhost:8080/root/ci-test.git
git add &lt;span class="nb"&gt;.&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"add: test CI"&lt;/span&gt;
git push &lt;span class="nt"&gt;--set-upstream&lt;/span&gt; origin main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi5hpccdvg4lscgoblkor.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi5hpccdvg4lscgoblkor.png" alt="Project Init" width="800" height="470"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;now create a file name &lt;code&gt;.gitlab-ci.yml&lt;/code&gt; in the root folder and add some demo CI/CD code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;stages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;test&lt;/span&gt;

&lt;span class="na"&gt;dummy_test_job&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;stage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;test&lt;/span&gt;
  &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo "Running dummy test..."&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;exit 0&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx0mmzhmrdszvehy3c3pf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx0mmzhmrdszvehy3c3pf.png" alt="local setup" width="800" height="555"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;An Error Occured! pipeline cant run!&lt;/p&gt;

&lt;p&gt;This is expected! We've built the "brain" (the GitLab server), but we haven't given it any "hands" to do the work. This is where the GitLab Runner comes in.&lt;/p&gt;




&lt;p&gt;In this article, we'll install and register our own local runner—also using Docker—to pick up those pending jobs and bring our &lt;code&gt;CI/CD pipelines&lt;/code&gt; to life.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a GitLab Runner and Why Do We Need One?
&lt;/h2&gt;

&lt;p&gt;A GitLab Runner is a separate application that executes the CI/CD jobs specified in your GitLab projects.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;On &lt;strong&gt;GitLab.com&lt;/strong&gt;, your jobs run on a shared fleet of runners managed by GitLab.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;On &lt;strong&gt;our self-hosted server&lt;/strong&gt;, we are in a private environment. The GitLab server knows what to do (from &lt;code&gt;.gitlab-ci.yml&lt;/code&gt;) but has no one to delegate the task to.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We must provide our own Runner. This runner will poll our GitLab server, ask "Are there any jobs for me?", and if so, execute them. We'll use the Docker executor, which means our runner will spin up a fresh, clean Docker container for every single job, providing a perfectly isolated and reproducible build environment.&lt;/p&gt;




&lt;h2&gt;
  
  
  Installation Process
&lt;/h2&gt;

&lt;p&gt;As we did in &lt;a href="https://dev.to/ishmam_abir/set-up-your-own-local-gitlab-server-self-hosted-gitlab-4d1"&gt;Part 1&lt;/a&gt;, we will use Docker to keep our setup clean and containerized.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Caution: Before we start, make sure Docker is running on your machine along with the gitlab container.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Step 0: Create a Docker Network
&lt;/h3&gt;

&lt;p&gt;To allow our gitlab container and our new gitlab-runner container to communicate with each other by name, we should create a dedicated Docker network.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;First, create the network:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker network create gitlab-network
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can verify it exists with &lt;code&gt;docker network ls&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbdudxkv0e9hle57bry5w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbdudxkv0e9hle57bry5w.png" alt="Network List" width="579" height="242"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Next, connect your existing gitlab container (from Part 1) to this network:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker network connect gitlab-network gitlab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows the runner to find the server at the hostname &lt;code&gt;gitlab&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Pull the GitLab Runner Docker Image
&lt;/h3&gt;

&lt;p&gt;Open your terminal and pull the latest official image for the runner:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker pull gitlab/gitlab-runner:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Start the Runner Container
&lt;/h3&gt;

&lt;p&gt;Now we'll launch the runner container. This command creates a persistent volume for the runner's configuration and mounts the host's Docker socket so the runner can launch other containers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For Linux / macOS&lt;/strong&gt;: (This assumes you want to store the config in /code/gitlab-runner/config, similar to Part 1)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--name&lt;/span&gt; gitlab-runner &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--restart&lt;/span&gt; always &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--network&lt;/span&gt; gitlab-network &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-v&lt;/span&gt; /code/gitlab-runner/config:/etc/gitlab-runner &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-v&lt;/span&gt; /var/run/docker.sock:/var/run/docker.sock &lt;span class="se"&gt;\&lt;/span&gt;
    gitlab/gitlab-runner:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;For Windows (using PowerShell)&lt;/strong&gt;: (This assumes you're using the D:\code\ path from Part 1)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;--name&lt;/span&gt; gitlab-runner &lt;span class="nt"&gt;--restart&lt;/span&gt; always &lt;span class="nt"&gt;--network&lt;/span&gt; gitlab-network &lt;span class="nt"&gt;-v&lt;/span&gt; D:&lt;span class="se"&gt;\c&lt;/span&gt;ode&lt;span class="se"&gt;\g&lt;/span&gt;itlab-runner&lt;span class="se"&gt;\c&lt;/span&gt;onfig:/etc/gitlab-runner &lt;span class="nt"&gt;-v&lt;/span&gt; //var/run/docker.sock:/var/run/docker.sock gitlab/gitlab-runner:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Command Breakdown:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;--name gitlab-runner&lt;/code&gt;: A recognizable name for our container.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;--restart always&lt;/code&gt;: Ensures the runner restarts if you reboot your machine.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;--network gitlab-network&lt;/code&gt;: Connects the runner to the same network as our GitLab server.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;-v /code/gitlab-runner/config:/etc/gitlab-runner&lt;/code&gt;: Persistent Config. This maps a folder on your host machine to the config folder inside the container. This is critical so your runner doesn't forget its registration if you update or restart the container.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;-v /var/run/docker.sock&lt;/code&gt;:/var/run/docker.sock: The Docker Socket. This is the magic. It gives the runner permission to use your host machine's Docker daemon. This is how the runner can spin up new containers (e.g., golang:1.21 or node:18) to run your jobs. (Note for Windows: the //var/run/docker.sock path is correct).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 3: Register the Runner
&lt;/h3&gt;

&lt;p&gt;Our runner container is running, but it's not authenticated with our server. We need to "register" it.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Find Your Registration Token:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Log into your local GitLab server (&lt;code&gt;http://localhost:8080&lt;/code&gt;) as the &lt;code&gt;root&lt;/code&gt; user.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click the &lt;strong&gt;Admin Area&lt;/strong&gt; (wrench icon) in the top navigation bar.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the left sidebar, go to &lt;strong&gt;CI/CD &amp;gt; Runners&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Click the "&lt;strong&gt;Register an instance runner&lt;/strong&gt;" button.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4vx6nq7u3rxve1tqa91u.png" alt="Create New Instance Runner" width="800" height="516"&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8yshmd6s5vy5lniejp8q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8yshmd6s5vy5lniejp8q.png" alt="Runner creation Page" width="800" height="518"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Copy the registration token displayed. It will start with &lt;code&gt;glrt...&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmlg0x10hhbeswvuosbee.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmlg0x10hhbeswvuosbee.png" alt="runner auth" width="800" height="482"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Run the Interactive Registration Command: We will execute a command inside our running &lt;code&gt;gitlab-runner&lt;/code&gt; container:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; gitlab-runner gitlab-runner register
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Answer the Prompts: This will start an interactive setup.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6v5c9a683uvulols587g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6v5c9a683uvulols587g.png" alt="Runner Register Cli" width="800" height="269"&gt;&lt;/a&gt;&lt;br&gt;
 Here are the answers you should provide:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;Enter the GitLab instance URL&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;http://gitlab&lt;/code&gt; (We use &lt;code&gt;http://gitlab&lt;/code&gt; instead of &lt;code&gt;localhost&lt;/code&gt; because both containers are on the &lt;code&gt;gitlab-network&lt;/code&gt; and can find each other by their container names. &lt;code&gt;8080&lt;/code&gt; is the port we exposed in Part 1.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;Enter the registration token&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;[PASTE_THE_TOKEN_YOU_COPIED]&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;Enter a description for the runner&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;'My Local Docker Runner (or whatever you want to write)' (This is just a friendly name you'll see in the UI.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;Enter tags for the runner&lt;/code&gt; (comma-separated):&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker&lt;/code&gt;, &lt;code&gt;local&lt;/code&gt; (Tags are very important. This allows you to "tag" your jobs in &lt;code&gt;.gitlab-ci.yml&lt;/code&gt; to ensure they run on the correct runner.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Enter an optional maintenance note:&lt;/p&gt;

&lt;p&gt;(Just press Enter to leave this blank.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;Enter the executor&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker&lt;/code&gt; (This is the most important setting. It tells the runner to use Docker to run jobs.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;Enter the default Docker image&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;alpine:latest&lt;/code&gt; (This is a fallback image to use if a job in your &lt;code&gt;.gitlab-ci.yml&lt;/code&gt; doesn't specify its own image:.)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The registration is now complete!&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 4: Verify Your Runner
&lt;/h3&gt;

&lt;p&gt;Go back to your GitLab browser window (the &lt;strong&gt;Admin Area &amp;gt; Runners&lt;/strong&gt; page) and refresh.&lt;/p&gt;

&lt;p&gt;You should now see your new runner listed, with a green circle indicating it is online and ready for jobs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdt3izt420n6q8ch6xsqq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdt3izt420n6q8ch6xsqq.png" alt="New Runner Online" width="800" height="470"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Optional&lt;/strong&gt;: You can manually verify that the runner is available to pick up jobs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; gitlab-runner gitlab-runner run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, go back to that "pending" pipeline (or push a new commit to trigger one). You will see it get picked up by your new runner and finally switch to "&lt;strong&gt;running&lt;/strong&gt;" and then "&lt;strong&gt;passed&lt;/strong&gt;"!&lt;/p&gt;




&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Congratulations! You now have a complete, end-to-end CI/CD setup on your local machine. You have the &lt;strong&gt;Local GitLab Server&lt;/strong&gt; to manage your code and pipelines, and a &lt;strong&gt;GitLab Runner&lt;/strong&gt; to execute the work.&lt;/p&gt;

&lt;p&gt;Hope this tutorial series helps you setup your own local version  control! &lt;br&gt;
Next what you can do is deploy this to your server and can access from anywhere!&lt;/p&gt;

&lt;p&gt;Enjoy your own Private gitlab! &lt;/p&gt;

</description>
      <category>cicd</category>
      <category>gitlab</category>
      <category>localhost</category>
      <category>docker</category>
    </item>
    <item>
      <title>Decoding Golang Interfaces: Why Your Struct Fits an Interface It Never Met</title>
      <dc:creator>Ishmam Abir | イシュマム・アビル</dc:creator>
      <pubDate>Tue, 09 Sep 2025 09:49:30 +0000</pubDate>
      <link>https://dev.to/ishmam_abir/decoding-golang-interfaces-why-your-struct-fits-an-interface-it-never-met-481b</link>
      <guid>https://dev.to/ishmam_abir/decoding-golang-interfaces-why-your-struct-fits-an-interface-it-never-met-481b</guid>
      <description>&lt;p&gt;If you’re coming to &lt;strong&gt;Golang&lt;/strong&gt; from a language like Java, C#, or other language, you’ve probably run into a piece of code that left you scratching your head. It looks something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"fmt"&lt;/span&gt;

&lt;span class="c"&gt;// 1. The Concrete Type&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;A&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;abc&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// 2. The Method attached to the type&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;f1&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"f1 function: "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;abc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// 3. The Abstract Interface&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;I&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;f1&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// 4. The Consumer Function&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;wantsI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;I&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;f1&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// 5. The Execution&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;abc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"test value"&lt;/span&gt;

    &lt;span class="c"&gt;// ➡ The "magic" question is right here: ⬅&lt;/span&gt;
    &lt;span class="n"&gt;wantsI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"method executed!..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you run this, it works perfectly and prints:&lt;br&gt;
&lt;code&gt;f1 function: test value&lt;/code&gt;&lt;br&gt;
&lt;code&gt;method executed!...&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This leads to the central question that stumps many new Go developers:&lt;br&gt;
&lt;strong&gt;Why does this work?&lt;/strong&gt; The &lt;code&gt;wantsI&lt;/code&gt; function clearly states it only accepts a parameter of type &lt;code&gt;I&lt;/code&gt; (the interface). Yet, we passed it &lt;code&gt;a&lt;/code&gt;, which is a variable of type &lt;code&gt;*A&lt;/code&gt; (a pointer to a struct). We never wrote "struct A implements I."&lt;/p&gt;

&lt;p&gt;How can a function expecting an interface accept a struct that seemingly has no connection to it?&lt;/p&gt;

&lt;p&gt;The answer is the single most powerful and defining feature of the Go language: &lt;strong&gt;implicit interface implementation&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Let's break it down how concrete types (structs) implicitly satisfy abstract types (interfaces) &amp;amp; Unlock the power of polymorphism in Go.&lt;/p&gt;




&lt;h3&gt;
  
  
  🧱 The Building Blocks: Concrete vs. Abstract Types
&lt;/h3&gt;

&lt;p&gt;First, you have to understand the two different kinds of types you created.&lt;/p&gt;

&lt;h4&gt;
  
  
  1. The Concrete Type: &lt;code&gt;struct A&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;A "concrete type" is a blueprint for a real thing that holds data.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Definition&lt;/strong&gt;: Your struct &lt;code&gt;A&lt;/code&gt; is a concrete blueprint. It describes a block of memory that will be created to hold exactly one piece of data: a &lt;code&gt;string&lt;/code&gt; named &lt;code&gt;abc&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt;: When you write &lt;code&gt;a := &amp;amp;A{}&lt;/code&gt;, you are building an actual instance of this blueprint. It's a real, tangible thing in your program's memory. Think of it as a specific worker you just hired.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  2. The Abstract Type: &lt;code&gt;interface I&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;An "abstract type," or interface, is not a thing. It’s a set of rules—a contract.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Definition&lt;/strong&gt;: Your &lt;code&gt;interface I&lt;/code&gt; holds &lt;strong&gt;zero data&lt;/strong&gt;. It only defines a list of &lt;strong&gt;behaviors (methods)&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The Contract&lt;/strong&gt;: This interface says, "I don't care what you are, what data you hold, or where you come from. To be considered an &lt;code&gt;I&lt;/code&gt; by the Go compiler, you must provide one behavior: a method called &lt;code&gt;f1()&lt;/code&gt; that takes no arguments and returns nothing."&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  ✨ The magic Explained: Go's Implicit Implementation
&lt;/h3&gt;

&lt;p&gt;Here is the entire magic trick, explained.&lt;/p&gt;

&lt;p&gt;In language like &lt;code&gt;Java&lt;/code&gt;, you must explicitly state your intent: &lt;code&gt;public class MyClass implements MyInterface&lt;/code&gt;. You are telling the compiler your intend to follow the contract.&lt;/p&gt;

&lt;p&gt;Go doesn't work that way. "Don't tell me what you &lt;em&gt;intend&lt;/em&gt; to do. Just show me what you can do."&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;🔄 &lt;strong&gt;The Rule in Go:&lt;/strong&gt; A type automatically and implicitly implements an interface if it possesses all the methods that the interface requires.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's apply this rule to our code:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The Contract (&lt;code&gt;interface I&lt;/code&gt;)&lt;/strong&gt;: Requires one method: &lt;code&gt;f1()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Candidate (&lt;code&gt;type *A&lt;/code&gt;)&lt;/strong&gt;: Does our type &lt;code&gt;*A&lt;/code&gt; have all the required methods?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Check&lt;/strong&gt;: Yes. We defined this exact method: &lt;code&gt;func (a *A) f1()&lt;/code&gt;. Its name (&lt;code&gt;f1&lt;/code&gt;) and signature (no args, no returns) perfectly match the contract.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Verdict&lt;/strong&gt;: Because *A has the &lt;code&gt;f1()&lt;/code&gt; method, the Go compiler automatically concludes: "&lt;code&gt;Type *A&lt;/code&gt; satisfies &lt;code&gt;interface I&lt;/code&gt;."&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's it. There is no step five.&lt;/p&gt;

&lt;p&gt;Because &lt;code&gt;*A&lt;/code&gt; satisfies &lt;code&gt;I&lt;/code&gt;, any variable of type &lt;code&gt;*A&lt;/code&gt; (like your &lt;code&gt;a&lt;/code&gt;) can be legally passed to any function that requires an &lt;code&gt;I&lt;/code&gt; (like &lt;code&gt;wantsI&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Inside the &lt;code&gt;wantsI&lt;/code&gt; function, the parameter &lt;code&gt;i&lt;/code&gt; is an interface value. Think of it as a box that holds two things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A label identifying its true, concrete type (in this case, &lt;code&gt;*A&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;The data itself (the pointer to your struct).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When &lt;code&gt;i.f1()&lt;/code&gt; is called, Go looks in the box, sees the type is &lt;code&gt;*A&lt;/code&gt;, and calls the specific &lt;code&gt;f1()&lt;/code&gt; method attached to &lt;code&gt;*A&lt;/code&gt;.&lt;/p&gt;




&lt;p&gt;(Bonus)&lt;/p&gt;

&lt;h3&gt;
  
  
  ⚠️ The Critical Detail: Pointers vs. Values (The "Method Set")
&lt;/h3&gt;

&lt;p&gt;There's one more crucial, expert-level detail here that you got right by default. Notice your method definition:&lt;br&gt;
&lt;code&gt;func (a *A) f1()&lt;/code&gt;&lt;br&gt;
This is a &lt;strong&gt;pointer receiver&lt;/strong&gt;.This means the f1() is not attached to the &lt;code&gt;A&lt;/code&gt; struct itself, but to a pointer to an &lt;code&gt;A&lt;/code&gt; struct (&lt;code&gt;*A&lt;/code&gt;). This defines what's called the &lt;strong&gt;method set&lt;/strong&gt;. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The method set for type &lt;code&gt;*A&lt;/code&gt;(the pointer) includes &lt;code&gt;f1()&lt;/code&gt;.✅&lt;/li&gt;
&lt;li&gt;The method set for type &lt;code&gt;A&lt;/code&gt;(the value) doesn't include &lt;code&gt;f1()&lt;/code&gt;.❌&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;This means &lt;code&gt;*A&lt;/code&gt; &lt;strong&gt;implements&lt;/strong&gt; &lt;code&gt;I&lt;/code&gt;, but the plain &lt;code&gt;A&lt;/code&gt; &lt;strong&gt;Does NOT&lt;/strong&gt; ! ✅&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is why your main function must create a pointer (&lt;code&gt;a := &amp;amp;A{}&lt;/code&gt;) to work. If you tried to create a value instead, the program would fail to compile.&lt;/p&gt;

&lt;h4&gt;
  
  
  Example (What Doesn't Work)
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// Create a_val as a VALUE (type A), not a pointer&lt;/span&gt;
    &lt;span class="n"&gt;a_val&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt; 
    &lt;span class="n"&gt;a_val&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;abc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"test value"&lt;/span&gt;

    &lt;span class="c"&gt;// This line will cause a compile-time error!&lt;/span&gt;
    &lt;span class="n"&gt;wantsI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a_val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The compiler will not run while showing this error:&lt;br&gt;
&lt;code&gt;cannot use a_val (variable of type A) as I value in argument to wantsI: A does not implement I (method f1 has pointer receiver)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This error message is the compiler explicitly telling you the logic: &lt;code&gt;A&lt;/code&gt; doesn't implement &lt;code&gt;I&lt;/code&gt; because its method set is missing &lt;code&gt;f1()&lt;/code&gt;, which is only on the &lt;em&gt;pointer type&lt;/em&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  💬 Final Takeaway
&lt;/h2&gt;

&lt;p&gt;This design is the genius of Go. Interfaces are not about &lt;em&gt;identity&lt;/em&gt; or &lt;em&gt;inheritance&lt;/em&gt; (what a thing is). They are about &lt;strong&gt;behavior&lt;/strong&gt; (what a thing can do).&lt;/p&gt;

&lt;p&gt;This allows you to write functions like &lt;code&gt;wantsI&lt;/code&gt; that are completely decoupled from your concrete data structures like &lt;code&gt;A&lt;/code&gt;. You can write 100 different structs, and as long as they all have an &lt;code&gt;f1()&lt;/code&gt; method, your &lt;code&gt;wantsI&lt;/code&gt; function can accept every single one of them without ever knowing they exist. This is the key to flexible, testable, and maintainable software.&lt;/p&gt;

&lt;h2&gt;
  
  
  📜 Referance
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://go.dev/tour/methods/10" rel="noopener noreferrer"&gt;Interfaces are implemented implicitly - go.dev&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://go.dev/wiki/MethodSets" rel="noopener noreferrer"&gt;Method Set - go.dev&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>go</category>
      <category>polymorphism</category>
      <category>interface</category>
    </item>
    <item>
      <title>Automate Github Page Deployment using Vue3/Vite</title>
      <dc:creator>Ishmam Abir | イシュマム・アビル</dc:creator>
      <pubDate>Tue, 03 Jun 2025 05:00:46 +0000</pubDate>
      <link>https://dev.to/ishmam_abir/automate-github-page-deployment-using-vue3vite-12h2</link>
      <guid>https://dev.to/ishmam_abir/automate-github-page-deployment-using-vue3vite-12h2</guid>
      <description>&lt;p&gt;In my previous article, I posted about how to publish a website created with Vue/Vite on GitHub Pages. In this follow-up, we'll automate the deployment process using GitHub Actions. This means your webpage will automatically update just by pushing changes to the &lt;code&gt;main&lt;/code&gt; branch using &lt;code&gt;git push&lt;/code&gt;.&lt;/p&gt;




&lt;p&gt;My previous article about setting up GitHub Pages can be found here =&amp;gt; &lt;a href="https://dev.to/ishmam_abir/publish-a-vuejs-3vite-project-on-github-pages-2a0b"&gt;Publish a Vue.js 3 / Vite Project on GitHub Pages&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Make sure you've set up your project according to the previous article before proceeding. Once that's done, we can dive into setting up the GitHub Action.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 1: Create YML File
&lt;/h2&gt;

&lt;p&gt;First, you'll need to create a specific directory structure in your project's root. This tells GitHub Actions where to find your workflow files.&lt;/p&gt;

&lt;p&gt;Create a &lt;code&gt;.github&lt;/code&gt; folder in your project's root directory. Inside the &lt;code&gt;.github&lt;/code&gt; folder, create another folder named &lt;code&gt;workflows&lt;/code&gt;. Finally, inside the &lt;code&gt;workflows&lt;/code&gt; folder, create a new file named &lt;code&gt;deploy.yml&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Your folder structure should look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;my-project-root/
├── .github/
│   └── workflows/
│       └── deploy.yml
├── src/
├── public/
├── package.json
└── ... (other project files)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This &lt;code&gt;deploy.yml&lt;/code&gt; file will contain the instructions for our automated deployment.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 2: Set GitHub Secrets
&lt;/h2&gt;

&lt;p&gt;To allow GitHub Actions to push to your repository (specifically to the &lt;code&gt;gh-pages&lt;/code&gt; branch), you need to provide secure credentials. We'll use GitHub Secrets for this. You'll need to set up two secrets in your repository's settings:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;code&gt;EMAIL&lt;/code&gt;: The email address associated with your GitHub account.&lt;/li&gt;
&lt;li&gt; &lt;code&gt;GH_TOKEN&lt;/code&gt;: A GitHub Personal Access Token with repository permissions.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Get GitHub Token
&lt;/h3&gt;

&lt;p&gt;To get a GitHub Personal Access Token (PAT):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Go to your GitHub &lt;strong&gt;Settings&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt; Navigate to &lt;strong&gt;Developer settings&lt;/strong&gt; &amp;gt; &lt;strong&gt;Personal access tokens&lt;/strong&gt; &amp;gt; &lt;strong&gt;Tokens (classic)&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt; Click on &lt;strong&gt;Generate new token&lt;/strong&gt; (or &lt;strong&gt;Generate new token (classic)&lt;/strong&gt;).&lt;/li&gt;
&lt;li&gt; Give your token a descriptive name (e.g., &lt;code&gt;GH_PAGES_DEPLOY&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt; Select the &lt;strong&gt;expiration&lt;/strong&gt; for your token.&lt;/li&gt;
&lt;li&gt; Under &lt;strong&gt;Select scopes&lt;/strong&gt;, check the &lt;code&gt;repo&lt;/code&gt; scope. This will grant the token permissions to access and modify your repositories.&lt;/li&gt;
&lt;li&gt; Click &lt;strong&gt;Generate token&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;⚠ Important&lt;/strong&gt;: Copy the generated token immediately. You won't be able to see it again.&lt;/p&gt;
&lt;/blockquote&gt;



&lt;p&gt;Now, go to your project repository on GitHub:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Click on &lt;strong&gt;Settings&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt; In the left sidebar, navigate to &lt;strong&gt;Secrets and variables&lt;/strong&gt; &amp;gt; &lt;strong&gt;Actions&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt; Click on &lt;strong&gt;New repository secret&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt; For the first secret, enter &lt;code&gt;GH_TOKEN&lt;/code&gt; as the &lt;strong&gt;Name&lt;/strong&gt; and paste your copied Personal Access Token into the &lt;strong&gt;Secret&lt;/strong&gt; field. Click &lt;strong&gt;Add secret&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt; Create another secret. Enter &lt;code&gt;EMAIL&lt;/code&gt; as the &lt;strong&gt;Name&lt;/strong&gt; and your GitHub email address as the &lt;strong&gt;Secret&lt;/strong&gt;. Click &lt;strong&gt;Add secret&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Freq2z4clzdo5i2zeslv4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Freq2z4clzdo5i2zeslv4.png" alt="Secret Create" width="800" height="445"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These secrets will be securely accessible within our GitHub Actions workflow.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3: Write Deploy Command
&lt;/h2&gt;

&lt;p&gt;Now, open your &lt;code&gt;deploy.yml&lt;/code&gt; file and add the following configuration. This YAML code defines the workflow for deploying your Vue.js project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy Vue.js Project to GitHub Pages&lt;/span&gt;

&lt;span class="c1"&gt;# Controls when the workflow will run&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;# Triggers the workflow on push events but only for the main branch&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;main&lt;/span&gt;

&lt;span class="c1"&gt;# A workflow run is made up of one or more jobs that can run sequentially or in parallel&lt;/span&gt;
&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;# This workflow contains a single job called "deploy-project"&lt;/span&gt;
  &lt;span class="na"&gt;deploy-project&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# The type of runner that the job will run on&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;

    &lt;span class="c1"&gt;# Steps represent a sequence of tasks that will be executed as part of the job&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout code&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;

    &lt;span class="c1"&gt;# Sets up Node\.js in the environment&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Set up Node.js&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v4&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;latest"&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install dependencies&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm ci&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;build project&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm run build&lt;/span&gt;

     &lt;span class="c1"&gt;# Deploys the built project to the gh\-pages branch&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy to GitHub Pages&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;cd dist&lt;/span&gt;
          &lt;span class="s"&gt;git config --global user.email "${{ secrets.EMAIL }}"&lt;/span&gt;
          &lt;span class="s"&gt;git config --global user.name "${{ github.actor }}"&lt;/span&gt;
          &lt;span class="s"&gt;git init&lt;/span&gt;
          &lt;span class="s"&gt;git add -A&lt;/span&gt;
          &lt;span class="s"&gt;git commit -m 'Automated deployment'&lt;/span&gt;
          &lt;span class="s"&gt;git push -f https://${{ github.actor }}:${{ secrets.GH_TOKEN }}@github.com/${{ github.repository }}.git master:gh-pages&lt;/span&gt;
        &lt;span class="na"&gt;shell&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bash&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we've defined a job named &lt;code&gt;deploy-project&lt;/code&gt; that will execute several steps to deploy our application:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Checkout code&lt;/strong&gt;: It checks out our repository's code.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Set up Node.js&lt;/strong&gt;: It installs the specified (or latest) version of Node.js.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Install dependencies&lt;/strong&gt;: It runs &lt;code&gt;npm ci&lt;/code&gt; to install our project's dependencies. This is generally preferred in CI environments over &lt;code&gt;npm install&lt;/code&gt; as it uses the &lt;code&gt;package-lock.json&lt;/code&gt; or &lt;code&gt;npm-shrinkwrap.json&lt;/code&gt; for more reproducible builds.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Build project&lt;/strong&gt;: It executes our build script (usually &lt;code&gt;npm run build&lt;/code&gt;) to generate the static files in the &lt;code&gt;dist&lt;/code&gt; directory.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Deploy to GitHub Pages&lt;/strong&gt;: This is the core deployment step.

&lt;ul&gt;
&lt;li&gt;It navigates into the &lt;code&gt;dist&lt;/code&gt; folder (where our built files are).&lt;/li&gt;
&lt;li&gt;Configures Git with the email (from &lt;code&gt;secrets.EMAIL&lt;/code&gt;) and username (the GitHub actor who triggered the action).&lt;/li&gt;
&lt;li&gt;Initializes a new Git repository in the &lt;code&gt;dist&lt;/code&gt; folder.&lt;/li&gt;
&lt;li&gt;Adds all files, commits them with a message.&lt;/li&gt;
&lt;li&gt;Force pushes the contents of the &lt;code&gt;dist&lt;/code&gt; folder to the &lt;code&gt;gh-pages&lt;/code&gt; branch of our repository using the &lt;code&gt;GH_TOKEN&lt;/code&gt; secret. The &lt;code&gt;HEAD:gh-pages&lt;/code&gt; syntax ensures that the current commit of the &lt;code&gt;dist&lt;/code&gt; directory becomes the &lt;code&gt;gh-pages&lt;/code&gt; branch.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;After committing this &lt;code&gt;deploy.yml&lt;/code&gt; file to our &lt;code&gt;main&lt;/code&gt; branch and pushing it to GitHub, the Action should trigger automatically. We can monitor its progress under the "Actions" tab of your GitHub repository. Any subsequent pushes to &lt;code&gt;main&lt;/code&gt; will also trigger this workflow, automatically rebuilding and redeploying our site!&lt;br&gt;
Check the changes at your gh-pages&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://&amp;lt;username&amp;gt;.github.io/&amp;lt;your-repository-name&amp;gt;/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In my case, as my repository name is &lt;code&gt;Portfolio&lt;/code&gt; &amp;amp; my username(check your's at profile setting page) is &lt;code&gt;ishmamabir&lt;/code&gt;, my url is:&lt;br&gt;
&lt;a href="https://ishmamabir.github.io/Portfolio/" rel="noopener noreferrer"&gt;https://ishmamabir.github.io/Portfolio/&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;By following these steps, we can automate the deployment process!&lt;br&gt;
Every time changes are pushed into the main branch, they are immediately uploaded to the deploy page.&lt;/p&gt;

&lt;p&gt;Apply this to your codebase and enjoy! ✨&lt;/p&gt;

</description>
      <category>vue</category>
      <category>vite</category>
      <category>githubactions</category>
      <category>deployaction</category>
    </item>
    <item>
      <title>Publish a Vue.js 3/Vite Project on GitHub Pages</title>
      <dc:creator>Ishmam Abir | イシュマム・アビル</dc:creator>
      <pubDate>Tue, 13 May 2025 09:51:45 +0000</pubDate>
      <link>https://dev.to/ishmam_abir/publish-a-vuejs-3vite-project-on-github-pages-2a0b</link>
      <guid>https://dev.to/ishmam_abir/publish-a-vuejs-3vite-project-on-github-pages-2a0b</guid>
      <description>&lt;p&gt;Publishing a static website for portfolio or information is cool.We can do it for free using github pages.&lt;br&gt;&lt;br&gt;
This guide will walk you through the process of deploying a Vue.js 3 application built with Vite to GitHub Pages.&lt;br&gt;
In this article first I will deploy a Vuejs project to to github pages. And in the next Part I will automate the deployment process using github actions.&lt;/p&gt;
&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Account&lt;/strong&gt; - We need a GitHub account to create a repository.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vue.js 3 Project&lt;/strong&gt; - A Vue.js 3 project created using &lt;a href="https://vitejs.dev/" rel="noopener noreferrer"&gt;Vite&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Git&lt;/strong&gt; - Installed and configured locally.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  Initial Process
&lt;/h2&gt;

&lt;p&gt;I won't talk much about about basic initialization as you already know what to do! I am skipping the basics, make sure to initialize them such as:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;create vue project using vite(&lt;code&gt;npm create vite@latest&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;git repository (from &lt;code&gt;git init&lt;/code&gt; to &lt;code&gt;git push&lt;/code&gt;)&lt;/li&gt;
&lt;/ol&gt;



&lt;p&gt;Lets jump into the project configuration part&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 1: Configure Your Project for GitHub Pages
&lt;/h2&gt;

&lt;p&gt;When deploying to GitHub Pages, we need to specify the base URL for our application. GitHub Pages serves the site from a subpath based on the repository name(which we created at the beginning), so it's important to adjust the &lt;code&gt;base&lt;/code&gt; configuration.&lt;/p&gt;

&lt;p&gt;Open &lt;code&gt;vite.config.js&lt;/code&gt; and add the &lt;code&gt;base&lt;/code&gt; configuration. Replace &lt;code&gt;&amp;lt;your-repository-name&amp;gt;&lt;/code&gt; with your actual repository name.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// vite.config.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defineConfig&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vite&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;defineConfig&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;base&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&amp;lt;your-repository-name&amp;gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;// Add this &lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="c1"&gt;//rest you the code&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You may leave the rest of your code alone, and in production, your links will be automatically prefixed with &lt;code&gt;/&amp;lt;your-repository-name&amp;gt;/&lt;/code&gt;.&lt;br&gt;
Let's suppose our repository name is &lt;code&gt;Portfolio&lt;/code&gt;. In that case, our project prefix is: &lt;code&gt;/Portfolio/&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;This is how our vite.config.js will look like:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwr6xep8frbrnixhb71jv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwr6xep8frbrnixhb71jv.png" alt="vite.config.js" width="800" height="404"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Caution: base value is type sensitive. check if your repository name match the base value. For easy understanding, I added &lt;code&gt;P&lt;/code&gt; as uppercase in my repository name and base value. &lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Step 2: Build the Project
&lt;/h2&gt;

&lt;p&gt;Run the build command to prepare the app for deployment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will generate the optimized static files inside the dist/ folder in your project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Deploy to GitHub Pages
&lt;/h2&gt;

&lt;p&gt;Let's assume that you already push your local repository to the Github(if not, do it now using &lt;code&gt;git push -u origin main&lt;/code&gt;).&lt;br&gt;
We need to push all contents of the dist folder to a &lt;code&gt;gh-pages&lt;/code&gt; branch of your project. We can do it yourself in the same way you push code to github. Or, lets just follow these commands to push them efficiently.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git subtree push &lt;span class="nt"&gt;--prefix&lt;/span&gt; dist origin gh-pages
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will push your files &amp;amp; folders from &lt;code&gt;/dist&lt;/code&gt; folder to a new or existing &lt;code&gt;gh-pages&lt;/code&gt; branch.&lt;br&gt;
Check yor git repository's branch list, you will see a new branch named &lt;code&gt;gh-pages&lt;/code&gt; if you executed it for the first time.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjhbluxls35lji7bs63xj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjhbluxls35lji7bs63xj.png" alt="gh-pages branch" width="473" height="471"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;ignore other branches, those are created by me.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Step 4: Enable GitHub Pages in the Repository Settings
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Go to your GitHub repository.&lt;/li&gt;
&lt;li&gt;Navigate to Settings &amp;gt; Pages.&lt;/li&gt;
&lt;li&gt;In the Source section,select 'Deploy from a branch', then select the 'gh-pages' branch.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F71z7xuo9bfpi9g9mw3yr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F71z7xuo9bfpi9g9mw3yr.png" alt="Settings page" width="800" height="525"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It will automatically update the settings, Your site should now be live at:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://&amp;lt;username&amp;gt;.github.io/&amp;lt;your-repository-name&amp;gt;/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In my case, as my repository name is &lt;code&gt;Portfolio&lt;/code&gt; &amp;amp; my username(check your's at profile setting page) is &lt;code&gt;ishmamabir&lt;/code&gt;, my url is:&lt;br&gt;
&lt;a href="https://ishmamabir.github.io/Portfolio/" rel="noopener noreferrer"&gt;https://ishmamabir.github.io/Portfolio/&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;We have successfully published our vuejs3 project to our github pages! &lt;br&gt;
Now I can access this website from anywhere and any device&lt;/p&gt;


&lt;h2&gt;
  
  
  Alternative to Step 3 !! Install the gh-pages node module
&lt;/h2&gt;

&lt;p&gt;To easily deploy the &lt;code&gt;dist/&lt;/code&gt; folder to GitHub Pages, you can use the gh-pages package. Its easy, shortcut and reduces the hassle of Step 3&lt;/p&gt;
&lt;h3&gt;
  
  
  5.1: Install &lt;code&gt;gh-pages&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Install gh-pages as a dev dependency:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;gh-pages &lt;span class="nt"&gt;--save-dev&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5.2: Update &lt;code&gt;package.json&lt;/code&gt; with Deploy Script
&lt;/h3&gt;

&lt;p&gt;dd the deploy script to package.json to deploy the app to GitHub Pages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;//previous&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;lines&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"deploy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"vite build &amp;amp;&amp;amp; gh-pages -d dist"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;alternatively you can also add this. any one will work fine.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;//previous&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;lines&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"predeploy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm run build"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"deploy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"gh-pages -d dist"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;your &lt;code&gt;package.json&lt;/code&gt; will look like this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbyxp43tmyppcpeljm5p3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbyxp43tmyppcpeljm5p3.png" alt="package.json" width="800" height="302"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  5.3: Run the Deploy Command
&lt;/h3&gt;

&lt;p&gt;Finally, deploy the built project to GitHub Pages by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will automatically push the contents of the dist/ folder to the gh-pages branch of your repository. You have to do nothing after this, and your changes will be visible to the github page.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;N.B.: You can find your url in the page section inside the Settings page(see my settings page's screenshot).&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;This is how easily i deployed my portfolio to the github pages. &lt;/p&gt;

&lt;p&gt;Now, You can also do it !&lt;/p&gt;

</description>
      <category>vue</category>
      <category>vite</category>
      <category>githubpage</category>
      <category>vuejs3</category>
    </item>
    <item>
      <title>Set Up Your Own Local GitLab Server | Self-hosted GitLab</title>
      <dc:creator>Ishmam Abir | イシュマム・アビル</dc:creator>
      <pubDate>Tue, 29 Oct 2024 05:03:26 +0000</pubDate>
      <link>https://dev.to/ishmam_abir/set-up-your-own-local-gitlab-server-self-hosted-gitlab-4d1</link>
      <guid>https://dev.to/ishmam_abir/set-up-your-own-local-gitlab-server-self-hosted-gitlab-4d1</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Ever wondered how to run your own Git on local server? Is it even possible? 🤷🏻‍♀️ &lt;br&gt;
&lt;em&gt;Ans: Yes, possible&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Do you want full control over your repositories, CI/CD pipelines, and user access? Setting up a self-hosted GitLab instance will help! &lt;br&gt;
It may appear difficult, but it's more easier than you think—and I'll walk you through it step by step!&lt;/p&gt;

&lt;p&gt;This is the part 1 of &lt;code&gt;Git on localhost! Local GitLab Server&lt;/code&gt; series. This article(part 1) contains only the git version control setup on the local machine,  We will dive further on the upcoming series. &lt;/p&gt;


&lt;h2&gt;
  
  
  Why Host Your Own GitLab Server?
&lt;/h2&gt;

&lt;p&gt;While services like GitHub and GitLab.com offer excellent hosted solutions, sometimes you just want full control. Running your own GitLab server can provide:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Complete autonomy over your code and repositories.&lt;/li&gt;
&lt;li&gt;Unlimited private repositories without cost.&lt;/li&gt;
&lt;li&gt;Custom user access management for your team or projects.&lt;/li&gt;
&lt;li&gt;Full control of CI/CD pipelines.&lt;/li&gt;
&lt;li&gt;Data privacy and security—everything stays on your machine or network.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before we begin, make sure you have the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Docker installed (we'll use Docker to easily run GitLab in a container).&lt;/li&gt;
&lt;li&gt;Admin privileges on your machine.&lt;/li&gt;
&lt;li&gt;Minimum hardware requirements(&lt;a href="https://docs.gitlab.com/ee/install/requirements.html" rel="noopener noreferrer"&gt;given here&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Installation Process
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Step 0: Install Docker
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;ignore this step if docker is already installed on your machine.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Install Docker from its &lt;a href="https://www.docker.com/get-started/" rel="noopener noreferrer"&gt;official website&lt;/a&gt; for your desired OS.&lt;br&gt;
Also, we can use any other open source container management tools (eg: &lt;a href="https://rancherdesktop.io/" rel="noopener noreferrer"&gt;Rancher Desktop&lt;/a&gt;) instead of Docker&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Tip: Before proceeding to the next step, ensure that Docker is running.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  Step 1: Download the GitLab CE Docker Image
&lt;/h3&gt;

&lt;p&gt;Open your terminal and write this command to pull the latest gitlab image&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker pull gitlab/gitlab-ce:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By doing this, the GitLab CE image that we need to run the server is downloaded.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2:  Create Directories for Persistent Storage
&lt;/h3&gt;

&lt;p&gt;To guarantee that GitLab data (such as repositories, settings, and logs) are saved between restarts, establish folders on your own system for these files.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /code/gitlab/config /code/gitlab/logs /code/gitlab/data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Tips: On &lt;strong&gt;Windows&lt;/strong&gt;, you’ll need to use Windows-style paths:&lt;/p&gt;


&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir D:\code\gitlab\config D:\code\gitlab\logs D:\code\gitlab\data
&lt;/code&gt;&lt;/pre&gt;

&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Step 3: Start the GitLab Container
&lt;/h3&gt;

&lt;p&gt;Now it is time to start the GitLab server!&lt;br&gt;
To launch &amp;amp; configure GitLab within a container, we'll use the &lt;code&gt;docker run&lt;/code&gt; command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;--detach&lt;/span&gt; 
    &lt;span class="nt"&gt;--hostname&lt;/span&gt; localhost 
    &lt;span class="nt"&gt;--publish&lt;/span&gt; 8443:443 
    &lt;span class="nt"&gt;--publish&lt;/span&gt; 8080:80 
    &lt;span class="nt"&gt;--publish&lt;/span&gt; 6022:22 
    &lt;span class="nt"&gt;--name&lt;/span&gt; gitlab 
    &lt;span class="nt"&gt;--restart&lt;/span&gt; always 
    &lt;span class="nt"&gt;--volume&lt;/span&gt; code/gitlab/config:/etc/gitlab 
    &lt;span class="nt"&gt;--volume&lt;/span&gt; code/gitlab/logs:/var/log/gitlab 
    &lt;span class="nt"&gt;--volume&lt;/span&gt; code/gitlab/data:/var/opt/gitlab 
    gitlab/gitlab-ce
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Breakdown
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Hostname&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;--hostname localhost&lt;/code&gt;: We’ve set the hostname to &lt;code&gt;localhost&lt;/code&gt;, which should be fine for local testing. You can change this to a custom domain if needed.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ports&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;--publish 8443:443&lt;/code&gt;: Exposes GitLab’s HTTPS (443) to port 8443 on your host machine.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--publish 8080:80&lt;/code&gt;: Exposes GitLab’s HTTP (80) to port 8080 on your host.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--publish 6022:22&lt;/code&gt;: Exposes SSH access (22) to port 6022 (used for cloning repositories via SSH).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Volumes&lt;/strong&gt;:
The volumes map your local directories to the container.

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;--volume code/gitlab/config:/etc/gitlab&lt;/code&gt;: Maps the configuration files to the host’s directory.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--volume code/gitlab/logs:/var/log/gitlab&lt;/code&gt;: Stores the logs.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--volume code/gitlab/data:/var/opt/gitlab&lt;/code&gt;: Stores GitLab repositories and other persistent data.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Make sure to replace the &lt;code&gt;code/gitlab/&lt;/code&gt; with the actual absolute path on your system. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Note&lt;/em&gt;: on &lt;strong&gt;Windows&lt;/strong&gt;, volume paths need to be &lt;code&gt;D:/code/github/&lt;/code&gt; instead of &lt;code&gt;code/gitlab/&lt;/code&gt;for absolute path.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Step 4: Access GitLab Instance
&lt;/h3&gt;

&lt;p&gt;Now that your GitLab container is running, open a web browser and go to &lt;code&gt;http://localhost:8080&lt;/code&gt; &lt;br&gt;
You should see the GitLab login screen! Since this is the first time you're logging in, The initialization process could take a lengthy time. You can monitor this process with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker logs &lt;span class="nt"&gt;-f&lt;/span&gt; gitlab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that, you will see this page: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqc5ljwc6eh1q9192tvh9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqc5ljwc6eh1q9192tvh9.png" alt="login page" width="718" height="506"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For logging in for the very first time, GitLab provides a default user &lt;strong&gt;root&lt;/strong&gt; and its password.&lt;br&gt;
The default password can be found inside the &lt;code&gt;/etc/gitlab/initial_root_password&lt;/code&gt;.&lt;br&gt;
Run the below command to get the password:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; gitlab &lt;span class="nb"&gt;cat&lt;/span&gt; /etc/gitlab/initial_root_password
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or, you can use this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; gitlab &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s1"&gt;'Password:'&lt;/span&gt; 
/etc/gitlab/initial_root_password
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo2h9bdv3yf27ikftrm9k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo2h9bdv3yf27ikftrm9k.png" alt="Get Password" width="800" height="276"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: This password file will delete automatically when the first container restart happens afer 24 hours. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;After login, This will be our homepage:&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F19lfm7phinl8cyq30h9a.png" alt="GitLab Homepage" width="800" height="424"&gt;
&lt;/h2&gt;

&lt;p&gt;Our Project installation is completed. Now We can use this as our local git without internet.&lt;br&gt;
In the next article, i will try push a small test project to our local git server &amp;amp; clone from there.&lt;/p&gt;




&lt;h2&gt;
  
  
  Alternative Approach
&lt;/h2&gt;

&lt;p&gt;In the Installation Process, we install the server by running several docker commands in our cli. &lt;br&gt;
But now  in this approach, we can replace the Step 1 &amp;amp; Step 3 by adding a &lt;strong&gt;docker-compose&lt;/strong&gt; file.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This procedure has been recommended by the GitLab documentation.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a &lt;code&gt;docker-compose.yml&lt;/code&gt; file &amp;amp; copy this below lines:
&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3.8'&lt;/span&gt;

&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;gitlab&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gitlab/gitlab-ce:latest&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gitlab&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;always&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;GITLAB_OMNIBUS_CONFIG&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
        &lt;span class="s"&gt;# Add any other gitlab.rb configuration here, each on its own line&lt;/span&gt;
        &lt;span class="s"&gt;external_url 'http://localhost:8080'&lt;/span&gt;
        &lt;span class="s"&gt;gitlab_rails['gitlab_shell_ssh_port'] = 6022&lt;/span&gt;
        &lt;span class="s"&gt;gitlab_rails['time_zone'] = 'Asia/Tokyo'&lt;/span&gt;

    &lt;span class="na"&gt;hostname&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;localhost&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;8443:443"&lt;/span&gt;   &lt;span class="c1"&gt;# HTTPS&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;8080:80"&lt;/span&gt;    &lt;span class="c1"&gt;# HTTP&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;6022:22"&lt;/span&gt;    &lt;span class="c1"&gt;# SSH for Git access&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;code/gitlab/config:/etc/gitlab&lt;/span&gt;   &lt;span class="c1"&gt;# Configuration storage&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;code/gitlab/logs:/var/log/gitlab&lt;/span&gt;  &lt;span class="c1"&gt;# Logs storage&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;code/gitlab/data:/var/opt/gitlab&lt;/span&gt;  &lt;span class="c1"&gt;# Data storage (repositories, etc.)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Note: For Windows, change path to &lt;code&gt;C:/path/to/code/gitlab/**&lt;/code&gt; instead of &lt;code&gt;code/gitlab/**&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;In the same directory as docker-compose.yml, Run the docker compose command to start GitLab:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker compose up -d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Common Troubleshooting Tips
&lt;/h2&gt;

&lt;p&gt;If you get a &lt;strong&gt;404 Page Not Found&lt;/strong&gt; or have issues accessing GitLab, here are some things to check:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Is the container running?&lt;/strong&gt;: Run docker ps to verify the GitLab container is up. If not, check the logs with docker logs gitlab to troubleshoot.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Wait for initialization&lt;/strong&gt;: GitLab can take several minutes to initialize on first launch. Check the container logs with &lt;code&gt;docker logs -f gitlab&lt;/code&gt; and wait for the message saying GitLab is ready.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check port mappings&lt;/strong&gt;: Ensure you’re accessing the correct ports (&lt;code&gt;80&lt;/code&gt; for HTTP or &lt;code&gt;443&lt;/code&gt; for HTTPS). If there's a conflict, adjust the ports in the &lt;code&gt;docker run&lt;/code&gt; command.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Firewall/Antivirus&lt;/strong&gt;: On Windows, ensure Docker is allowed through the firewall and no other security software is blocking the ports.&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;🎉 Now We have finished configuring our self-hosted GitLab server. We can now manage our code using this as our git server. &lt;br&gt;
In the upcoming sections, we will commit a project onto our local self-hosted GitLab server and set up a CICD pipeline on it.&lt;br&gt;
Let's catch up on the next section! ✨&lt;/p&gt;

</description>
      <category>git</category>
      <category>gitlab</category>
      <category>docker</category>
      <category>localhost</category>
    </item>
    <item>
      <title>Swithing Data Types: Understanding the 'Type Switch' in GoLang</title>
      <dc:creator>Ishmam Abir | イシュマム・アビル</dc:creator>
      <pubDate>Tue, 18 Jun 2024 08:27:31 +0000</pubDate>
      <link>https://dev.to/ishmam_abir/swithing-data-types-understanding-the-type-switch-in-golang-4enc</link>
      <guid>https://dev.to/ishmam_abir/swithing-data-types-understanding-the-type-switch-in-golang-4enc</guid>
      <description>&lt;p&gt;Type switches in Golang offer a robust mechanism for handling different types within interfaces. They simplify the code and enhance readability, making it easier to manage complex logic based on type assertions. Whether you are dealing with polymorphic data structures or custom error types, type switches provide a clean and effective solution.&lt;/p&gt;

&lt;h3&gt;
  
  
  TL;DR:
&lt;/h3&gt;

&lt;p&gt;It allows executing different code based on the type of an interface value, using the syntax switch v := x.(type) { case T1: /&lt;em&gt;...&lt;/em&gt;/ case T2: /&lt;em&gt;...&lt;/em&gt;/ default: /&lt;em&gt;...&lt;/em&gt;/ }&lt;/p&gt;




&lt;h3&gt;
  
  
  What is a Type Switch?
&lt;/h3&gt;

&lt;p&gt;A type switch is a construct that permits the switching over the types of an interface value. Unlike a regular switch statement that evaluates expressions to find a matching case, a type switch is used to compare the type of a variable. This is particularly useful when you are working with interfaces and need to handle different types differently.&lt;/p&gt;

&lt;h3&gt;
  
  
  Syntax of Type Switch
&lt;/h3&gt;

&lt;p&gt;The syntax of a type switch in Go is similar to that of a regular switch statement but includes a special .(type) assertion. Here is the basic structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;T1&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="c"&gt;// v has type T1&lt;/span&gt;
&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;T2&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="c"&gt;// v has type T2&lt;/span&gt;
&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="c"&gt;// no match; v has type of the interface value x&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this structure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;x&lt;/code&gt; is the interface value whose dynamic type is being inspected.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;v&lt;/code&gt; is the variable that will hold the value of &lt;code&gt;x&lt;/code&gt; in the respective case.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;T1&lt;/code&gt;, &lt;code&gt;T2&lt;/code&gt;, etc., are the types being checked against.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Example
&lt;/h4&gt;

&lt;p&gt;An example according to the syntex is given below&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"fmt"&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;SelectType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;{})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%v is String Type&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%v is int type&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="kt"&gt;float64&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%v is float type&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"type of %v is not defined&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;SelectType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"cow"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;SelectType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;3.1416&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;SelectType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cow is String Type
3.1416 is float type
type of true is not defined
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, Data type of an interface is showing using the Type switch. &lt;/p&gt;




&lt;h3&gt;
  
  
  Real-life Example
&lt;/h3&gt;

&lt;p&gt;Consider a scenario in a web application where you need to handle different types of errors in a custom way. Go's error handling can be enhanced using type switches to provide more detailed error processing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"net"&lt;/span&gt;
    &lt;span class="s"&gt;"os"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;// Custom error types&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;NetworkError&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Op&lt;/span&gt;  &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;Err&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;NetworkError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"network error: %s: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Op&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;FileError&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Path&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;Err&lt;/span&gt;  &lt;span class="kt"&gt;error&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;FileError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"file error: %s: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;handleError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;NetworkError&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Handling network error:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;FileError&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Handling file error:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Handling general error:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// Simulate different errors&lt;/span&gt;
    &lt;span class="n"&gt;netErr&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;NetworkError&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Op&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"dial"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Err&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;net&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UnknownNetworkError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"tcp"&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
    &lt;span class="n"&gt;fileErr&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;FileError&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"/invalid/path"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Err&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ErrNotExist&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;handleError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;netErr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;handleError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fileErr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;handleError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"a general error"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this real-life example, &lt;code&gt;handleError&lt;/code&gt; function uses a type switch to handle different custom error types (&lt;code&gt;NetworkError&lt;/code&gt; and &lt;code&gt;FileError&lt;/code&gt;) and provides specific messages for each type of error.&lt;/p&gt;

&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Handling network error: network error: dial: unknown network tcp
Handling file error: file error: /invalid/path: file does not exist
Handling general error: a general error
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Hopefully this example will make a clear vision where we can use the type switch in our development work.&lt;/p&gt;

</description>
      <category>go</category>
      <category>typeswitch</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
