<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[MARS Tech Engineering]]></title><description><![CDATA[DevOps Engineer with 7+ years in backend, cloud, and CI/CD. Expert in Kubernetes, Docker, GitHub Actions, IDPs, and observability with Grafana &amp; Prometheus.]]></description><link>https://blog.mdaburaihan.pro</link><generator>RSS for Node</generator><lastBuildDate>Wed, 15 Apr 2026 03:19:06 GMT</lastBuildDate><atom:link href="https://blog.mdaburaihan.pro/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Automating Docker Image Versioning, Build, Push, and Scanning Using GitHub Actions]]></title><description><![CDATA[Introduction
In a previous blog post, Beginner’s Guide: Build, Push, and Deploy Docker Image with GitHub Actions, we explored how to set up a GitHub Actions workflow for building, pushing, and deploying Docker images. This guide takes it a step furth...]]></description><link>https://blog.mdaburaihan.pro/automating-docker-image-versioning-build-push-and-scanning-using-github-actions</link><guid isPermaLink="true">https://blog.mdaburaihan.pro/automating-docker-image-versioning-build-push-and-scanning-using-github-actions</guid><dc:creator><![CDATA[Md. Abu Raihan Srabon]]></dc:creator><pubDate>Tue, 17 Dec 2024 15:47:28 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1734451820321/2b6bee57-f8b7-4b0a-9d94-bd6bce7c427c.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p>In a previous blog post, <a target="_blank" href="https://dev.to/msrabon/beginners-guide-build-push-and-deploy-docker-image-with-github-actions-aa7">Beginner’s Guide: Build, Push, and Deploy Docker Image with GitHub Actions</a>, we explored how to set up a GitHub Actions workflow for building, pushing, and deploying Docker images. This guide takes it a step further by adding semantic versioning, cleaner build workflows, and vulnerability scanning to the CI/CD pipeline. By implementing these improvements, you can better automate Docker image lifecycle management with a robust and professional workflow.</p>
<h2 id="heading-why-this-update">Why This Update?</h2>
<p>The updated workflow introduces several notable enhancements:</p>
<ul>
<li>Semantic Versioning: Automatically bump Docker image versions based on commit messages.</li>
<li>Improved Docker Build and Push: Cleaner setup with GitHub Container Registry (GHCR).</li>
<li>Security Scanning: Use Trivy to scan Docker images for vulnerabilities before deployment.</li>
</ul>
<p>This workflow ensures version control, clean tagging, and improved security measures in an automated CI/CD pipeline.</p>
<h2 id="heading-complete-github-actions-workflow">Complete GitHub Actions Workflow</h2>
<p>Here is the updated GitHub Actions YAML workflow:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1734451818917/62e36835-64fa-41d5-a46f-02f8f5b92753.png" alt="Updated github actions workflow" /></p>
<h2 id="heading-key-improvements-and-explanation">Key Improvements and Explanation</h2>
<ol>
<li>Semantic Versioning</li>
</ol>
<p>Managing Docker image versions can become tedious, especially in collaborative projects. Semantic versioning automates version bumps based on commit messages:</p>
<ul>
<li>Default Behavior: Increments the patch version.</li>
<li><p>Custom Increments:</p>
<ul>
<li>Add bump: major in a commit message to increment the major version.</li>
<li>Add bump: minor in a commit message to increment the minor version.</li>
</ul>
</li>
</ul>
<p>Code Explanation:</p>
<pre><code class="lang-yaml"><span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Determine</span> <span class="hljs-string">Version</span> <span class="hljs-string">Bump</span> <span class="hljs-string">Type</span>
  <span class="hljs-attr">id:</span> <span class="hljs-string">determine-bump-type</span>
  <span class="hljs-attr">run:</span> <span class="hljs-string">|
    echo "level=patch" &gt;&gt; $GITHUB_ENV
    if git log -1 --pretty=%B | grep -q 'bump: major'; then
      echo "level=major" &gt;&gt; $GITHUB_ENV
    elif git log -1 --pretty=%B | grep -q 'bump: minor'; then
      echo "level=minor" &gt;&gt; $GITHUB_ENV</span>
</code></pre>
<p>Here, the script scans the latest commit message for keywords and determines the version bump level.</p>
<ol start="2">
<li>Clean Docker Build and Push to GHCR</li>
</ol>
<p>The Docker image is built and pushed to GitHub Container Registry (GHCR), making it easier to manage images natively in GitHub.</p>
<p>Steps:</p>
<ul>
<li>Log in to the GHCR using GitHub credentials.</li>
<li>Build and tag the image with the new version and latest tag.</li>
</ul>
<p>Code Example:</p>
<pre><code class="lang-yaml"><span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Build</span> <span class="hljs-string">and</span> <span class="hljs-string">Push</span> <span class="hljs-string">Docker</span> <span class="hljs-string">Image</span>
  <span class="hljs-attr">uses:</span> <span class="hljs-string">docker/build-push-action@v6</span>
  <span class="hljs-attr">with:</span>
    <span class="hljs-attr">context:</span> <span class="hljs-string">./php-8.2</span>
    <span class="hljs-attr">file:</span> <span class="hljs-string">./php-8.2/Dockerfile</span>
    <span class="hljs-attr">push:</span> <span class="hljs-literal">true</span>
    <span class="hljs-attr">tags:</span> <span class="hljs-string">|
      ghcr.io/${{ github.repository }}:${{ needs.semver.outputs.new_version }}
      ghcr.io/${{ github.repository }}:latest</span>
</code></pre>
<ol start="3">
<li>Vulnerability Scanning with Trivy</li>
</ol>
<p>Security is critical for containerized applications. Trivy scans the built Docker image for vulnerabilities before deployment. It exits with an error if vulnerabilities are found, ensuring only secure images are deployed.</p>
<p>Code Explanation:</p>
<pre><code class="lang-yaml"><span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Run</span> <span class="hljs-string">Trivy</span> <span class="hljs-string">Vulnerability</span> <span class="hljs-string">Scan</span>
  <span class="hljs-attr">uses:</span> <span class="hljs-string">aquasecurity/trivy-action@0.28.0</span>
  <span class="hljs-attr">with:</span>
    <span class="hljs-attr">scan-type:</span> <span class="hljs-string">'image'</span>
    <span class="hljs-attr">image-ref:</span> <span class="hljs-string">ghcr.io/${{</span> <span class="hljs-string">github.repository</span> <span class="hljs-string">}}:${{</span> <span class="hljs-string">needs.semver.outputs.new_version</span> <span class="hljs-string">}}</span>
    <span class="hljs-attr">format:</span> <span class="hljs-string">'table'</span>
    <span class="hljs-attr">exit-code:</span> <span class="hljs-string">'1'</span>
    <span class="hljs-attr">ignore-unfixed:</span> <span class="hljs-literal">true</span>
    <span class="hljs-attr">vuln-type:</span> <span class="hljs-string">'os,library'</span>
</code></pre>
<ul>
<li><code>scan-type: image</code>: Scans the built image.</li>
<li><code>exit-code: 1</code>: Fails the workflow if vulnerabilities are detected.</li>
<li><code>ignore-unfixed: true</code>: Ignores vulnerabilities without known fixes.</li>
</ul>
<h2 id="heading-conclusion">Conclusion</h2>
<p>This enhanced GitHub Actions workflow adds automation, cleaner versioning, and security scanning to your Docker CI/CD pipeline. By leveraging <strong>semantic versioning</strong>, Docker builds with <strong>GHCR</strong>, and vulnerability scanning via <strong>Trivy</strong>, you can ensure efficient, secure, and manageable image deployments.</p>
<p>For a practical implementation, you can refer to the complete workflow in my <a target="_blank" href="https://github.com/aburaihan-dev/docker-php-base-image">GitHub repository</a>.</p>
<p>If you're new to GitHub Actions or Docker automation, check out my earlier blog post for foundational concepts: <a target="_blank" href="https://blog.lazycoder.ninja/beginners-guide-build-push-and-deploy-docker-image-with-github-actions">Beginner’s Guide: Build, Push, and Deploy Docker Image with GitHub Actions</a>.</p>
<p>Happy automating! </p>
]]></content:encoded></item><item><title><![CDATA[Beginner’s Guide: Build, Push, and Deploy Docker Image with GitHub Actions]]></title><description><![CDATA[In this post, we’ll introduce GitHub Actions and explain how to use them for automating Docker image builds, pushing images to a self-hosted registry, and deploying them to a remote server. This guide is tailored for beginners who want to start simpl...]]></description><link>https://blog.mdaburaihan.pro/beginners-guide-build-push-and-deploy-docker-image-with-github-actions</link><guid isPermaLink="true">https://blog.mdaburaihan.pro/beginners-guide-build-push-and-deploy-docker-image-with-github-actions</guid><dc:creator><![CDATA[Md. Abu Raihan Srabon]]></dc:creator><pubDate>Sun, 10 Nov 2024 14:04:25 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1731247539136/7bcdcfc7-65fc-4d12-b177-043386f55476.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this post, we’ll introduce GitHub Actions and explain how to use them for automating Docker image builds, pushing images to a self-hosted registry, and deploying them to a remote server. This guide is tailored for beginners who want to start simple and expand their knowledge over time.</p>
<ol>
<li>What’s GitHub Actions?</li>
</ol>
<p>GitHub Actions is a powerful tool for automating software workflows directly within your GitHub repository. It allows you to build, test, and deploy your code directly from GitHub. You define your automation tasks as YAML files within your repository, and these tasks run on GitHub’s hosted servers (or self-hosted runners if you prefer).</p>
<p>Why use GitHub Actions?</p>
<ul>
<li>Seamless integration with GitHub repositories.</li>
<li>Customization: Create workflows tailored to your project needs.</li>
<li><p>Ease of use: Simple YAML configuration.</p>
</li>
<li><p>What This Script Does</p>
</li>
</ul>
<p>The given GitHub Actions script automates the CI/CD pipeline for building, tagging, and pushing a Docker image to a self-hosted registry, then deploying it to a remote server. Let’s dive into the main sections of the script and understand how each part works.</p>
<p>a. Checking Out the Code</p>
<pre><code class="lang-yaml"><span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Checkout</span> <span class="hljs-string">Code</span>
  <span class="hljs-attr">uses:</span> <span class="hljs-string">actions/checkout@v3</span>
</code></pre>
<p>This step clones the repository into the GitHub Actions runner, enabling the workflow to access your project files.</p>
<p>b. Setting Up Docker Buildx</p>
<pre><code class="lang-yaml"><span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Set</span> <span class="hljs-string">up</span> <span class="hljs-string">Docker</span> <span class="hljs-string">Buildx</span>
  <span class="hljs-attr">uses:</span> <span class="hljs-string">docker/setup-buildx-action@v2</span>
</code></pre>
<p>Docker Buildx allows the runner to build multi-platform images and use advanced build features.</p>
<p>c. Configuring and Logging into the Docker Registry</p>
<pre><code class="lang-yaml"><span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Add</span> <span class="hljs-string">Registry</span> <span class="hljs-string">to</span> <span class="hljs-string">/etc/hosts</span>
  <span class="hljs-attr">run:</span> <span class="hljs-string">|
    echo "${{ secrets.HOSTS_ENTRY }}" | sudo tee -a /etc/hosts
</span>
<span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Configure</span> <span class="hljs-string">Docker</span> <span class="hljs-string">for</span> <span class="hljs-string">Insecure</span> <span class="hljs-string">Registry</span>
  <span class="hljs-attr">run:</span> <span class="hljs-string">|
    sudo mkdir -p /etc/docker
    echo '{ "insecure-registries": ["https://harbor.example.com"] }' | sudo tee /etc/docker/daemon.json
    sudo systemctl restart docker
</span>
<span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Log</span> <span class="hljs-string">in</span> <span class="hljs-string">to</span> <span class="hljs-string">Docker</span> <span class="hljs-string">Registry</span>
  <span class="hljs-attr">uses:</span> <span class="hljs-string">docker/login-action@v2</span>
  <span class="hljs-attr">with:</span>
    <span class="hljs-attr">registry:</span> <span class="hljs-string">harbor.example.com</span>
    <span class="hljs-attr">username:</span> <span class="hljs-string">${{</span> <span class="hljs-string">secrets.DOCKER_USERNAME</span> <span class="hljs-string">}}</span>
    <span class="hljs-attr">password:</span> <span class="hljs-string">${{</span> <span class="hljs-string">secrets.DOCKER_PASSWORD</span> <span class="hljs-string">}}</span>
</code></pre>
<p>These steps set up Docker on the runner to connect to the self-hosted Harbor registry. It configures Docker to treat the registry as an insecure source (use this cautiously) and logs in using provided credentials.</p>
<p>d. Tagging with a Date-Time-Based Version</p>
<pre><code class="lang-yaml"><span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Generate</span> <span class="hljs-string">Date-Time-Based</span> <span class="hljs-string">Tag</span>
  <span class="hljs-attr">id:</span> <span class="hljs-string">generate_tag</span>
  <span class="hljs-attr">run:</span> <span class="hljs-string">|
    new_version=$(date -u +"v%Y.%m.%d.%H%M%S")
    echo "Generated tag: $new_version"
    echo "version=$new_version" &gt;&gt; $GITHUB_ENV</span>
</code></pre>
<p>This step creates a version tag based on the current UTC date and time, ensuring unique version identifiers for each image build.</p>
<p>e. Building and Pushing the Docker Image</p>
<pre><code class="lang-yaml"><span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Build</span> <span class="hljs-string">Docker</span> <span class="hljs-string">Image</span>
  <span class="hljs-attr">run:</span> <span class="hljs-string">|
    PROJECT_NAME=$(echo "${GITHUB_REPOSITORY}" | cut -d'/' -f2)
    docker build -f .docker/Dockerfile \
      -t harbor.example.com/${{ vars.PROJECT_NAME }}/$PROJECT_NAME:${{ env.version }} -t harbor.example.com/${{ vars.PROJECT_NAME }}/$PROJECT_NAME:latest .
</span>  <span class="hljs-attr">env:</span>
    <span class="hljs-attr">GITHUB_REPOSITORY:</span> <span class="hljs-string">${{</span> <span class="hljs-string">github.repository</span> <span class="hljs-string">}}</span>

<span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Push</span> <span class="hljs-string">Docker</span> <span class="hljs-string">Image</span>
  <span class="hljs-attr">run:</span> <span class="hljs-string">|
    PROJECT_NAME=$(echo "${GITHUB_REPOSITORY}" | cut -d'/' -f2)
    docker push harbor.example.com/${{ vars.PROJECT_NAME }}/$PROJECT_NAME:${{ env.version }}
    docker push harbor.example.com/${{ vars.PROJECT_NAME }}/$PROJECT_NAME:latest
</span>  <span class="hljs-attr">env:</span>
    <span class="hljs-attr">GITHUB_REPOSITORY:</span> <span class="hljs-string">${{</span> <span class="hljs-string">github.repository</span> <span class="hljs-string">}}</span>
</code></pre>
<p>This section builds the Docker image using the Dockerfile and tags it with both the generated version and latest. It then pushes the images to the Harbor registry.</p>
<p>f. Deploying to a Remote Server</p>
<pre><code class="lang-yaml"><span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Deploy</span> <span class="hljs-string">to</span> <span class="hljs-string">Remote</span> <span class="hljs-string">Server</span>
  <span class="hljs-attr">if:</span> <span class="hljs-string">success()</span>
  <span class="hljs-attr">env:</span>
    <span class="hljs-attr">SSH_HOST:</span> <span class="hljs-string">${{</span> <span class="hljs-string">secrets.SSH_HOST</span> <span class="hljs-string">}}</span>
    <span class="hljs-attr">SSH_USERNAME:</span> <span class="hljs-string">${{</span> <span class="hljs-string">secrets.SSH_USERNAME</span> <span class="hljs-string">}}</span>
    <span class="hljs-attr">SSH_PRIVATE_KEY:</span> <span class="hljs-string">${{</span> <span class="hljs-string">secrets.SSH_PRIVATE_KEY</span> <span class="hljs-string">}}</span>
    <span class="hljs-attr">DEPLOY_COMMANDS:</span> <span class="hljs-string">${{</span> <span class="hljs-string">secrets.DEPLOY_COMMANDS</span> <span class="hljs-string">}}</span>
  <span class="hljs-attr">run:</span> <span class="hljs-string">|
    echo "${SSH_PRIVATE_KEY}" &gt; /tmp/private_key
    chmod 600 /tmp/private_key
    ssh -o StrictHostKeyChecking=no -i /tmp/private_key ${SSH_USERNAME}@${SSH_HOST} "${DEPLOY_COMMANDS}"
</span>  <span class="hljs-attr">shell:</span> <span class="hljs-string">bash</span>
</code></pre>
<p>Finally, this step connects to a remote server via SSH and runs the deployment commands specified in the GitHub secret <code>DEPLOY_COMMANDS</code>. This helps automate the release process.</p>
<p>Below is an image of the complete GitHub Actions script:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731247537316/dda0c2cb-b7c3-461e-8884-b020f7a495ac.png" alt="Image description" /></p>
<ol start="3">
<li>What We Have Accomplished by Running This Script</li>
</ol>
<p>By running this GitHub Actions workflow, we have:</p>
<ul>
<li>Automated the process of checking out code and setting up Docker on a GitHub-hosted runner.</li>
<li>Built a Docker image from the code and tagged it with both a version and latest.</li>
<li>Pushed the Docker image to a self-hosted Harbor registry.</li>
<li>Deployed the image to a remote server using secure SSH commands.</li>
</ul>
<p>This streamlines the CI/CD process, making development and deployment faster and more reliable.</p>
<ol start="4">
<li>Link to GitHub Gist</li>
</ol>
<p>For an easy reference and to adapt this workflow to your needs, you can find the complete script here on <a target="_blank" href="https://gist.github.com/abu-raihan-ddclbd/c9f68b562fa1b3b8e4c81d3234bb7d2a">GitHub Gist</a>.</p>
<p>Feel free to use this template as a starting point for automating your Docker workflows and deployment pipelines. With GitHub Actions, you can achieve seamless automation with just a few configuration steps!</p>
]]></content:encoded></item><item><title><![CDATA[Step-by-Step Guide to Setting Up Jenkins on Docker with Docker Agent-Based Builds]]></title><description><![CDATA[Part 1: Introduction to Docker and Jenkins, Setting Up Jenkins on Docker

Introduction to Docker and Jenkins
Hello there! If you're stepping into the world of DevOps or are a Senior Software Engineer looking to dip your toes into automation, this sec...]]></description><link>https://blog.mdaburaihan.pro/step-by-step-guide-to-setting-up-jenkins-on-docker-with-docker-agent-based-builds</link><guid isPermaLink="true">https://blog.mdaburaihan.pro/step-by-step-guide-to-setting-up-jenkins-on-docker-with-docker-agent-based-builds</guid><dc:creator><![CDATA[Md. Abu Raihan Srabon]]></dc:creator><pubDate>Mon, 15 Jan 2024 13:07:47 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1730105155585/54e19450-232a-4f00-8d18-4097bcb5792b.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-part-1-introduction-to-docker-and-jenkins-setting-up-jenkins-on-docker">Part 1: Introduction to Docker and Jenkins, Setting Up Jenkins on Docker</h2>
<hr />
<h2 id="heading-introduction-to-docker-and-jenkins">Introduction to Docker and Jenkins</h2>
<p>Hello there! If you're stepping into the world of DevOps or are a Senior Software Engineer looking to dip your toes into automation, this section is a gentle introduction to two powerful tools: Docker and Jenkins.</p>
<p><strong>Docker - Simplifying Environments:</strong> Docker is a tool that uses containerization to make it easier for you to develop, deploy, and run applications. Think of it as a virtual box where everything your application needs to run (code, runtime, system tools) is packaged together. This means no more 'it works on my machine' issues, as Docker ensures consistency across environments.</p>
<p><strong>Jenkins - Automating the Boring Stuff:</strong> Jenkins is like a helpful robot for software teams. It automates parts of the software development process, particularly those repetitive tasks like building, testing, and deploying code. With Jenkins, you can focus more on writing great code and less on the process of getting that code into production.</p>
<p><strong>Why Are We Talking About Both?</strong> Combining Docker and Jenkins can significantly streamline your development workflow. Docker provides a consistent environment for Jenkins to operate in, making your CI/CD pipelines more efficient and less prone to environment-related issues.</p>
<blockquote>
<p>Remember, everyone starts somewhere, and questions are a sign of a great learner. Whether you're a beginner in DevOps or an experienced engineer new to automation, this guide aims to make your journey into Docker and Jenkins as smooth as possible. Let's get started and unlock the potential of these tools together!</p>
</blockquote>
<h3 id="heading-installing-docker-and-jenkins">Installing Docker and Jenkins</h3>
<p>In this section, we'll cover the basic steps for installing Docker and setting up Jenkins using a Dockerfile and docker-compose.yml. This setup ensures a smooth and consistent environment for your Jenkins instance.</p>
<p>Installing Docker:</p>
<ul>
<li><p>Download Docker:</p>
<ul>
<li>For Windows and Mac: Download Docker Desktop from the <a target="_blank" href="https://www.docker.com/products/docker-desktop/">official Docker website</a>.</li>
<li>For Linux: Follow the instructions specific to your Linux distribution on the <a target="_blank" href="https://docs.docker.com/engine/install/">Docker installation guide</a>.</li>
</ul>
</li>
<li>Install Docker:</li>
</ul>
<p>Follow the installation guide for your operating system on the Docker website. This typically involves running an installer or executing a few commands in the terminal.
Verify Installation:</p>
<p>Open a terminal or command prompt and run <code>docker --version</code> to ensure Docker was installed successfully.</p>
<pre><code># docker --version
Docker version <span class="hljs-number">24.0</span><span class="hljs-number">.7</span>, build afdd53b
</code></pre><h3 id="heading-setting-up-jenkins-in-docker">Setting Up Jenkins in Docker:</h3>
<p>For Jenkins, we will use a custom Dockerfile and docker-compose.yml to create a Docker image with Jenkins installed. Here's a step-by-step guide:</p>
<ul>
<li>Prepare the Dockerfile:</li>
</ul>
<pre><code># Jenkins JDK <span class="hljs-number">17</span>, JDK <span class="hljs-number">11</span> is being deprecated
FROM jenkins/jenkins:latest-jdk17

USER root

RUN apt-get update &amp;&amp; apt-get install -y lsb-release

RUN curl -fsSLo /usr/share/keyrings/docker-archive-keyring.asc \
  <span class="hljs-attr">https</span>:<span class="hljs-comment">//download.docker.com/linux/debian/gpg</span>

RUN echo <span class="hljs-string">"deb [arch=$(dpkg --print-architecture) \
  signed-by=/usr/share/keyrings/docker-archive-keyring.asc] \
  https://download.docker.com/linux/debian \
  $(lsb_release -cs) stable"</span> &gt; <span class="hljs-regexp">/etc/</span>apt/sources.list.d/docker.list

RUN apt-get update &amp;&amp; apt-get install -y docker-ce-cli

RUN apt update &amp;&amp; apt install tzdata -y

ENV TZ=<span class="hljs-string">"Asia/Dhaka"</span>

USER jenkins
</code></pre><p>The provided <code>Dockerfile</code> sets up Jenkins with JDK 17 and installs Docker inside the Jenkins container. This setup allows Jenkins to run Docker commands, which is crucial for Docker Agent-based builds.</p>
<h3 id="heading-understanding-the-dockerfile">Understanding the Dockerfile:</h3>
<ul>
<li>The Dockerfile begins with the latest Jenkins image with JDK 17.</li>
<li>It installs the necessary packages and Docker CLI inside the container.</li>
<li>The timezone is set to 'Asia/Dhaka', which you can adjust as per your requirement.</li>
</ul>
<h3 id="heading-setting-up-docker-compose">Setting Up docker-compose:</h3>
<pre><code>version: <span class="hljs-string">'3.8'</span>
<span class="hljs-attr">services</span>:
  jenkins:
    build: 
      context: .
      dockerfile: .docker/Jenkins/Dockerfile
    <span class="hljs-attr">image</span>: jenkins-jdk<span class="hljs-number">-17</span>
    <span class="hljs-attr">container_name</span>: jenkins-jdk<span class="hljs-number">-17</span>
    <span class="hljs-attr">privileged</span>: <span class="hljs-literal">true</span>
    <span class="hljs-attr">user</span>: root
    <span class="hljs-attr">restart</span>: always
    <span class="hljs-attr">ports</span>:
      - <span class="hljs-number">8080</span>:<span class="hljs-number">8080</span>
      - <span class="hljs-number">50000</span>:<span class="hljs-number">50000</span>
    <span class="hljs-attr">volumes</span>:
      - jenkins_home:<span class="hljs-regexp">/var/</span>jenkins_home
      - <span class="hljs-regexp">/var/</span>run/docker.sock:<span class="hljs-regexp">/var/</span>run/docker.sock
      - <span class="hljs-regexp">/usr/</span>bin/docker:<span class="hljs-regexp">/usr/</span>bin/docker

<span class="hljs-attr">volumes</span>:
  jenkins_home:
    name: jenkins_home
</code></pre><ul>
<li>The provided <code>docker-compose.yml</code> file defines the Jenkins service, using the image built from our Dockerfile.</li>
<li>It sets the container to run in privileged mode with root user, ensuring that Docker commands can be executed within Jenkins.</li>
<li>Ports 8080 and 50000 are exposed for Jenkins web UI and agent connections.</li>
<li>Volumes are used for persisting Jenkins data and for Docker socket binding, allowing Jenkins to control Docker on the host.</li>
</ul>
<h3 id="heading-building-and-running-jenkins-container">Building and Running Jenkins Container:</h3>
<ul>
<li>Navigate to the directory containing your Dockerfile and docker-compose.yml.</li>
<li>Run docker-compose build to build your Jenkins image.</li>
<li>Once the build is complete, run docker-compose up to start Jenkins.</li>
<li>Jenkins should now be accessible at http://localhost:8080.</li>
</ul>
<h3 id="heading-accessing-jenkins">Accessing Jenkins:</h3>
<ul>
<li>On your browser, go to <code>http://localhost:8080</code> to access the Jenkins web UI.</li>
</ul>
%[INVALID_URL]<ul>
<li>Follow the initial setup wizard to configure Jenkins. You will need the initial admin password, which can be found in the Jenkins console logs or inside your Jenkins container at /var/jenkins_home/secrets/initialAdminPassword.</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1730105145293/3ab1a62d-786c-49f6-9520-d7182ba1ddec.png" alt="Image description" /> Pic: collect initial admin password from console.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1730105146749/b8e139dd-db50-4d0f-af49-f71055da50b0.png" alt="Image description" /> Pic: Jenkins UI for initial admin password</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1730105148505/563e5971-dce7-4d81-992a-86e6f9ea1c5d.png" alt="Image description" /> Pic: Plugins Selection page (we will move forward with defaults).</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1730105150303/608f51f8-a9ce-417c-80f5-e5e0a15c9d85.png" alt="Image description" /> Pic: Default plugins are being installed.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1730105151657/5eeb5e0e-6212-49ce-9487-3607a287616c.png" alt="Image description" /> Pic: Setup Jenkins URL (This URL will be used to configure projects)</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1730105153143/fee80a38-ad39-4ee2-8939-6e8a7b9616f2.png" alt="Image description" /> Pic: admin user setup.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1730105154467/2c86547b-c707-477a-90d5-9efdd50af119.png" alt="Image description" /> Pic: Jenkins Home page.</p>
<h3 id="heading-additional-resources">Additional Resources:</h3>
<ul>
<li>For a more detailed Docker installation guide, visit the <a target="_blank" href="https://docs.docker.com/engine/install/">Docker documentation</a>.</li>
<li>To understand more about Jenkins and Docker, explore the <a target="_blank" href="https://www.jenkins.io/doc/book/installing/docker/">official Jenkins documentation</a>.</li>
</ul>
<h3 id="heading-github-repository">GitHub Repository:</h3>
<p>For the complete Dockerfile, docker-compose.yml, and additional configuration files, you can visit the GitHub repository: https://github.com/aburaihan-dev/jenkins-in-docker. This repository contains all the necessary files and instructions to get your Jenkins on Docker up and running.</p>
]]></content:encoded></item></channel></rss>