<?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: Berk</title>
    <description>The latest articles on DEV Community by Berk (@berk).</description>
    <link>https://dev.to/berk</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%2F995825%2Fe3ae8ac8-918c-42c2-baa2-615f01ec715b.jpg</url>
      <title>DEV Community: Berk</title>
      <link>https://dev.to/berk</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/berk"/>
    <language>en</language>
    <item>
      <title>Split-Horizon DNS on AdGuard: One Domain, Two Networks, Two IP Addresses</title>
      <dc:creator>Berk</dc:creator>
      <pubDate>Sat, 19 Apr 2025 23:47:29 +0000</pubDate>
      <link>https://dev.to/berk/split-horizon-dns-on-adguard-one-domain-two-networks-two-ip-addresses-48n8</link>
      <guid>https://dev.to/berk/split-horizon-dns-on-adguard-one-domain-two-networks-two-ip-addresses-48n8</guid>
      <description>&lt;h2&gt;
  
  
  Split-Horizon DNS with AdGuard Home
&lt;/h2&gt;

&lt;p&gt;Let’s say you self-host an app on your home network. Your server’s local IP is &lt;code&gt;192.168.1.200&lt;/code&gt;, so you set &lt;code&gt;app.example.com&lt;/code&gt; to point to that. Everything works fine—until you want to access it from outside your home.&lt;/p&gt;

&lt;p&gt;You set up a VPN (like Tailscale, WireGuard, or OpenVPN) so your clients and server can talk securely. The server now also has a VPN IP, like &lt;code&gt;100.64.50.50&lt;/code&gt;. You configure your devices to use your home AdGuard DNS over VPN.&lt;/p&gt;

&lt;p&gt;But here’s the problem: when you try to reach &lt;code&gt;app.example.com&lt;/code&gt; over VPN, it still resolves to &lt;code&gt;192.168.1.200&lt;/code&gt;—a local IP that doesn’t work outside the LAN. So, you switch the DNS to return &lt;code&gt;100.64.50.50&lt;/code&gt; instead.&lt;/p&gt;

&lt;p&gt;Great—VPN clients can now connect. But now what about your devices at home? Do they also need to connect through VPN all the time? Do you really want encrypted VPN traffic on your local LAN? Should you run two separate DNS servers and sync them?&lt;/p&gt;

&lt;p&gt;There’s a simpler way using &lt;strong&gt;split-horizon DNS&lt;/strong&gt; with &lt;strong&gt;AdGuard Home&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  What’s Split-Horizon DNS?
&lt;/h3&gt;

&lt;p&gt;It’s when your DNS server returns different IP addresses depending on where the request comes from. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you're on VPN → return VPN IP (&lt;code&gt;100.64.50.50&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;If you're on home LAN → return local IP (&lt;code&gt;192.168.1.200&lt;/code&gt;)
### How to Set It Up in AdGuard Home&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Log in to your AdGuard Home dashboard.&lt;/li&gt;
&lt;li&gt;Go to &lt;strong&gt;Filters → Custom Filtering Rules&lt;/strong&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%2F97u7ja89ompswpgxt6hk.webp" alt="AdGuard Dashboard" width="800" height="476"&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add these two rules:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;||&lt;/span&gt;split.example.com^&lt;span class="nv"&gt;$dnsrewrite&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;NOERROR&lt;span class="p"&gt;;&lt;/span&gt;A&lt;span class="p"&gt;;&lt;/span&gt;100.64.50.50,client&lt;span class="o"&gt;=&lt;/span&gt;100.0.0.0/8
&lt;span class="o"&gt;||&lt;/span&gt;split.example.com^&lt;span class="nv"&gt;$dnsrewrite&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;NOERROR&lt;span class="p"&gt;;&lt;/span&gt;A&lt;span class="p"&gt;;&lt;/span&gt;192.168.1.200,client&lt;span class="o"&gt;=&lt;/span&gt;192.168.1.0/24
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;The first rule responds with the VPN IP if the query comes from the Tailscale subnet (&lt;code&gt;100.0.0.0/8&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;The second rule responds with the local IP for devices on your home network (&lt;code&gt;192.168.1.0/24&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;📝 &lt;strong&gt;Note:&lt;/strong&gt; These rules are just an example for testing!&lt;br&gt;&lt;br&gt;
Be sure to replace &lt;code&gt;split.example.com&lt;/code&gt; with your actual domain name,&lt;br&gt;&lt;br&gt;
&lt;code&gt;100.64.50.50&lt;/code&gt; with your server’s VPN IP,&lt;br&gt;&lt;br&gt;
and &lt;code&gt;192.168.1.200&lt;/code&gt; with your server’s local IP.&lt;/p&gt;
&lt;h3&gt;
  
  
  Testing
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;From home network:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nslookup split.example.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Server: 192.168.1.235
Address: 192.168.1.235#53

Non-authoritative answer:
Name: split.example.com
Address: 192.168.1.200
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;From VPN:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nslookup split.example.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Server: 100.100.100.100
Address: 100.100.100.100#53

Non-authoritative answer:
Name: split.example.com
Address: 100.64.50.50
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Result
&lt;/h3&gt;

&lt;p&gt;Now you’ve got one domain, one DNS server, and two responses—depending on where the request comes from. It’s a clean and easy solution for accessing your app from both home and VPN.&lt;/p&gt;

&lt;p&gt;Achievements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One domain name for all environments&lt;/li&gt;
&lt;li&gt;No need to run multiple DNS servers&lt;/li&gt;
&lt;li&gt;Easy to manage and update from the AdGuard Home dashboard&lt;/li&gt;
&lt;li&gt;Works great with VPNs like Tailscale, WireGuard, or OpenVPN&lt;/li&gt;
&lt;li&gt;No need to keep VPN enabled all the time&lt;/li&gt;
&lt;li&gt;Devices without VPN can still connect on the home network&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>adguard</category>
      <category>splithorizon</category>
      <category>vpn</category>
    </item>
    <item>
      <title>Fixing Unknown SMART Status for External SSD/HDD on Proxmox</title>
      <dc:creator>Berk</dc:creator>
      <pubDate>Sun, 30 Mar 2025 13:52:14 +0000</pubDate>
      <link>https://dev.to/berk/fixing-unknown-smart-status-for-external-ssdhdd-on-proxmox-4gmn</link>
      <guid>https://dev.to/berk/fixing-unknown-smart-status-for-external-ssdhdd-on-proxmox-4gmn</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;If you are using an External SSD/Harddisk and the Proxmox can't detect the SMART status, this post &lt;strong&gt;might&lt;/strong&gt; help you.&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%2Fcdn.jsdelivr.net%2Fgh%2Fburakberkkeskin%2Fblog-cdn%2Ffixing-unknown-smart-proxmox%2Fmain.webp" 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%2Fcdn.jsdelivr.net%2Fgh%2Fburakberkkeskin%2Fblog-cdn%2Ffixing-unknown-smart-proxmox%2Fmain.webp" alt="Before After" width="800" height="316"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In a previous blog, I showed how to use &lt;code&gt;smartctl&lt;/code&gt; tool with external SSDs/Harddisks. The problem with in previous blog post was that &lt;code&gt;smartctl&lt;/code&gt; was not automatically detecting my external SSD controller and the SMART query command failed. The fix is very easy. You should detect the controller chip and tell &lt;code&gt;smartctl&lt;/code&gt; with &lt;code&gt;-d&lt;/code&gt; flag. For more details, you can head to the &lt;a href="https://burakberk.dev/smart-monitoring-for-external-ssds-hdds-the-smartmontools-guide/" rel="noopener noreferrer"&gt;previous blog post&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;TDLR: &lt;/p&gt;

&lt;p&gt;Problem was default command can't detect the device type:&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="nv"&gt;$ &lt;/span&gt;smartctl &lt;span class="nt"&gt;-i&lt;/span&gt; /dev/sdb

/dev/sdb: Unknown USB bridge &lt;span class="o"&gt;[&lt;/span&gt;0x0bda:0x0bda &lt;span class="o"&gt;(&lt;/span&gt;0x2001&lt;span class="o"&gt;)]&lt;/span&gt;
Please specify device &lt;span class="nb"&gt;type &lt;/span&gt;with the &lt;span class="nt"&gt;-d&lt;/span&gt; option.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fixed with specifying the correct device type:&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="nv"&gt;$ &lt;/span&gt;smartctl &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; sntrealtek /dev/sdb

&lt;span class="o"&gt;===&lt;/span&gt; START OF INFORMATION SECTION &lt;span class="o"&gt;===&lt;/span&gt;
Model Number:                       KBG50ZNV256G KIOXIA
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;If you can't query your SSD's SMART values with the default command, Proxmox can't too. In this blog, we will wrap the &lt;code&gt;smartctl&lt;/code&gt; so Proxmox won't have problem while querying the SMART status of my external SSD.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First, login to the Proxmox host server.

&lt;ul&gt;
&lt;li&gt;I am using the &lt;code&gt;root&lt;/code&gt; account directly.&lt;/li&gt;
&lt;li&gt;If you are not using &lt;code&gt;root&lt;/code&gt;, please add &lt;code&gt;sudo&lt;/code&gt; to beginning of the commands below.&lt;/li&gt;
&lt;li&gt;Note that you need &lt;code&gt;sudo&lt;/code&gt; privileges for this solution.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Create a bash script somewhere in your server.
&lt;/li&gt;

&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vim ~/smartctl.external
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Copy and paste the script below to the file.

&lt;ul&gt;
&lt;li&gt;What this script basically do is adding &lt;code&gt;-d sntrealtek&lt;/code&gt; flag if the queried device is &lt;code&gt;/dev/sdb&lt;/code&gt;. It doesn't do anything to another devices or flags.&lt;/li&gt;
&lt;li&gt;⚠️ Please change the &lt;code&gt;/dev/sdb&lt;/code&gt; and &lt;code&gt;-d sntrealtek&lt;/code&gt; according to your requirements.
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/usr/bin/env bash&lt;/span&gt;

&lt;span class="nv"&gt;SMARTCTL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/usr/sbin/smartctl.orig
&lt;span class="nv"&gt;OPTIONS&lt;/span&gt;&lt;span class="o"&gt;=(&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$@&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;i&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1&lt;span class="p"&gt;;&lt;/span&gt; i&amp;lt;&lt;span class="nv"&gt;$#;&lt;/span&gt; ++i&lt;span class="o"&gt;))&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="c"&gt;# Check for /dev/sdb and add the Realtek option&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;OPTIONS&lt;/span&gt;&lt;span class="p"&gt;[i]&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"/dev/sdb"&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nv"&gt;realtek_option&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"-d sntrealtek"&lt;/span&gt;
        &lt;span class="c"&gt;# Add the "-d sntrealtek" option to the list of options&lt;/span&gt;
        &lt;span class="nv"&gt;OPTIONS&lt;/span&gt;&lt;span class="o"&gt;=(&lt;/span&gt;&lt;span class="nv"&gt;$realtek_option&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;OPTIONS&lt;/span&gt;&lt;span class="p"&gt;[@]&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;fi
done

&lt;/span&gt;&lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nv"&gt;$SMARTCTL&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;OPTIONS&lt;/span&gt;&lt;span class="p"&gt;[@]&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Now rename the original &lt;code&gt;smartctl&lt;/code&gt; tool.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cp&lt;/span&gt; /usr/sbin/smartctl /usr/sbin/smartctl.orig
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Replace the wrapper script with the original &lt;code&gt;smartctl&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cp&lt;/span&gt; ~/smartctl.external /usr/sbin/smartctl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Set the permissions of the wrapper script.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;chmod &lt;/span&gt;755 /usr/sbin/smartctl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;(Optional) Change the attribute of the wrapper script so it won't be changed by updates or by mistake.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;chattr +i /usr/sbin/smartctl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Now make sure that the default command returns the SMART values:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;smartctl &lt;span class="nt"&gt;-i&lt;/span&gt; /dev/sdb

&lt;span class="o"&gt;===&lt;/span&gt; START OF INFORMATION SECTION &lt;span class="o"&gt;===&lt;/span&gt;
Model Number:                       KBG50ZNV256G KIOXIA
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Return to the Proxmox and click on the &lt;code&gt;reload&lt;/code&gt; on the Disks page to reload the SMART values.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;UNKNOWN&lt;/code&gt; status should be &lt;code&gt;PASSED&lt;/code&gt; now.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.jsdelivr.net%2Fgh%2Fburakberkkeskin%2Fblog-cdn%2Ffixing-unknown-smart-proxmox%2Ffixed-passed.webp" alt="Fixed" width="800" height="160"&gt;
&lt;/li&gt;
&lt;li&gt;You can also view the full SMART details.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.jsdelivr.net%2Fgh%2Fburakberkkeskin%2Fblog-cdn%2Ffixing-unknown-smart-proxmox%2Fsmartctl.webp" alt="Full SMART Details" width="800" height="434"&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>proxmox</category>
      <category>smart</category>
      <category>ssd</category>
      <category>unknown</category>
    </item>
    <item>
      <title>Enabling Secure Boot with Linux and Windows Dual-Boot Setup</title>
      <dc:creator>Berk</dc:creator>
      <pubDate>Mon, 10 Feb 2025 21:57:27 +0000</pubDate>
      <link>https://dev.to/berk/complete-guide-enabling-secure-boot-with-linux-and-windows-dual-boot-setup-24o8</link>
      <guid>https://dev.to/berk/complete-guide-enabling-secure-boot-with-linux-and-windows-dual-boot-setup-24o8</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;This comprehensive guide demonstrates how to enable Secure Boot on a dual-boot system running both Linux and Windows. While maintaining the ability to boot into both operating systems, this setup ensures UEFI Secure Boot verification for enhanced system security.&lt;/p&gt;

&lt;p&gt;Although demonstrated using Arch Linux and a Gigabyte motherboard, these procedures are applicable across most Linux distributions and motherboard manufacturers with minor variations in UEFI interface layouts.&lt;/p&gt;

&lt;p&gt;This guide was specifically created to enable Secure Boot for applications requiring stringent security measures, such as FACEIT Anti-Cheat (used in Counter-Strike), while preserving full Linux functionality. Many modern gaming anti-cheat systems and enterprise applications mandate Secure Boot for enhanced security.&lt;/p&gt;

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

&lt;p&gt;Before modifying your UEFI firmware settings, complete these essential preparation steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Backup Your UEFI (BIOS) Configuration&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The procedure requires clearing existing and generating new Secure Boot keys&lt;/li&gt;
&lt;li&gt;While most modern motherboards provide options to restore factory Secure Boot keys, this capability varies by manufacturer&lt;/li&gt;
&lt;li&gt;Document all current UEFI settings thoroughly, especially boot sequence and security options&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Locate Essential UEFI Settings&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Navigate through your motherboard's UEFI interface to familiarize yourself with its layout&lt;/li&gt;
&lt;li&gt;Identify these critical security settings:

&lt;ul&gt;
&lt;li&gt;Secure Boot activation toggle&lt;/li&gt;
&lt;li&gt;Secure Boot key management interface (for key deletion and restoration)
&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%2Folco0vqg6bftkg4ees82.png" alt="Gigabyte Motherboard Secure Boot Location" width="800" height="427"&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Step-by-Step Implementation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Disable Secure Boot
&lt;/h3&gt;

&lt;p&gt;Initially, disable Secure Boot in your UEFI settings. This step is necessary because Linux cannot boot with the default Secure Boot keys, and we need to establish our own custom keys.&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%2Fc1lj2niyqbjep353vzaw.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%2Fc1lj2niyqbjep353vzaw.png" alt="Disable secure boot." width="800" height="439"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  2. Delete Secure Boot Keys
&lt;/h3&gt;

&lt;p&gt;Navigate through your UEFI settings to prepare for custom key enrollment:&lt;/p&gt;

&lt;p&gt;First, switch to "Custom" secure boot mode. This enables granular control over Secure Boot keys.&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%2Faammm9kudvkk61y1ahy7.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%2Faammm9kudvkk61y1ahy7.png" alt="Switch to the custom secure boot mode." width="800" height="434"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, remove all existing Secure Boot keys to prepare for custom key enrollment. This step places the system in Setup Mode.&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%2Fxavsjohksx81dzxhrd58.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%2Fxavsjohksx81dzxhrd58.png" alt="Delete default secure boot keys." width="800" height="432"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Verify the keys have been deleted and boot into Linux. The system should now be in Setup Mode.&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%2Fwwfv9birnhhqodfjncme.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%2Fwwfv9birnhhqodfjncme.png" alt="Verify to delete default secure boot keys." width="800" height="429"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  3. Install and Configure &lt;code&gt;sbctl&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Install &lt;code&gt;sbctl&lt;/code&gt;, the Secure Boot key management utility. For installation instructions specific to your distribution, consult the official &lt;a href="https://github.com/Foxboron/sbctl/blob/master/README.md#available-packages" rel="noopener noreferrer"&gt;README file&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For Arch Linux users:&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;sudo &lt;/span&gt;pacman &lt;span class="nt"&gt;-S&lt;/span&gt; sbctl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Check Status
&lt;/h3&gt;

&lt;p&gt;Verify the current Secure Boot configuration:&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;sudo &lt;/span&gt;sbctl status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output indicating proper setup mode:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Installed:  ✘ Sbctl is not installed
Owner GUID: bbbfcaf8-3102-47f9-a921-2e5245da7e9f
Setup Mode: ✗ Enabled
Secure Boot:    ✗ Disabled
Vendor Keys:    none
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. Generate and Enroll Keys
&lt;/h3&gt;

&lt;p&gt;Generate a new set of custom Secure Boot keys:&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;sudo &lt;/span&gt;sbctl create-keys
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Upon successful key creation, you'll see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Created Owner UUID a9fbbdb7-a05f-48d5-b63a-08c5df45ee70
Creating secure boot keys...✔
Secure boot keys created!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Enroll both your custom keys and Microsoft's keys (required for Windows boot compatibility):&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;sudo &lt;/span&gt;sbctl enroll-keys &lt;span class="nt"&gt;--microsoft&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Successful enrollment confirmation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Enrolling keys to EFI variables...
With vendor keys from microsoft...✓ 
Enrolled keys to the EFI variables!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6. Configure GRUB Bootloader
&lt;/h3&gt;

&lt;p&gt;Install GRUB with TPM support and security modules enabled:&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;sudo &lt;/span&gt;grub-install &lt;span class="nt"&gt;--target&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;x86_64-efi &lt;span class="nt"&gt;--efi-directory&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/boot &lt;span class="nt"&gt;--bootloader-id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;GRUB &lt;span class="nt"&gt;--modules&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"tpm"&lt;/span&gt; &lt;span class="nt"&gt;--disable-shim-lock&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  7. Sign Boot Files
&lt;/h3&gt;

&lt;p&gt;First, check for unsigned boot 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;sudo &lt;/span&gt;sbctl verify
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The system will identify unsigned files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Verifying file database and EFI images in /boot...
✗ /boot/EFI/BOOT/BOOTX64.EFI is not signed
✗ /boot/EFI/GRUB/grubx64.efi is not signed
✗ /boot/grub/x86_64-efi/core.efi is not signed
✗ /boot/grub/x86_64-efi/grub.efi is not signed
✗ /boot/vmlinuz-linux is not signed
✗ /boot/vmlinuz-linux-lts is not signed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sign all boot files with your custom keys:&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;sudo &lt;/span&gt;sbctl sign-all
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Successful signing confirmation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;✓ Signed /boot/EFI/BOOT/BOOTX64.EFI
✓ Signed /boot/EFI/GRUB/grubx64.efi
✓ Signed /boot/grub/x86_64-efi/core.efi
✓ Signed /boot/grub/x86_64-efi/grub.efi
✓ Signed /boot/vmlinuz-linux
✓ Signed /boot/vmlinuz-linux-lts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify all files are now properly signed:&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;sudo &lt;/span&gt;sbctl verify
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected verification output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Verifying file database and EFI images in /boot...
✓ /boot/EFI/BOOT/BOOTX64.EFI is signed
✓ /boot/EFI/GRUB/grubx64.efi is signed
✓ /boot/grub/x86_64-efi/core.efi is signed
✓ /boot/grub/x86_64-efi/grub.efi is signed
✓ /boot/vmlinuz-linux is signed
✓ /boot/vmlinuz-linux-lts is signed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  8. Enable Secure Boot
&lt;/h3&gt;

&lt;p&gt;Return to UEFI settings to activate Secure Boot with your new keys:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Reboot and enter UEFI settings&lt;/li&gt;
&lt;li&gt;Navigate to Secure Boot configuration&lt;/li&gt;
&lt;li&gt;Enable Secure Boot&lt;/li&gt;
&lt;li&gt;Save changes and exit
&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%2Fwj6wq4sg3l0060jo1dn7.png" alt="Enable secure boot." width="800" height="427"&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  9. Verify Configuration
&lt;/h3&gt;

&lt;p&gt;After booting into Linux, confirm Secure Boot is properly enabled:&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;sudo &lt;/span&gt;sbctl status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected configuration status:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Installed:  ✓ sbctl is installed
Owner GUID: bbbfcaf8-3102-47f9-a921-2e5245da7e9f
Setup Mode: ✓ Disabled
Secure Boot:    ✓ Enabled
Vendor Keys:    microsoft
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Troubleshooting Guide
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Common Issues and Solutions
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Boot Failures&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If boot fails, temporarily disable Secure Boot through UEFI settings&lt;/li&gt;
&lt;li&gt;Boot into Linux and verify all boot files are correctly signed&lt;/li&gt;
&lt;li&gt;If problems persist, consider regenerating and re-enrolling keys&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Windows Boot Problems&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Verify Microsoft keys were properly enrolled using the &lt;code&gt;--microsoft&lt;/code&gt; flag&lt;/li&gt;
&lt;li&gt;Ensure Windows Boot Manager maintains proper signatures&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Key Management Issues&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For corrupted keys, use UEFI options to restore factory Secure Boot keys&lt;/li&gt;
&lt;li&gt;Repeat the key generation and enrollment process from the beginning
&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%2F4j4dgzd2fln2ccluy4vh.png" alt="Restore factory secure boot keys." width="800" height="425"&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Maintenance Notes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Sign new kernel images after system updates: &lt;code&gt;sudo sbctl sign-all&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Monitor Secure Boot status regularly, especially following system updates&lt;/li&gt;
&lt;li&gt;Store custom key backups securely in a separate location&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Security Considerations
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Custom Secure Boot keys enhance security only when properly managed&lt;/li&gt;
&lt;li&gt;Implement a strong UEFI administrator password&lt;/li&gt;
&lt;li&gt;Consider enabling TPM for additional hardware-based security features&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>linux</category>
      <category>secureboot</category>
      <category>grub</category>
      <category>dualboot</category>
    </item>
    <item>
      <title>How to Add Domains and IP Addresses to Docker Containers</title>
      <dc:creator>Berk</dc:creator>
      <pubDate>Sat, 19 Oct 2024 14:52:57 +0000</pubDate>
      <link>https://dev.to/berk/how-to-add-domains-and-ip-addresses-to-docker-containers-h9p</link>
      <guid>https://dev.to/berk/how-to-add-domains-and-ip-addresses-to-docker-containers-h9p</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;Docker users often face challenges with custom domain and IP address mappings in their containers. The inability of containers to read the host machine's &lt;code&gt;/etc/hosts&lt;/code&gt; file creates significant obstacles.&lt;/p&gt;

&lt;p&gt;In this practical guide, we'll tackle this common Docker networking challenge: how to make containers resolve custom domains and IP addresses without modifying each container individually.&lt;/p&gt;

&lt;p&gt;We'll cover two methods: integrating &lt;code&gt;dnsmasq&lt;/code&gt; with NetworkManager and configuring &lt;code&gt;dnsmasq&lt;/code&gt; without NetworkManager. By the end of this post, you'll be able to easily manage custom domain resolutions in your containers.&lt;/p&gt;

&lt;p&gt;By the end of this post, you'll be able to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Easily add custom domain resolutions to all your Docker containers&lt;/li&gt;
&lt;li&gt;Streamline your development and testing workflows&lt;/li&gt;
&lt;li&gt;Avoid the headache of managing &lt;code&gt;/etc/hosts&lt;/code&gt; files for each container&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Install Dnsmasq&lt;/li&gt;
&lt;li&gt;
Configure Dnsmasq

&lt;ol&gt;
&lt;li&gt;Dnsmasq Standalone Usage&lt;/li&gt;
&lt;li&gt;Dnsmasq with NetworkManager&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;li&gt;Configure Docker&lt;/li&gt;

&lt;li&gt;Add Test Domain Names to &lt;code&gt;/etc/hosts&lt;/code&gt;
&lt;/li&gt;

&lt;li&gt;Test the Custom Domain Names&lt;/li&gt;

&lt;/ol&gt;

&lt;h2&gt;
  
  
  Install Dnsmasq
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Make sure &lt;code&gt;dnsmasq&lt;/code&gt; is installed.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;which dnsmasq
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;If not installed, install it
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# For Debian / Ubuntu&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;dnsmasq

&lt;span class="c"&gt;# For RHEL / CentOS / Fedora&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;dnf &lt;span class="nb"&gt;install &lt;/span&gt;dnsmasq
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Configure Dnsmasq
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Dnsmasq Standalone Usage
&lt;/h3&gt;

&lt;p&gt;In this section, we'll configure &lt;code&gt;dnsmasq&lt;/code&gt; if you are not using NetworkManager.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a new configuration file for &lt;code&gt;dnsmasq&lt;/code&gt;:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;vim /etc/dnsmasq.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Add the following configuration options:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Listen on the Docker bridge interface&lt;/span&gt;
&lt;span class="nv"&gt;interface&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;docker0

&lt;span class="c"&gt;# Specify a default DNS server to forward queries&lt;/span&gt;
&lt;span class="nv"&gt;server&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;8.8.8.8  &lt;span class="c"&gt;# Example: Google DNS&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Start the &lt;code&gt;dnsmasq&lt;/code&gt; service and enable it to run on boot:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl stop dnsmasq &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; &lt;span class="nt"&gt;--now&lt;/span&gt; dnsmasq &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl status dnsmasq
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Dnsmasq with NetworkManager
&lt;/h3&gt;

&lt;p&gt;If you are using NetworkManager, you can use &lt;code&gt;dnsmasq&lt;/code&gt; as its plugin.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open NetworkManager main configuration file with an text editor:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;vim /etc/NetworkManager/NetworkManager.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Find the &lt;code&gt;[main]&lt;/code&gt; section and add &lt;code&gt;dns=dnsmasq&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;main]
&lt;span class="nv"&gt;dns&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;dnsmasq
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Create &lt;code&gt;dnsmasq&lt;/code&gt; configuration file in the config daemon directory.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;vim /etc/NetworkManager/dnsmasq.d/split-dns.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Listen on the Docker bridge interface&lt;/span&gt;
&lt;span class="nv"&gt;interface&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;docker0

&lt;span class="c"&gt;# Specify a default DNS server to forward queries&lt;/span&gt;
&lt;span class="nv"&gt;server&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;8.8.8.8  &lt;span class="c"&gt;# Example: Google DNS&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Check if NetworkManager is running without no problem.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart NetworkManager &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nb"&gt;sleep &lt;/span&gt;5 &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl status NetworkManager
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;If there are problems, check the NetworkManager logs.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;journalctl &lt;span class="nt"&gt;-u&lt;/span&gt; NetworkManager &lt;span class="nt"&gt;-r&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Configure Docker
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Check the IP address of the &lt;code&gt;docker0&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ip a show docker0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;4: docker0: &amp;lt;NO-CARRIER,BROADCAST,MULTICAST,UP&amp;gt; mtu 1500 qdisc noqueue state DOWN group default
    link/ether 02:42:a9:72:e1:3a brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:a9ff:fe72:e13a/64 scope link
       valid_lft forever preferred_lft forever
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Configure Docker to use the &lt;code&gt;Dnsmasq&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;vim /etc/docker/daemon.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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;"dns"&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="s2"&gt;"172.17.0.1"&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;ul&gt;
&lt;li&gt;Restart the docker service
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart docker 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Add Test Domain Names to &lt;code&gt;/etc/hosts&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;For testing purposes, add a domain to &lt;code&gt;/etc/hosts&lt;/code&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;sudo &lt;/span&gt;bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"echo '192.168.1.12 nonexisting.example.com' &amp;gt;&amp;gt; /etc/hosts"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Restart the &lt;code&gt;dnsmasq&lt;/code&gt; service to get updates.&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;sudo &lt;/span&gt;systemctl restart dnsmasq
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Test the Custom Domain Names
&lt;/h2&gt;

&lt;p&gt;In the &lt;code&gt;/etc/hosts&lt;/code&gt; file, we defined &lt;code&gt;nonexisting.example.com&lt;/code&gt; as &lt;code&gt;192.168.1.10&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Lets test if the configuration works as expected.&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;--rm&lt;/span&gt; &lt;span class="nt"&gt;--name&lt;/span&gt; dns-test busybox nslookup nonexisting.example.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The output should be:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Server:     172.17.0.1
Address:    172.17.0.1:53

Non-authoritative answer:

Non-authoritative answer:
Name:   example.com
Address: 192.168.1.10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Viola, you can set any custom domain name in the &lt;code&gt;/etc/hosts&lt;/code&gt; file on the host machine and containers will use it by default.&lt;/p&gt;
&lt;h2&gt;
  
  
  For More
&lt;/h2&gt;

&lt;p&gt;If you like the post, you can head to my personal blog site and read more about DevOps, Linux, system engineering, and self-hosted applications for homelab!&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://burakberk.dev/" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fburakberk.dev%2Fcontent%2Fimages%2F2024%2F09%2Fwallpaperflare-cropped--1-.jpg" height="449" class="m-0" width="800"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://burakberk.dev/" rel="noopener noreferrer" class="c-link"&gt;
          Burak Berk Keskin
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          Blog of a DevOps &amp;amp; System Engineer
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fburakberk.dev%2Fcontent%2Fimages%2Fsize%2Fw256h256%2F2024%2F02%2Fwebsite-logo2.jpeg" width="60" height="60"&gt;
        burakberk.dev
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;



</description>
      <category>dnsamsq</category>
      <category>hosts</category>
      <category>domain</category>
      <category>docker</category>
    </item>
    <item>
      <title>Sonatype Nexus Usage 101 | Best Practices &amp; Example Use Cases</title>
      <dc:creator>Berk</dc:creator>
      <pubDate>Sun, 06 Oct 2024 20:26:39 +0000</pubDate>
      <link>https://dev.to/berk/sonatype-nexus-usage-101-5h82</link>
      <guid>https://dev.to/berk/sonatype-nexus-usage-101-5h82</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;In my &lt;a href="https://dev.to/berk/installing-sonatype-nexus-with-nginx-reverse-proxy-https-1cag"&gt;previous blog post&lt;/a&gt;, we embarked on a journey to set up Sonatype Nexus with an Nginx reverse proxy. We covered everything from the initial server preparation to accessing the Nexus Web UI securely via HTTPS. Now that you've got Nexus up and running, it's time to roll up our sleeves and dive into the nitty-gritty of using this powerful tool effectively.&lt;/p&gt;

&lt;h2&gt;
  
  
  Nexus Dashboard
&lt;/h2&gt;

&lt;p&gt;Upon logging into the Nexus web UI, you'll be greeted by a dashboard showcasing several pre-defined repositories.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fvj15c2uxw2bofwk85nx1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fvj15c2uxw2bofwk85nx1.png" alt="Predefined Repositories"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For those of us who prefer a clean slate and better organization, we're going to start by decluttering. We'll remove all the pre-defined repositories and the default blob storage. This approach allows us to create a more tailored setup, with dedicated repositories and blobs for each category we'll be working with.&lt;/p&gt;

&lt;p&gt;Let's begin by logging in with the &lt;code&gt;admin&lt;/code&gt; user and navigating to the administration section.&lt;/p&gt;

&lt;h3&gt;
  
  
  Clearing the Slate
&lt;/h3&gt;

&lt;p&gt;First, we'll tackle the repositories. One by one, we'll select each repository and hit that &lt;code&gt;Delete repository&lt;/code&gt; button.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.jsdelivr.net%2Fgh%2Fburakberkkeskin%2Fblog-cdn%2Fsonatype-nexus-101%2Fimages%2F1-delete-repository-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.jsdelivr.net%2Fgh%2Fburakberkkeskin%2Fblog-cdn%2Fsonatype-nexus-101%2Fimages%2F1-delete-repository-1.png" alt="Delete Predefined Repositories 1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hit Delete and confirm your choice.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.jsdelivr.net%2Fgh%2Fburakberkkeskin%2Fblog-cdn%2Fsonatype-nexus-101%2Fimages%2F2-delete-repository-2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.jsdelivr.net%2Fgh%2Fburakberkkeskin%2Fblog-cdn%2Fsonatype-nexus-101%2Fimages%2F2-delete-repository-2.png" alt="Delete Predefined Repositories 2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, we'll turn our attention to the default blob storage.&lt;/p&gt;

&lt;p&gt;Head over to the &lt;code&gt;Blob Stores&lt;/code&gt; section and locate the &lt;code&gt;default&lt;/code&gt; blob store.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fqv3w3o4rb5v76ealzxd9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fqv3w3o4rb5v76ealzxd9.png" alt="Delete Predefined Blob 1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hit &lt;code&gt;Delete&lt;/code&gt; and confirm your choice.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F7n4q3d2km0dpgx15cbqw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F7n4q3d2km0dpgx15cbqw.png" alt="Delete Predefined Blob 2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Building Our Custom Setup
&lt;/h3&gt;

&lt;p&gt;Now that we've cleared the decks, it's time to start building our custom setup. We'll create new blob stores, each dedicated to a specific type of repository. This approach allows for better organization and management of our assets.&lt;/p&gt;

&lt;p&gt;Let's start by creating a new blob store for our Maven repositories. Navigate to the administrator blob stores menu and click on &lt;code&gt;Create blob store&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.jsdelivr.net%2Fgh%2Fburakberkkeskin%2Fblog-cdn%2Fsonatype-nexus-101%2Fimages%2F5-create-blob-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.jsdelivr.net%2Fgh%2Fburakberkkeskin%2Fblog-cdn%2Fsonatype-nexus-101%2Fimages%2F5-create-blob-1.png" alt="Create new blobs"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select &lt;code&gt;File&lt;/code&gt; as the type and name it &lt;code&gt;maven&lt;/code&gt;. This will be our dedicated storage space for all things Maven.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.jsdelivr.net%2Fgh%2Fburakberkkeskin%2Fblog-cdn%2Fsonatype-nexus-101%2Fimages%2F6-create-blob-2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.jsdelivr.net%2Fgh%2Fburakberkkeskin%2Fblog-cdn%2Fsonatype-nexus-101%2Fimages%2F6-create-blob-2.png" alt="Predefined Repositories"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Repeat this process to create blob stores for other types of repositories you'll be working with. In our case, we'll set up separate stores for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Maven&lt;/li&gt;
&lt;li&gt;NPM&lt;/li&gt;
&lt;li&gt;Docker&lt;/li&gt;
&lt;li&gt;Yum&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By the end of this process, you'll have a clean, organized foundation for your Nexus setup.&lt;/p&gt;

&lt;h2&gt;
  
  
  Maven Repository
&lt;/h2&gt;

&lt;p&gt;Now that we've laid the groundwork, it's time to set up our Maven repositories. Maven is a staple in the Java ecosystem, and having a well-configured Maven repository in Nexus can significantly streamline your development process.&lt;/p&gt;

&lt;h3&gt;
  
  
  Maven Proxy Repository
&lt;/h3&gt;

&lt;p&gt;We're going to create two Maven proxy repositories. We'll set up one for the central Maven repository and another for the Google Maven repository.&lt;/p&gt;

&lt;p&gt;Let's start by navigating to the repositories administrator menu and clicking that inviting &lt;code&gt;Create repository&lt;/code&gt; button.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.jsdelivr.net%2Fgh%2Fburakberkkeskin%2Fblog-cdn%2Fsonatype-nexus-101%2Fimages%2F7-create-maven-repo-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.jsdelivr.net%2Fgh%2Fburakberkkeskin%2Fblog-cdn%2Fsonatype-nexus-101%2Fimages%2F7-create-maven-repo-1.png" alt="Create maven repositories 1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select &lt;code&gt;maven2 (proxy)&lt;/code&gt; from the list. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.jsdelivr.net%2Fgh%2Fburakberkkeskin%2Fblog-cdn%2Fsonatype-nexus-101%2Fimages%2F8-create-maven-repo-2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.jsdelivr.net%2Fgh%2Fburakberkkeskin%2Fblog-cdn%2Fsonatype-nexus-101%2Fimages%2F8-create-maven-repo-2.png" alt="create-maven-repo-2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, let's fill in the details for our central Maven repository:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Name: maven-central
Remote Storage: https://repo1.maven.org/maven2/
Blob Store: maven
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.jsdelivr.net%2Fgh%2Fburakberkkeskin%2Fblog-cdn%2Fsonatype-nexus-101%2Fimages%2F9-create-maven-repo-3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.jsdelivr.net%2Fgh%2Fburakberkkeskin%2Fblog-cdn%2Fsonatype-nexus-101%2Fimages%2F9-create-maven-repo-3.png" alt="create-maven-repo-3"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.jsdelivr.net%2Fgh%2Fburakberkkeskin%2Fblog-cdn%2Fsonatype-nexus-101%2Fimages%2F10-create-maven-repo-4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.jsdelivr.net%2Fgh%2Fburakberkkeskin%2Fblog-cdn%2Fsonatype-nexus-101%2Fimages%2F10-create-maven-repo-4.png" alt="create-maven-repo-4"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hit &lt;code&gt;Create&lt;/code&gt; to create the repository. &lt;/p&gt;

&lt;p&gt;Great! Now let's repeat this process for the Google Maven repository. Use these values:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Name: maven-google
Remote Storage: https://maven.google.com/
Blob Store: maven
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Maven Group Repository
&lt;/h3&gt;

&lt;p&gt;Now that we have our individual Maven proxy repositories set up, it's time to group them together. You can give clients the single URL of the group repository and manage the group repository on the Nexus side without having to change the repository URL. &lt;/p&gt;

&lt;p&gt;Head back to the repositories administrator menu and click &lt;code&gt;Create repository&lt;/code&gt;  again. This time, select &lt;code&gt;maven2 (group)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.jsdelivr.net%2Fgh%2Fburakberkkeskin%2Fblog-cdn%2Fsonatype-nexus-101%2Fimages%2F11-create-maven-group-repo-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.jsdelivr.net%2Fgh%2Fburakberkkeskin%2Fblog-cdn%2Fsonatype-nexus-101%2Fimages%2F11-create-maven-group-repo-1.png" alt="create-maven-group-repo-1."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select &lt;code&gt;maven2 (group)&lt;/code&gt;.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.jsdelivr.net%2Fgh%2Fburakberkkeskin%2Fblog-cdn%2Fsonatype-nexus-101%2Fimages%2F12-create-maven-group-repo-2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.jsdelivr.net%2Fgh%2Fburakberkkeskin%2Fblog-cdn%2Fsonatype-nexus-101%2Fimages%2F12-create-maven-group-repo-2.png" alt="create-maven-group-repo-2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's set it up with these details:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Name: maven
Blob: maven
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the group section, click on the previously created repositories and use the right arrow to move both repositories to the members column.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fgb3uq8csh2i0fnws6u69.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fgb3uq8csh2i0fnws6u69.png" alt="create-maven-group-repo-3"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hit that 'Create repository' button, and voila! Your Maven repository is ready to serve.&lt;/p&gt;

&lt;h3&gt;
  
  
  Raw Proxy for Gradle Zip File
&lt;/h3&gt;

&lt;p&gt;If you're planning to use this Maven repository for Android development, there's one more piece of the puzzle we need to address. The &lt;code&gt;gradlew&lt;/code&gt; tool needs to download the Gradle distribution zip file, and we want to ensure it does so through our Nexus repository.&lt;/p&gt;

&lt;p&gt;Go to the repositories administrator menu and click &lt;code&gt;Create repository&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Select &lt;code&gt;raw (proxy)&lt;/code&gt;.&lt;br&gt;
&lt;a href="https://media.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%2Freobnbszrgjbsqeyv2kr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Freobnbszrgjbsqeyv2kr.png" alt="create-maven-raw-proxy-repo-1."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fill in the details:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Name: gradle-distributions
Remote storage: https://services.gradle.org/distributions/
Blob store: maven
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.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%2Fjvvfqhzjbjxdhcn5fzap.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fjvvfqhzjbjxdhcn5fzap.png" alt="create-maven-raw-proxy-repo-2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now maven repositories are ready to use. You can head to the [[#Maven Usage Examples]] if you want to skip other repository configuration examples.&lt;/p&gt;

&lt;h2&gt;
  
  
  NPM Repository
&lt;/h2&gt;

&lt;p&gt;Next up, let's set up our NPM repository to manage JavaScript packages efficiently.&lt;/p&gt;

&lt;h3&gt;
  
  
  NPM Proxy Repository
&lt;/h3&gt;

&lt;p&gt;We'll create two NPM proxy repositories: one for the main npm registry and another for the Yarn package registry. This dual setup helps reduce potential downtime and provides a fallback option.&lt;/p&gt;

&lt;p&gt;Navigate to the repositories menu and create a new repository, selecting &lt;code&gt;npm (proxy)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fgpvndlqipw3c7keuxkx9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fgpvndlqipw3c7keuxkx9.png" alt="create-npm-proxy-repo-1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F8o7yt907n2s2ibjwaryv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F8o7yt907n2s2ibjwaryv.png" alt="create-npm-proxy-repo-2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For the npm registry, use these settings:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Name: npmjs
Remote Storage: https://registry.npmjs.org
Blob: npm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.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%2Fhighksnk37thjobyiqnq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fhighksnk37thjobyiqnq.png" alt="create-npm-proxy-repo-3"&gt;&lt;/a&gt;&lt;br&gt;
Hit "Create repository".&lt;/p&gt;

&lt;p&gt;Repeat the process for the Yarn registry:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Name: yarnpkg
Remote Storage: https://registry.yarnpkg.com
Blob: npm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  NPM Group Repository
&lt;/h3&gt;

&lt;p&gt;Now, let's group these repositories for easier management:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.jsdelivr.net%2Fgh%2Fburakberkkeskin%2Fblog-cdn%2Fsonatype-nexus-101%2Fimages%2F20-create-npm-group-repo-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.jsdelivr.net%2Fgh%2Fburakberkkeskin%2Fblog-cdn%2Fsonatype-nexus-101%2Fimages%2F20-create-npm-group-repo-1.png" alt="create-npm-group-repo-1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.jsdelivr.net%2Fgh%2Fburakberkkeskin%2Fblog-cdn%2Fsonatype-nexus-101%2Fimages%2F21-create-npm-group-repo-2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.jsdelivr.net%2Fgh%2Fburakberkkeskin%2Fblog-cdn%2Fsonatype-nexus-101%2Fimages%2F21-create-npm-group-repo-2.png" alt="create-npm-group-repo-2"&gt;&lt;/a&gt;&lt;br&gt;
Now NPM repositories are ready to use. You can head to the [[#NPM Usage Examples]] if you want to skip other repository configuration examples.&lt;/p&gt;
&lt;h2&gt;
  
  
  Docker Repository
&lt;/h2&gt;

&lt;p&gt;Last but not least, let's set up Docker repositories to manage container images efficiently.&lt;/p&gt;

&lt;p&gt;We'll create proxy repositories for &lt;code&gt;Docker Hub&lt;/code&gt;, &lt;code&gt;GitHub Container Registry&lt;/code&gt;, and &lt;code&gt;Red Hat Registry&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F4qfod48vib850vq9mss9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F4qfod48vib850vq9mss9.png" alt="create-docker-proxy-repo-1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fsi5xhwco07ion4z95v0b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fsi5xhwco07ion4z95v0b.png" alt="create-docker-proxy-repo-2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For Docker Hub:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Name: dockerhub
Allow anonymous docker pull: &lt;span class="nb"&gt;true
&lt;/span&gt;Remote Storage: https://registry-1.docker.io
Docker Index: Use Docker Hub 
Blob: docker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.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%2F69ht27tw5x5dx0g9rvuq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F69ht27tw5x5dx0g9rvuq.png" alt="create-docker-proxy-repo-4"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hit &lt;code&gt;Create repository&lt;/code&gt; button.&lt;/p&gt;

&lt;p&gt;Repeat the same process for &lt;code&gt;GitHub container registry&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Name: github-container-registry
Allow anonymous docker pull: &lt;span class="nb"&gt;true
&lt;/span&gt;Remote Storage: https://ghcr.io
Docker Index: Use proxy registry
Blob: docker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;[!important] &lt;br&gt;
 We didn't specify any &lt;code&gt;HTTP&lt;/code&gt; or &lt;code&gt;HTTPS&lt;/code&gt; port for the &lt;code&gt;dockerhub&lt;/code&gt; and &lt;code&gt;github-container-registry&lt;/code&gt; repository since we will group them and publish as groupped.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now create another Docker proxy repository for Red Hat registry but with the values below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Name: redhat-registry
HTTP: Enable and enter &lt;span class="sb"&gt;`&lt;/span&gt;8083&lt;span class="sb"&gt;`&lt;/span&gt;
Allow anonymous docker pull: &lt;span class="nb"&gt;true
&lt;/span&gt;Remote Storage: https://registry.access.redhat.com
Docker Index: Use proxy registry
Blob: docker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;[!important] &lt;br&gt;
 We are publishing the Red Hat registry directly, without a group. I am configuring the ports this way since my Nginx configuration is ready for that. You can check &lt;a href="https://dev.to/berk/installing-sonatype-nexus-with-nginx-reverse-proxy-https-1cag"&gt;the previous blog&lt;/a&gt; for the configuration.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Container Registry Group Repository
&lt;/h3&gt;

&lt;p&gt;We will group &lt;code&gt;dockerhub&lt;/code&gt; and &lt;code&gt;github-container-registry&lt;/code&gt; repositories. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Frpym8rlf6v6p0u01g78l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Frpym8rlf6v6p0u01g78l.png" alt="create-docker-group-repo-1"&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;Name: cr
HTTP: enabled on port &lt;span class="sb"&gt;`&lt;/span&gt;8082&lt;span class="sb"&gt;`&lt;/span&gt;
Blob store: docker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.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%2Fetylhpn8riqu88c2ulei.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fetylhpn8riqu88c2ulei.png" alt="create-docker-group-repo-2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fa144jqygclimrawelpzr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fa144jqygclimrawelpzr.png" alt="create-docker-group-repo-3"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hit create repository.&lt;/p&gt;

&lt;h2&gt;
  
  
  Maven Usage Examples
&lt;/h2&gt;

&lt;p&gt;To use your Maven repository, update your &lt;code&gt;build.gradle&lt;/code&gt; or &lt;code&gt;pom.xml&lt;/code&gt; files with the Nexus repository URL. For Android projects, also update the Gradle wrapper properties.&lt;/p&gt;

&lt;h3&gt;
  
  
  Check the Repository URLs
&lt;/h3&gt;

&lt;p&gt;Go to the repositories section and check the public URL of the &lt;code&gt;maven&lt;/code&gt; and &lt;code&gt;gradle-distributions&lt;/code&gt; repositories.&lt;br&gt;
&lt;a href="https://media.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%2Fa1wrey2opk0uatorggwb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fa1wrey2opk0uatorggwb.png" alt="check-maven-group-repo-url-1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Copy the URL.&lt;br&gt;
&lt;a href="https://media.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%2Fqrahndejybdckzcjjgqh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fqrahndejybdckzcjjgqh.png" alt="check-maven-group-repo-url-2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In my example, the repository URLs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;maven: https://registry.burakberk.dev/repository/maven/
gradle distributions: https://registry.burakberk.dev/repository/gradle-distributions/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Usage For an Android Gradle App
&lt;/h3&gt;

&lt;p&gt;Create an react native application just to test android app.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @react-native-community/cli init myreactnativeapp &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nb"&gt;cd &lt;/span&gt;myreactnativeapp/android
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Edit the &lt;code&gt;build.gradle&lt;/code&gt; file and add custom maven url. Remove the &lt;code&gt;google()&lt;/code&gt; and other maven repositories.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vim build.gradle
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;buildscript &lt;span class="o"&gt;{&lt;/span&gt;
    ext &lt;span class="o"&gt;{&lt;/span&gt;
        buildToolsVersion &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"34.0.0"&lt;/span&gt;
        minSdkVersion &lt;span class="o"&gt;=&lt;/span&gt; 23
        compileSdkVersion &lt;span class="o"&gt;=&lt;/span&gt; 34
        targetSdkVersion &lt;span class="o"&gt;=&lt;/span&gt; 34
        ndkVersion &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"26.1.10909125"&lt;/span&gt;
        kotlinVersion &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"1.9.24"&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    repositories &lt;span class="o"&gt;{&lt;/span&gt;
      maven &lt;span class="o"&gt;{&lt;/span&gt;
        url &lt;span class="s1"&gt;'https://registry.burakberk.dev/repository/maven'&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    dependencies &lt;span class="o"&gt;{&lt;/span&gt;
        classpath&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"com.android.tools.build:gradle"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        classpath&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"com.facebook.react:react-native-gradle-plugin"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        classpath&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"org.jetbrains.kotlin:kotlin-gradle-plugin"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

apply plugin: &lt;span class="s2"&gt;"com.facebook.react.rootproject"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also edit the gradle wrapper properties file to download the zip from the Nexus raw repository. Also update the timeout to a higher rate.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vim gradle/wrapper/gradle-wrapper.properties
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;gradle/wrapper/gradle-wrapper.properties
&lt;span class="nv"&gt;distributionBase&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;GRADLE_USER_HOME
&lt;span class="nv"&gt;distributionPath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;wrapper/dists
&lt;span class="nv"&gt;distributionUrl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;https&lt;span class="se"&gt;\:&lt;/span&gt;//registry.burakberk.dev/repository/gradle-distributions/gradle-8.8-all.zip
&lt;span class="nv"&gt;networkTimeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;120000
&lt;span class="nv"&gt;validateDistributionUrl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true
&lt;/span&gt;&lt;span class="nv"&gt;zipStoreBase&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;GRADLE_USER_HOME
&lt;span class="nv"&gt;zipStorePath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;wrapper/dists
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Usage for other Java Applications
&lt;/h3&gt;

&lt;p&gt;Edit the &lt;code&gt;pom.xml&lt;/code&gt;  file of the project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vim pom.xml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Change or edit the &lt;code&gt;repositories&lt;/code&gt; section. Add the public URL you copied from the nexus.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;repositories&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;repository&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;id&amp;gt;&lt;/span&gt;nexus-repo&lt;span class="nt"&gt;&amp;lt;/id&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;url&amp;gt;&lt;/span&gt;https://registry.burakberk.dev/repository/maven/&lt;span class="nt"&gt;&amp;lt;/url&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/repository&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/repositories&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Browse the Maven Repository From Nexus UI
&lt;/h3&gt;

&lt;p&gt;Check the maven repository if there are any downloaded and cached packages to make sure your configurations are correct and the packages are being downloaded from the Nexus.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F9lmi7lvoib2dhd3lmcty.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F9lmi7lvoib2dhd3lmcty.png" alt="check-maven-group-repo-1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  NPM Usage Examples
&lt;/h2&gt;

&lt;p&gt;Update your &lt;code&gt;package-lock.json&lt;/code&gt; or &lt;code&gt;yarn.lock&lt;/code&gt; files to use the Nexus NPM repository URL:&lt;/p&gt;

&lt;p&gt;Head to the Nexus UI and NPM group repository named &lt;code&gt;npm&lt;/code&gt; if you followed the guides above.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.jsdelivr.net%2Fgh%2Fburakberkkeskin%2Fblog-cdn%2Fsonatype-nexus-101%2Fimages%2F22-check-npm-group-repo-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.jsdelivr.net%2Fgh%2Fburakberkkeskin%2Fblog-cdn%2Fsonatype-nexus-101%2Fimages%2F22-check-npm-group-repo-1.png" alt="check-npm-group-repo-1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note the repository URL&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.jsdelivr.net%2Fgh%2Fburakberkkeskin%2Fblog-cdn%2Fsonatype-nexus-101%2Fimages%2F23-check-npm-group-repo-2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.jsdelivr.net%2Fgh%2Fburakberkkeskin%2Fblog-cdn%2Fsonatype-nexus-101%2Fimages%2F23-check-npm-group-repo-2.png" alt="check-npm-group-repo-2"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Sample NodeJS Application
&lt;/h3&gt;

&lt;p&gt;Create a new react application to test the Nexus repository.&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;my-app &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;my-app/ &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
npx create-react-app &lt;span class="nb"&gt;.&lt;/span&gt; my-app &lt;span class="nt"&gt;--template&lt;/span&gt; typescript
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Usage for NPM
&lt;/h3&gt;

&lt;p&gt;This command will replace all &lt;code&gt;https://registry.npmjs.org&lt;/code&gt; URLs in your &lt;code&gt;package-lock.json&lt;/code&gt; file with your own Nexus repository URL. It will also backup the original file before replacing the URLs.&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="nv"&gt;NEXUS_NPM_REGISTRY_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;https://registry.burakberk.dev/repository/npm  &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nv"&gt;DEFAULT_NPM_REGISTRY_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;https://registry.npmjs.org &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s1"&gt;'.backup'&lt;/span&gt; &lt;span class="s2"&gt;"s#&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;DEFAULT_NPM_REGISTRY_URL&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;#&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;NEXUS_NPM_REGISTRY_URL&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;#g"&lt;/span&gt; package-lock.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install packages.&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;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want to be sure about the downloaded packages are being downloaded from the Nexus URL, you can add &lt;code&gt;--verbose&lt;/code&gt; flag to the &lt;code&gt;npm install&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;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--verbose&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Usage for Yarn
&lt;/h3&gt;

&lt;p&gt;This command will replace all &lt;code&gt;https://registry.npmjs.org&lt;/code&gt; URLs in your &lt;code&gt;yarn.lock&lt;/code&gt; file with your own Nexus repository URL. It will also backup the original file before replacing the URLs.&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="nv"&gt;NEXUS_NPM_REGISTRY_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;https://registry.burakberk.dev/repository/npm  &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nv"&gt;DEFAULT_NPM_REGISTRY_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;https://registry.yarnpkg.com &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s1"&gt;'.backup'&lt;/span&gt; &lt;span class="s2"&gt;"s#&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;DEFAULT_NPM_REGISTRY_URL&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;#&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;NEXUS_NPM_REGISTRY_URL&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;#g"&lt;/span&gt; yarn.lock
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install packages.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want to be sure about the downloaded packages are being downloaded from the Nexus URL, you can add &lt;code&gt;--verbose&lt;/code&gt; flag to the &lt;code&gt;npm install&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;yarn &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--verbose&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Browse the NPM Repository From Nexus UI
&lt;/h3&gt;

&lt;p&gt;Check the NPM repository if there are any downloaded and cached packages to make sure your configurations are correct and the packages are being downloaded from the Nexus.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F7uzexusherd58keuqlu0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F7uzexusherd58keuqlu0.png" alt="check-npm-group-repo-3"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Docker Usage Examples
&lt;/h2&gt;

&lt;h3&gt;
  
  
  CR registry: Group of Docker Hub and Github Container Registry
&lt;/h3&gt;

&lt;p&gt;Try to pull a standart image like &lt;code&gt;nginx&lt;/code&gt; or &lt;code&gt;ubuntu&lt;/code&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="nv"&gt;$ &lt;/span&gt;docker pull cr.burakberk.dev/nginx
Using default tag: latest
latest: Pulling from nginx
302e3ee49805: Pull &lt;span class="nb"&gt;complete
&lt;/span&gt;d07412f52e9d: Pull &lt;span class="nb"&gt;complete
&lt;/span&gt;9ab66c386e9c: Pull &lt;span class="nb"&gt;complete
&lt;/span&gt;4b563e5e980a: Pull &lt;span class="nb"&gt;complete
&lt;/span&gt;55af3c8febf2: Pull &lt;span class="nb"&gt;complete
&lt;/span&gt;5b8e768fb22d: Pull &lt;span class="nb"&gt;complete
&lt;/span&gt;85177e2c6f39: Pull &lt;span class="nb"&gt;complete
&lt;/span&gt;Digest: sha256:d2eb56950b84efe34f966a2b92efb1a1a2ea53e7e93b94cdf45a27cf3cd47fc0
Status: Downloaded newer image &lt;span class="k"&gt;for &lt;/span&gt;cr.burakberk.dev/nginx:latest
cr.burakberk.dev/nginx:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Successfully pulled the image from the Nexus repository. The image is downloaded from the Docker Hub proxy registry.&lt;/p&gt;

&lt;p&gt;Now lets try to pull a Github container registry specific 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 cr.burakberk.dev/github/super-linter:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Successfully pulled ✅ &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fusi25omuwos3scrsrwrf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fusi25omuwos3scrsrwrf.png" alt="check-docker-group-repo-1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Red Hat Registry
&lt;/h3&gt;

&lt;p&gt;Run the &lt;code&gt;docker pull&lt;/code&gt; command on two different registries and see if you can pull the images from the Nexus installation.&lt;/p&gt;

&lt;p&gt;For example, pulling the &lt;code&gt;ubi:8.10-1088&lt;/code&gt; image from the &lt;code&gt;redhat-registry&lt;/code&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="nv"&gt;$ &lt;/span&gt;docker pull redhat-registry.burakberk.dev/ubi8/ubi:8.10-1088
8.10-1088: Pulling from ubi8/ubi
148a3ed2f70e: Pull &lt;span class="nb"&gt;complete
&lt;/span&gt;Digest: sha256:a965f33ee4ee57dc8e40a1f9350ddf28ed0727b6cf80db46cdad0486a7580f9d
Status: Downloaded newer image &lt;span class="k"&gt;for &lt;/span&gt;redhat-registry.burakberk.dev/ubi8/ubi:8.10-1088
redhat-registry.burakberk.dev/ubi8/ubi:8.10-1088
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Successfully pulled ✅&lt;/p&gt;

&lt;p&gt;Also browse the Nexus repository and check if the image exists.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fie83choj9yakrmq02ro5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fie83choj9yakrmq02ro5.png" alt="create-docker-group-repo-4"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Congratulations! You've now set up a comprehensive Nexus repository manager capable of handling Maven, NPM, and Docker packages. This setup will provide faster access to packages and greater control over your dependencies.&lt;/p&gt;

&lt;p&gt;Remember to regularly maintain your Nexus instance, keeping an eye on storage usage and updating proxy repositories as needed.&lt;/p&gt;

</description>
      <category>nexus</category>
      <category>registry</category>
      <category>sonatype</category>
      <category>repository</category>
    </item>
    <item>
      <title>Installing Sonatype Nexus With Nginx Reverse Proxy &amp; HTTPS</title>
      <dc:creator>Berk</dc:creator>
      <pubDate>Sun, 06 Oct 2024 20:25:17 +0000</pubDate>
      <link>https://dev.to/berk/installing-sonatype-nexus-with-nginx-reverse-proxy-https-1cag</link>
      <guid>https://dev.to/berk/installing-sonatype-nexus-with-nginx-reverse-proxy-https-1cag</guid>
      <description>&lt;h2&gt;
  
  
  Introduction to Sonatype Nexus
&lt;/h2&gt;

&lt;p&gt;Sonatype Nexus is a powerful repository manager that has become an essential tool in modern software development ecosystems. It serves as a central hub for storing and managing various types of artifacts, including Maven dependencies, NPM packages, Docker images, and more.&lt;/p&gt;

&lt;p&gt;But for a container image registry, I prefer Harbor:) &lt;/p&gt;

&lt;h3&gt;
  
  
  Why Use Sonatype Nexus?
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Centralized Management&lt;/strong&gt;: Nexus provides a single point of control for all your software artifacts, simplifying dependency management across projects.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Improved Build Performance&lt;/strong&gt;: By caching dependencies locally, Nexus significantly reduces build times and network usage.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enhanced Security&lt;/strong&gt;: Nexus offers fine-grained access control and can act as a firewall between your organization and public repositories.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Support for Multiple Repository Formats&lt;/strong&gt;: Nexus can handle various repository types, including Maven, NPM, Docker, and raw repositories, among others.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CI/CD Pipeline Optimization&lt;/strong&gt;: For organizations running Continuous Integration and Continuous Deployment (CI/CD) pipelines, Nexus acts as a local cache for dependencies. This caching mechanism substantially improves pipeline performance by reducing network-dependent downloads, leading to faster and more reliable builds.
## Installation with HTTPS&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In this guide, we'll walk through the process of installing Nexus and configuring Nginx as a reverse proxy, all containerized using Docker. This setup will provide HTTPS access to your Nexus instance.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Docker and Docker Compose installed on your system&lt;/li&gt;
&lt;li&gt;A domain name (for HTTPS configuration)&lt;/li&gt;
&lt;li&gt;SSL certificate and key for your domain&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 1: Set Up the Directory Structure
&lt;/h3&gt;

&lt;p&gt;First, let's create the necessary directory structure for our Nexus installation:&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;nexus &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;nexus &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; config/ssl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Create Docker Compose File
&lt;/h3&gt;

&lt;p&gt;Create a &lt;code&gt;docker-compose.yaml&lt;/code&gt; file in the &lt;code&gt;nexus&lt;/code&gt; directory with the following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vim docker-compose.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;nexus&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="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sonatype/nexus3:3.72.0"&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="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;nexus-data:/nexus-data"&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;proxy&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="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;nginx:alpine"&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;80:80"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;443:443"&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;./config/nginx.conf:/etc/nginx/nginx.conf&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./config/ssl/:/etc/nginx/ssl&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;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;nexus-data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This configuration sets up two services:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;nexus&lt;/code&gt;: The Sonatype Nexus service

&lt;ul&gt;
&lt;li&gt;There is no ports published from the &lt;code&gt;nexus&lt;/code&gt; service since we will use Nginx for all requests. &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;proxy&lt;/code&gt;: An Nginx service acting as a reverse proxy&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Step 3: Configure Nginx
&lt;/h3&gt;

&lt;p&gt;Create an Nginx configuration file at &lt;code&gt;config/nginx.conf&lt;/code&gt; with the following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vim config/nginx.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="n"&gt;worker_processes&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;;

&lt;span class="n"&gt;events&lt;/span&gt; {
  &lt;span class="n"&gt;worker_connections&lt;/span&gt; &lt;span class="m"&gt;1024&lt;/span&gt;;
}

&lt;span class="n"&gt;http&lt;/span&gt; {
    &lt;span class="n"&gt;proxy_send_timeout&lt;/span&gt; &lt;span class="m"&gt;120&lt;/span&gt;;
    &lt;span class="n"&gt;proxy_read_timeout&lt;/span&gt; &lt;span class="m"&gt;300&lt;/span&gt;;
    &lt;span class="n"&gt;proxy_buffering&lt;/span&gt;    &lt;span class="n"&gt;off&lt;/span&gt;;
    &lt;span class="n"&gt;proxy_request_buffering&lt;/span&gt; &lt;span class="n"&gt;off&lt;/span&gt;;
    &lt;span class="n"&gt;keepalive_timeout&lt;/span&gt;  &lt;span class="m"&gt;5&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;;
    &lt;span class="n"&gt;tcp_nodelay&lt;/span&gt;        &lt;span class="n"&gt;on&lt;/span&gt;;

    &lt;span class="n"&gt;server&lt;/span&gt; {
        &lt;span class="n"&gt;listen&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;;
        &lt;span class="n"&gt;server_name&lt;/span&gt; &lt;span class="n"&gt;registry&lt;/span&gt;.&lt;span class="n"&gt;burakberk&lt;/span&gt;.&lt;span class="n"&gt;dev&lt;/span&gt;;
        &lt;span class="n"&gt;location&lt;/span&gt; / {
            &lt;span class="n"&gt;return&lt;/span&gt; &lt;span class="m"&gt;301&lt;/span&gt; &lt;span class="n"&gt;https&lt;/span&gt;://$&lt;span class="n"&gt;host&lt;/span&gt;$&lt;span class="n"&gt;request_uri&lt;/span&gt;;
        }
    }

    &lt;span class="n"&gt;server&lt;/span&gt; {
        &lt;span class="n"&gt;listen&lt;/span&gt; &lt;span class="m"&gt;443&lt;/span&gt; &lt;span class="n"&gt;ssl&lt;/span&gt;;
        &lt;span class="n"&gt;server_name&lt;/span&gt;  &lt;span class="n"&gt;registry&lt;/span&gt;.&lt;span class="n"&gt;burakberk&lt;/span&gt;.&lt;span class="n"&gt;dev&lt;/span&gt;;
        &lt;span class="n"&gt;ssl_certificate&lt;/span&gt; /&lt;span class="n"&gt;etc&lt;/span&gt;/&lt;span class="n"&gt;nginx&lt;/span&gt;/&lt;span class="n"&gt;ssl&lt;/span&gt;/&lt;span class="n"&gt;server&lt;/span&gt;.&lt;span class="n"&gt;crt&lt;/span&gt;;
        &lt;span class="n"&gt;ssl_certificate_key&lt;/span&gt; /&lt;span class="n"&gt;etc&lt;/span&gt;/&lt;span class="n"&gt;nginx&lt;/span&gt;/&lt;span class="n"&gt;ssl&lt;/span&gt;/&lt;span class="n"&gt;server&lt;/span&gt;.&lt;span class="n"&gt;key&lt;/span&gt;;
        &lt;span class="n"&gt;client_max_body_size&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="n"&gt;G&lt;/span&gt;;
        &lt;span class="c"&gt;# optimize downloading files larger than 1G - refer to nginx doc before adjusting
&lt;/span&gt;        &lt;span class="c"&gt;#proxy_max_temp_file_size 2G;
&lt;/span&gt;        &lt;span class="n"&gt;location&lt;/span&gt; / {
            &lt;span class="n"&gt;proxy_pass&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;://&lt;span class="n"&gt;nexus&lt;/span&gt;:&lt;span class="m"&gt;8081&lt;/span&gt;;
            &lt;span class="n"&gt;proxy_set_header&lt;/span&gt; &lt;span class="n"&gt;Host&lt;/span&gt; $&lt;span class="n"&gt;host&lt;/span&gt;;
            &lt;span class="n"&gt;proxy_set_header&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;-&lt;span class="n"&gt;Real&lt;/span&gt;-&lt;span class="n"&gt;IP&lt;/span&gt; $&lt;span class="n"&gt;remote_addr&lt;/span&gt;;
            &lt;span class="n"&gt;proxy_set_header&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;-&lt;span class="n"&gt;Forwarded&lt;/span&gt;-&lt;span class="n"&gt;For&lt;/span&gt; $&lt;span class="n"&gt;proxy_add_x_forwarded_for&lt;/span&gt;;
            &lt;span class="n"&gt;proxy_set_header&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;-&lt;span class="n"&gt;Forwarded&lt;/span&gt;-&lt;span class="n"&gt;Proto&lt;/span&gt; &lt;span class="s2"&gt;"https"&lt;/span&gt;;
        }
    }

    &lt;span class="n"&gt;server&lt;/span&gt; {
        &lt;span class="n"&gt;listen&lt;/span&gt; &lt;span class="m"&gt;443&lt;/span&gt; &lt;span class="n"&gt;ssl&lt;/span&gt;;
        &lt;span class="n"&gt;server_name&lt;/span&gt; &lt;span class="n"&gt;cr&lt;/span&gt;.&lt;span class="n"&gt;burakberk&lt;/span&gt;.&lt;span class="n"&gt;dev&lt;/span&gt;;
        &lt;span class="n"&gt;ssl_certificate&lt;/span&gt; /&lt;span class="n"&gt;etc&lt;/span&gt;/&lt;span class="n"&gt;nginx&lt;/span&gt;/&lt;span class="n"&gt;ssl&lt;/span&gt;/&lt;span class="n"&gt;cr&lt;/span&gt;.&lt;span class="n"&gt;crt&lt;/span&gt;;
        &lt;span class="n"&gt;ssl_certificate_key&lt;/span&gt; /&lt;span class="n"&gt;etc&lt;/span&gt;/&lt;span class="n"&gt;nginx&lt;/span&gt;/&lt;span class="n"&gt;ssl&lt;/span&gt;/&lt;span class="n"&gt;cr&lt;/span&gt;.&lt;span class="n"&gt;key&lt;/span&gt;;
        &lt;span class="n"&gt;client_max_body_size&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="n"&gt;G&lt;/span&gt;;
        &lt;span class="c"&gt;# optimize downloading files larger than 1G - refer to nginx doc before adjusting
&lt;/span&gt;        &lt;span class="c"&gt;#proxy_max_temp_file_size 2G;
&lt;/span&gt;        &lt;span class="n"&gt;location&lt;/span&gt; / {
            &lt;span class="n"&gt;proxy_pass&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;://&lt;span class="n"&gt;nexus&lt;/span&gt;:&lt;span class="m"&gt;8082&lt;/span&gt;/;
            &lt;span class="n"&gt;proxy_set_header&lt;/span&gt; &lt;span class="n"&gt;Host&lt;/span&gt; $&lt;span class="n"&gt;host&lt;/span&gt;;
            &lt;span class="n"&gt;proxy_set_header&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;-&lt;span class="n"&gt;REAL&lt;/span&gt;-&lt;span class="n"&gt;IP&lt;/span&gt; $&lt;span class="n"&gt;remote_addr&lt;/span&gt;;
            &lt;span class="n"&gt;proxy_set_header&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;-&lt;span class="n"&gt;Forwarded&lt;/span&gt;-&lt;span class="n"&gt;For&lt;/span&gt; $&lt;span class="n"&gt;proxy_add_x_forwarded_for&lt;/span&gt;;
            &lt;span class="n"&gt;proxy_set_header&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;-&lt;span class="n"&gt;Forwarded&lt;/span&gt;-&lt;span class="n"&gt;Proto&lt;/span&gt; &lt;span class="s2"&gt;"https"&lt;/span&gt;;
        }
    }

    &lt;span class="n"&gt;server&lt;/span&gt; {
        &lt;span class="n"&gt;listen&lt;/span&gt; &lt;span class="m"&gt;443&lt;/span&gt; &lt;span class="n"&gt;ssl&lt;/span&gt;;
        &lt;span class="n"&gt;server_name&lt;/span&gt; &lt;span class="n"&gt;redhat&lt;/span&gt;-&lt;span class="n"&gt;registry&lt;/span&gt;.&lt;span class="n"&gt;burakberk&lt;/span&gt;.&lt;span class="n"&gt;dev&lt;/span&gt;;
        &lt;span class="n"&gt;ssl_certificate&lt;/span&gt; /&lt;span class="n"&gt;etc&lt;/span&gt;/&lt;span class="n"&gt;nginx&lt;/span&gt;/&lt;span class="n"&gt;ssl&lt;/span&gt;/&lt;span class="n"&gt;redhat&lt;/span&gt;-&lt;span class="n"&gt;registry&lt;/span&gt;.&lt;span class="n"&gt;crt&lt;/span&gt;;
        &lt;span class="n"&gt;ssl_certificate_key&lt;/span&gt; /&lt;span class="n"&gt;etc&lt;/span&gt;/&lt;span class="n"&gt;nginx&lt;/span&gt;/&lt;span class="n"&gt;ssl&lt;/span&gt;/&lt;span class="n"&gt;redhat&lt;/span&gt;-&lt;span class="n"&gt;registry&lt;/span&gt;.&lt;span class="n"&gt;key&lt;/span&gt;;
        &lt;span class="n"&gt;client_max_body_size&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="n"&gt;G&lt;/span&gt;;
        &lt;span class="c"&gt;# optimize downloading files larger than 1G - refer to nginx doc before adjusting
&lt;/span&gt;        &lt;span class="c"&gt;#proxy_max_temp_file_size 2G;
&lt;/span&gt;        &lt;span class="n"&gt;location&lt;/span&gt; / {
            &lt;span class="n"&gt;proxy_pass&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;://&lt;span class="n"&gt;nexus&lt;/span&gt;:&lt;span class="m"&gt;8083&lt;/span&gt;/;
            &lt;span class="n"&gt;proxy_set_header&lt;/span&gt; &lt;span class="n"&gt;Host&lt;/span&gt; $&lt;span class="n"&gt;host&lt;/span&gt;;
            &lt;span class="n"&gt;proxy_set_header&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;-&lt;span class="n"&gt;REAL&lt;/span&gt;-&lt;span class="n"&gt;IP&lt;/span&gt; $&lt;span class="n"&gt;remote_addr&lt;/span&gt;;
            &lt;span class="n"&gt;proxy_set_header&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;-&lt;span class="n"&gt;Forwarded&lt;/span&gt;-&lt;span class="n"&gt;For&lt;/span&gt; $&lt;span class="n"&gt;proxy_add_x_forwarded_for&lt;/span&gt;;
            &lt;span class="n"&gt;proxy_set_header&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;-&lt;span class="n"&gt;Forwarded&lt;/span&gt;-&lt;span class="n"&gt;Proto&lt;/span&gt; &lt;span class="s2"&gt;"https"&lt;/span&gt;;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This configuration sets up HTTP to HTTPS redirection and proxies requests to the Nexus container.&lt;/p&gt;

&lt;p&gt;In Nexus, generally container image registries run  on different ports. So if you want to host a container image registry, I recommend to create virtual servers as you need in the Nginx configuration above. &lt;/p&gt;

&lt;p&gt;For a brief, &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I will create 3 docker proxy registry. 

&lt;ul&gt;
&lt;li&gt;Docker hub&lt;/li&gt;
&lt;li&gt;Red Hat registry&lt;/li&gt;
&lt;li&gt;GitHub container registry&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Group the Docker hub and Github container registry under a common name

&lt;ul&gt;
&lt;li&gt;Publish it on the port &lt;code&gt;8082&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Access with the domain &lt;code&gt;cr.burakberk.dev&lt;/code&gt; &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Standalone Red Hat registry

&lt;ul&gt;
&lt;li&gt;Publish it on the port &lt;code&gt;8083&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Access with the domain &lt;code&gt;redhat-registry.burakberk.dev&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;[!tip] &lt;br&gt;
 I will share how to configure and use the Nexus repositories in another blog post.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Step 4: Set Up SSL Certificates
&lt;/h3&gt;

&lt;p&gt;You can obtain the SSL certificates from LetsEncrypt for free.&lt;br&gt;
I used self-signed certificates that created with &lt;code&gt;crtforge&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;[!note] &lt;br&gt;
If you don't have an SSL certificate, you can obtain one from Let's Encrypt for free if you own a public domain name. &lt;br&gt;
Alternatively, you can create your self-signed SSL certificates by following the  &lt;a href="https://dev.to/berk/creating-fullchain-self-signed-ssl-with-3-commands-1i0i"&gt;Creating Fullchain Self Signed SSL With 3 Commands&lt;/a&gt; blog post.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Copy the SSL certificates and keys to the &lt;code&gt;config/ssl&lt;/code&gt; directory:&lt;/p&gt;

&lt;p&gt;For &lt;code&gt;registry.burakberk.dev&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Certificate: &lt;code&gt;config/ssl/server.crt&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Key: &lt;code&gt;config/ssl/server.key&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For &lt;code&gt;cr.burakberk.dev&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Certificate: &lt;code&gt;config/ssl/cr.crt&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Key: &lt;code&gt;config/ssl/cr.key&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For &lt;code&gt;redhat-registry.burakberk.dev&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Certificate: &lt;code&gt;config/ssl/redhat-registry.crt&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Key: &lt;code&gt;config/ssl/redhat-registry.key&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;[!info] &lt;br&gt;
It is best practice to copy fullchain certificate into the &lt;code&gt;server.crt&lt;/code&gt;  file.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The overall file structure should be:&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="nv"&gt;$ &lt;/span&gt;tree
nexus
├── config
│   ├── nginx.conf
│   └── ssl
│       ├── server.crt
│       └── server.key
└── docker-compose.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 5: Start the Services
&lt;/h3&gt;

&lt;p&gt;Run the following command to start Nexus and Nginx:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 6: Retrieve Initial Admin Password
&lt;/h3&gt;

&lt;p&gt;To access the Nexus web UI, you'll need the initial admin password. Retrieve it with the following 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 compose &lt;span class="nb"&gt;exec &lt;/span&gt;nexus &lt;span class="nb"&gt;cat&lt;/span&gt; /nexus-data/admin.password
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 7: Access Nexus Web UI
&lt;/h3&gt;

&lt;p&gt;Open your web browser and navigate to &lt;code&gt;https://registry.burakberk.dev&lt;/code&gt; (replace with your actual domain). Log in with the following credentials:&lt;/p&gt;

&lt;p&gt;Login with the admin user.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;username: admin
password: the password you retrieved &lt;span class="k"&gt;in &lt;/span&gt;Step 6
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Follow the initial setup wizard to change the admin password and configure anonymous access if desired. I will enable anonymous access in my case.&lt;/p&gt;

&lt;h2&gt;
  
  
  Move to the Nexus Usage
&lt;/h2&gt;

&lt;p&gt;You can head over to the my next post to read &lt;a href="https://dev.to/berk/sonatype-nexus-usage-101-5h82"&gt;Sonatype Nexus 101&lt;/a&gt; to see how to configure Maven, NPM and container image repositories. You can also see some use cases and tests in the blog post.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Free, Self-Hosted &amp; Private Copilot to Streamline Coding</title>
      <dc:creator>Berk</dc:creator>
      <pubDate>Sat, 31 Aug 2024 07:15:30 +0000</pubDate>
      <link>https://dev.to/berk/streamline-code-writing-with-free-self-hosted-private-free-copilot-5230</link>
      <guid>https://dev.to/berk/streamline-code-writing-with-free-self-hosted-private-free-copilot-5230</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;In today's fast-paced development landscape, having a reliable and efficient copilot by your side can be a game-changer. However, relying on cloud-based services often comes with concerns over data privacy and security. This is where self-hosted LLMs come into play, offering a cutting-edge solution that empowers developers to tailor their functionalities while keeping sensitive information within their control.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Advantages of Self-Hosted LLMs
&lt;/h3&gt;

&lt;p&gt;Self-hosted LLMs provide unparalleled advantages over their hosted counterparts. By hosting the model on your machine, you gain greater control over customization, enabling you to tailor functionalities to your specific needs. Moreover, self-hosted solutions ensure data privacy and security, as sensitive information remains within the confines of your infrastructure.&lt;/p&gt;

&lt;p&gt;Imagine having a Copilot or Cursor alternative that is both free and private, seamlessly integrating with your development environment to offer real-time code suggestions, completions, and reviews. This self-hosted copilot leverages powerful language models to provide intelligent coding assistance while ensuring your data remains secure and under your control. A free self-hosted copilot eliminates the need for expensive subscriptions or licensing fees associated with hosted solutions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Getting Started with Ollama
&lt;/h3&gt;

&lt;p&gt;In this article, we will explore how to use a cutting-edge LLM hosted on your machine to connect it to VSCode for a powerful free self-hosted Copilot or Cursor experience without sharing any information with third-party services. We will utilize the Ollama server, which has been previously deployed in our &lt;a href="https://dev.to/berk/running-ollama-and-open-webui-self-hosted-4ih5"&gt;previous blog post&lt;/a&gt;. If you don't have Ollama or another OpenAI API-compatible LLM, you can follow the instructions outlined in that article to deploy and configure your own instance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pre-requirements
&lt;/h2&gt;

&lt;p&gt;Before we dive into the installation process, ensure that you meet the following pre-requisites:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;VSCode installed on your machine.&lt;/li&gt;
&lt;li&gt;Network access to the Ollama server. If you are running the Ollama on another machine, you should be able to connect to the Ollama server port.&lt;/li&gt;
&lt;li&gt;If you want to test if you can connect to the Ollama server on another machine, you can use the following command:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl http://192.168.1.100:11434
Ollama is running
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;If you want to test if you can connect to the Ollama server on the local machine, you can use the following command:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl http://127.0.0.1:11434
Ollama is running
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;If you don't have Ollama installed, check &lt;a href="https://dev.to/berk/running-ollama-and-open-webui-self-hosted-4ih5"&gt;the previous blog&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Installing the Continue plugin
&lt;/h2&gt;

&lt;p&gt;To integrate your LLM with VSCode, begin by installing the &lt;a href="https://github.com/continuedev/continue" rel="noopener noreferrer"&gt;Continue&lt;/a&gt; extension that enable copilot functionalities.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Ff0lsqhkei4gwfe6m96qz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Ff0lsqhkei4gwfe6m96qz.png" alt="Install continue" width="792" height="520"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Configure the Continue Plugin
&lt;/h2&gt;

&lt;p&gt;In MacOS and Linux, you can find the configuration file in &lt;code&gt;~/.continue/config.json&lt;/code&gt;. In Windows, it is in &lt;code&gt;%userprofile%\.continue/config.json&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Edit the file with a text editor. Here I will show to edit with &lt;code&gt;vim&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vim ~/.continue/config.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the models list, add the models that installed on the Ollama server you want to use in the VSCode. In the example below, I will define two LLMs installed my Ollama server which is &lt;code&gt;deepseek-coder&lt;/code&gt; and &lt;code&gt;llama3.1&lt;/code&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="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"models"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
    &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"title"&lt;/span&gt;: &lt;span class="s2"&gt;"Llama 3"&lt;/span&gt;,
      &lt;span class="s2"&gt;"provider"&lt;/span&gt;: &lt;span class="s2"&gt;"ollama"&lt;/span&gt;,
      &lt;span class="s2"&gt;"model"&lt;/span&gt;: &lt;span class="s2"&gt;"llama3"&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;,
    &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"title"&lt;/span&gt;: &lt;span class="s2"&gt;"Ollama"&lt;/span&gt;,
      &lt;span class="s2"&gt;"provider"&lt;/span&gt;: &lt;span class="s2"&gt;"ollama"&lt;/span&gt;,
      &lt;span class="s2"&gt;"model"&lt;/span&gt;: &lt;span class="s2"&gt;"AUTODETECT"&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;,
    &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"title"&lt;/span&gt;: &lt;span class="s2"&gt;"Local Ollama DeepSeek-Coder 6.7b"&lt;/span&gt;,
      &lt;span class="s2"&gt;"provider"&lt;/span&gt;: &lt;span class="s2"&gt;"ollama"&lt;/span&gt;,
      &lt;span class="s2"&gt;"model"&lt;/span&gt;: &lt;span class="s2"&gt;"deepseek-coder:6.7b-instruct-q8_0"&lt;/span&gt;,
      &lt;span class="s2"&gt;"apiBase"&lt;/span&gt;: &lt;span class="s2"&gt;"http://192.168.1.100:11434"&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;,
    &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"title"&lt;/span&gt;: &lt;span class="s2"&gt;"Local Ollama LLama3.1"&lt;/span&gt;,
      &lt;span class="s2"&gt;"provider"&lt;/span&gt;: &lt;span class="s2"&gt;"ollama"&lt;/span&gt;,
      &lt;span class="s2"&gt;"model"&lt;/span&gt;: &lt;span class="s2"&gt;"llama3.1:8b-instruct-q8_0"&lt;/span&gt;,
      &lt;span class="s2"&gt;"apiBase"&lt;/span&gt;: &lt;span class="s2"&gt;"http://192.168.1.100:11434"&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;]&lt;/span&gt;,
...
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save and exit the file. If you use the &lt;code&gt;vim&lt;/code&gt; command to edit the file, hit &lt;code&gt;ESC&lt;/code&gt;, then type &lt;code&gt;:wq!&lt;/code&gt; and hit enter.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test the Ollama LLMs on VSCode with Continue
&lt;/h2&gt;

&lt;p&gt;Open the VSCode window and Continue extension chat menu.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Flbq2we0bgte3vbg4h5pt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Flbq2we0bgte3vbg4h5pt.png" alt="Test Ollama" width="792" height="520"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Check if the LLMs exists that you have configured in the previous step. Send a test message like "hi" and check if you can get response from the Ollama server.&lt;/p&gt;

&lt;p&gt;You can use that menu to chat with the Ollama server without needing a web UI.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using Continue as Copilot Alternative
&lt;/h2&gt;

&lt;p&gt;To use Ollama and Continue as a Copilot alternative, we will create a Golang CLI app.&lt;/p&gt;

&lt;p&gt;Lets create a Go application in an empty directory.&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;aitest
&lt;span class="nb"&gt;cd &lt;/span&gt;aitest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open the directory with the VSCode.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;code &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a file named &lt;code&gt;main.go&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Hit &lt;code&gt;command&lt;/code&gt; (&lt;code&gt;ctrl&lt;/code&gt; on Windows/Linux) + &lt;code&gt;I&lt;/code&gt; to open the Continue context menu.&lt;/p&gt;

&lt;p&gt;Copy the prompt below and give it to Continue to ask for the application codes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Create a command-line interface &lt;span class="o"&gt;(&lt;/span&gt;CLI&lt;span class="o"&gt;)&lt;/span&gt; application that meets the following requirements: The application should display its version, provide a &lt;span class="nb"&gt;help &lt;/span&gt;message, and include usage examples. The CLI should accept one positional argument, which will be a number. Upon execution, the application should print numbers from 0 up to the provided number. Additionally, &lt;span class="k"&gt;while &lt;/span&gt;printing each number, the application should display a progress bar indicating the percentage of completion. The progress bar should use the symbol &lt;span class="s2"&gt;"#"&lt;/span&gt; to represent the progress and also display the percentage as a number. The application should &lt;span class="nb"&gt;wait &lt;/span&gt;3 milliseconds before printing each number to simulate the progress. The output should always be on one line, and each new log should overwrite the previous one. Do not use any external libraries &lt;span class="k"&gt;for &lt;/span&gt;this task.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can see the performance and quality of the code from the video below:&lt;/p&gt;


  


</description>
      <category>githubcopilot</category>
      <category>ai</category>
      <category>llm</category>
      <category>cursor</category>
    </item>
    <item>
      <title>Running Ollama and Open WebUI Self-Hosted With AMD GPU</title>
      <dc:creator>Berk</dc:creator>
      <pubDate>Sat, 25 May 2024 09:04:54 +0000</pubDate>
      <link>https://dev.to/berk/running-ollama-and-open-webui-self-hosted-4ih5</link>
      <guid>https://dev.to/berk/running-ollama-and-open-webui-self-hosted-4ih5</guid>
      <description>&lt;h2&gt;
  
  
  Why Host Your Own Large Language Model (LLM)?
&lt;/h2&gt;

&lt;p&gt;While there are many excellent LLMs available for VSCode, hosting your own LLM offers several advantages that can significantly enhance your coding experience. Below you can find some reasons to host your own LLM.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Customization and Fine-Tuning&lt;/li&gt;
&lt;li&gt;Data Control and Security&lt;/li&gt;
&lt;li&gt;Domain Expertise&lt;/li&gt;
&lt;li&gt;Easy Switching Between Models&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;To host your own Large Language Model (LLM) for use in VSCode, you'll need a few pieces of hardware and software in place. &lt;/p&gt;

&lt;h3&gt;
  
  
  Hardware Requirements
&lt;/h3&gt;

&lt;p&gt;For this example, we'll be using a Radeon 6700 XT graphics card and a Ryzen 5 7600X processor on Linux. However, you can also host an LLM on Windows or macOS machines with compatible hardware.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A modern CPU (at least quad-core) with high-performance capabilities&lt;/li&gt;
&lt;li&gt;A suitable graphics card with OpenCL or HIP support (Radeon or NVIDIA)&lt;/li&gt;
&lt;li&gt;At least 16 GB of RAM for smooth performance&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Software Prerequisites
&lt;/h3&gt;

&lt;p&gt;To get started, you'll need to install the packages you need on your Linux machine are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Docker&lt;/li&gt;
&lt;li&gt;GPU drivers.&lt;/li&gt;
&lt;li&gt;Nvidia Container Toolkit (if you use Nvidia GPU)&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;[!tip] &lt;br&gt;
 If you don't have docker installed already, please check the &lt;a href="https://docs.docker.com/engine/install/" rel="noopener noreferrer"&gt;Docker Installation&lt;/a&gt; document.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It doesn't matter if you are using Arch, Debian, Ubuntu, Mint etc. Since we will use containers, the environment will be the same. &lt;/p&gt;

&lt;p&gt;Note that we won't be training our own LLM models; instead, we'll focus on hosting and running pre-trained models. This means you won't need a high-performance GPU or specialized hardware for model training.&lt;/p&gt;

&lt;p&gt;With these prerequisites in place, you're ready to start setting up your LLM hosting environment!&lt;/p&gt;

&lt;h2&gt;
  
  
  Deploying the AI
&lt;/h2&gt;

&lt;p&gt;We will deploy two containers. One for the Ollama server which runs the LLMs and one for the Open WebUI which we integrate with the Ollama server from a browser.&lt;/p&gt;

&lt;p&gt;To deploy Ollama, you have three options:&lt;/p&gt;

&lt;h3&gt;
  
  
  Running Ollama on AMD GPU (Recommended)
&lt;/h3&gt;

&lt;p&gt;If you have a AMD GPU that supports &lt;a href="https://www.amd.com/en/products/software/rocm.html" rel="noopener noreferrer"&gt;ROCm&lt;/a&gt;, you can simple run the &lt;code&gt;rocm&lt;/code&gt; version of the Ollama 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 run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;--restart&lt;/span&gt; always &lt;span class="nt"&gt;--device&lt;/span&gt; /dev/kfd &lt;span class="nt"&gt;--device&lt;/span&gt; /dev/dri &lt;span class="nt"&gt;-v&lt;/span&gt; ollama:/root/.ollama &lt;span class="nt"&gt;-p&lt;/span&gt; 11434:11434 &lt;span class="nt"&gt;--name&lt;/span&gt; ollama ollama/ollama:rocm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;If your AMD GPU doesn't support &lt;code&gt;ROCm&lt;/code&gt; but if it is strong enough, you can still use your GPU to run Ollama server. I use that command to run on a Radeon 6700 XT GPU.&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;--restart&lt;/span&gt; always &lt;span class="nt"&gt;--device&lt;/span&gt; /dev/kfd &lt;span class="nt"&gt;--device&lt;/span&gt; /dev/dri &lt;span class="nt"&gt;-v&lt;/span&gt; ollama:/root/.ollama &lt;span class="nt"&gt;-p&lt;/span&gt; 11434:11434 &lt;span class="nt"&gt;--name&lt;/span&gt; ollama &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;HSA_OVERRIDE_GFX_VERSION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;10.3.0 &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;HCC_AMDGPU_TARGET&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;gfx1030 ollama/ollama:rocm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;[!info] &lt;br&gt;
If you run LLMs that are bigger than your GPUs memory, then they will be loaded partially on the GPU memory and RAM memory. This will cause a slow response time in your prompts.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  Running Ollama on CPU Only (Not Recommended)
&lt;/h3&gt;

&lt;p&gt;If you run the ollama image with the command below, you will start the Ollama on your computer memory and CPU.&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;-v&lt;/span&gt; ollama:/root/.ollama &lt;span class="nt"&gt;-p&lt;/span&gt; 11434:11434 &lt;span class="nt"&gt;--name&lt;/span&gt; ollama ollama/ollama
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;[!warning] &lt;br&gt;
This is not recommended if you have a dedicated GPU since running LLMs on with this way will consume your computer memory and CPU. &lt;/p&gt;

&lt;p&gt;Also running LLMs on the CPU are much slower than GPUs.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  Verifying Installation
&lt;/h3&gt;

&lt;p&gt;After you have deployed the Ollama container, you can manually check if the Ollama server is running successfully.&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;ollama ollama list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;You won't see any LLM in the list because we haven't downloaded any.&lt;/p&gt;
&lt;h2&gt;
  
  
  Deploying Web UI
&lt;/h2&gt;

&lt;p&gt;We will deploy the Open WebUI and then start using the Ollama from our web browser.&lt;/p&gt;

&lt;p&gt;Since our Ollama container listens on the host TCP 11434 port, we will run our Open WebUI like 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 run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;--network&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;host &lt;span class="nt"&gt;-v&lt;/span&gt; open-webui:/app/backend/data &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;OLLAMA_BASE_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;http://127.0.0.1:11434 &lt;span class="nt"&gt;--name&lt;/span&gt; open-webui &lt;span class="nt"&gt;--restart&lt;/span&gt; always ghcr.io/open-webui/open-webui:main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;After the container is up, you can head to your browser and hit the &lt;a href="http://localhost:8080" rel="noopener noreferrer"&gt;http://localhost:8080&lt;/a&gt; if Open WebUI is running on your own computer. If it's on another computer, you can use &lt;a href="http://ip-address-or-domain:8080" rel="noopener noreferrer"&gt;http://ip-address-or-domain:8080&lt;/a&gt; to access Open WebUI from browser.&lt;/p&gt;
&lt;h2&gt;
  
  
  Pulling LLM AI Models
&lt;/h2&gt;

&lt;p&gt;Ollama provides LLMs ready to use with Ollama server. To view all the models, you can head to &lt;a href="https://ollama.com/library" rel="noopener noreferrer"&gt;Ollama Library&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Since my GPU has 12GB memory, I run these models:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Name: &lt;code&gt;deepseek-coder:6.7b-instruct-q8_0&lt;/code&gt; , Size: &lt;code&gt;7.2GB&lt;/code&gt;:  I use that LLM most of the time for my coding requirements.&lt;/li&gt;
&lt;li&gt;Name: &lt;code&gt;llama3:8b-instruct-q8_0&lt;/code&gt; , Size: &lt;code&gt;8.5 GB&lt;/code&gt;:  I use that LLM to chat if I am writing emails or etc.&lt;/li&gt;
&lt;li&gt;Name: &lt;code&gt;deepseek-coder:33b-instruct-q4_0&lt;/code&gt; , Size: &lt;code&gt;18 GB&lt;/code&gt;:  I use that LLM for challenging coding requirements.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can paste the LLM name into the red box to pull the LLM image.&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%2Fcg9w1x04t7z81hls2gfd.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%2Fcg9w1x04t7z81hls2gfd.png" alt="Pulling the First AI Model" width="800" height="473"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Performance
&lt;/h2&gt;

&lt;p&gt;If you want to see how the AI is performing, you can check the &lt;code&gt;i&lt;/code&gt; button of response messages from AI.&lt;/p&gt;

&lt;p&gt;At the first message to an LLM, it will take a couple of seconds to load your selected model.&lt;br&gt;
As you can see below, the LLM took 9 seconds to get loaded. Then answered in 1 second.&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%2Fzunocvo2ququv3j1m61z.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%2Fzunocvo2ququv3j1m61z.png" alt="First response performance" width="800" height="473"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The messages after the first one doesn't took that &lt;code&gt;load&lt;/code&gt; time. &lt;/p&gt;

&lt;p&gt;As you can see below, it started to response after 0.5 seconds and all the answer took 7.7 seconds.&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%2Fx6a64m55pud1ejrz71lm.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%2Fx6a64m55pud1ejrz71lm.png" alt="Chat performance" width="800" height="472"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also you can check your GPU statics if you want to be sure about where the LLM is running.&lt;/p&gt;

&lt;p&gt;For the AMD GPUs, you can use &lt;a href="https://github.com/clbr/radeontop" rel="noopener noreferrer"&gt;radeontop&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For Nvidia GPUs, you can use nvidia-smi.&lt;/p&gt;

&lt;p&gt;This is my &lt;code&gt;radeontop&lt;/code&gt; command outputs while a prompt is running:&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%2Fi7coohekazrb5i07tjre.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%2Fi7coohekazrb5i07tjre.png" alt="radeontop output" width="800" height="503"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  For More
&lt;/h2&gt;

&lt;p&gt;If you want to use the deployed Ollama server as your free and private Copilot/Cursor alternative, you can also read the next post in the series!&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/berk" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&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%2Fuser%2Fprofile_image%2F995825%2Fe3ae8ac8-918c-42c2-baa2-615f01ec715b.jpg" alt="berk"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/berk/streamline-code-writing-with-free-self-hosted-private-free-copilot-5230" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Free, Self-Hosted &amp;amp; Private Copilot to Streamline Coding&lt;/h2&gt;
      &lt;h3&gt;Berk ・ Aug 31 '24&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#githubcopilot&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#ai&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#llm&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#cursor&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;



&lt;p&gt;If you like the post, you can head to my personal blog site and read more about DevOps, Linux, system engineering, and self-hosted applications for homelab!&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
        &lt;div class="c-embed__cover"&gt;
          &lt;a href="https://burakberk.dev/" class="c-link align-middle" rel="noopener noreferrer"&gt;
            &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fburakberk.dev%2Fcontent%2Fimages%2F2024%2F09%2Fwallpaperflare-cropped--1-.jpg" height="449" class="m-0" width="800"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="c-embed__body"&gt;
        &lt;h2 class="fs-xl lh-tight"&gt;
          &lt;a href="https://burakberk.dev/" rel="noopener noreferrer" class="c-link"&gt;
            Burak Berk Keskin
          &lt;/a&gt;
        &lt;/h2&gt;
          &lt;p class="truncate-at-3"&gt;
            Blog of a DevOps &amp;amp; System Engineer
          &lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    &amp;lt;div class="color-secondary fs-s flex items-center"&amp;gt;
        &amp;lt;img
          alt="favicon"
          class="c-embed__favicon m-0 mr-2 radius-0"
          src="https://burakberk.dev/content/images/size/w256h256/2024/02/website-logo2.jpeg"
          loading="lazy" /&amp;gt;
      burakberk.dev
    &amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;/div&gt;
&lt;br&gt;
 
&lt;/div&gt;
&lt;/div&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>tutorial</category>
      <category>productivity</category>
    </item>
    <item>
      <title>How to Create VPC and EC2 on AWS for Free Tier With Terraform</title>
      <dc:creator>Berk</dc:creator>
      <pubDate>Wed, 03 Apr 2024 19:58:38 +0000</pubDate>
      <link>https://dev.to/berk/how-to-create-vpc-and-ec2-on-aws-for-free-tier-with-terraform-4d70</link>
      <guid>https://dev.to/berk/how-to-create-vpc-and-ec2-on-aws-for-free-tier-with-terraform-4d70</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;In this post, you will learn how to deploy resources to AWS without exceeding the free limits with Terraform.&lt;/p&gt;

&lt;p&gt;Once you follow this tutorial, you will have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A VPC with &lt;code&gt;10.10.0.0/16&lt;/code&gt; CIDR,&lt;/li&gt;
&lt;li&gt;A public subnet with &lt;code&gt;10.10.20.0/24&lt;/code&gt; CIDR on &lt;code&gt;eu-central-1a&lt;/code&gt; AZ,

&lt;ul&gt;
&lt;li&gt;A public subnet with &lt;code&gt;10.10.40.0/24&lt;/code&gt; CIDR on &lt;code&gt;eu-central-1b&lt;/code&gt; AZ,&lt;/li&gt;
&lt;li&gt;A private subnet with &lt;code&gt;10.10.21.0/24&lt;/code&gt; CIDR on &lt;code&gt;eu-central-1a&lt;/code&gt; AZ,&lt;/li&gt;
&lt;li&gt;A private subnet with &lt;code&gt;10.10.41.0/24&lt;/code&gt; CIDR on &lt;code&gt;eu-central-1b&lt;/code&gt; AZ,&lt;/li&gt;
&lt;li&gt;Security groups for SSH, HTTP(S) for ingress and all for egress,&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;A Public Elastic IP,&lt;/li&gt;

&lt;li&gt;An Ec2 Instance,

&lt;ul&gt;
&lt;li&gt;Ubuntu Linux &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;t2.micro&lt;/code&gt; type,&lt;/li&gt;
&lt;li&gt;25GB storage,&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;All these resources are free if you are on AWS free tier!&lt;/p&gt;

&lt;p&gt;You can see an example diagram of the resources.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fgmbvchxb8zi4eem8gp7y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fgmbvchxb8zi4eem8gp7y.png" width="800" height="453"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Pre-Requirements
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;An AWS account.&lt;/li&gt;
&lt;li&gt;A Linux or macOS computer to run Terraform.&lt;/li&gt;
&lt;li&gt;Git&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Install Terraform
&lt;/h2&gt;

&lt;p&gt;You can skip this section if you already have Terraform installed on your computer.&lt;/p&gt;

&lt;p&gt;If you are reading this tutorial, you know what Terraform is. Terraform is an open-source Infrastructure as Code (IaC) tool that enables users to define and provision infrastructure efficiently across various cloud providers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Installation on MacOS
&lt;/h3&gt;

&lt;p&gt;If you have &lt;code&gt;Homebrew&lt;/code&gt; installed on your computer, you can use &lt;code&gt;brew&lt;/code&gt; to install Terraform.&lt;br&gt;&lt;br&gt;
Open a terminal and run these commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew tap hashicorp/tap &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
brew &lt;span class="nb"&gt;install &lt;/span&gt;hashicorp/tap/terraform
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Once the installation is finished, you can check the Terraform version and verify the installation.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Installation on Windows
&lt;/h3&gt;

&lt;p&gt;You can head to the official &lt;a href="https://developer.hashicorp.com/terraform/install#windows" rel="noopener noreferrer"&gt;Terraform installation document&lt;/a&gt; and download the latest Terraform version.&lt;/p&gt;

&lt;p&gt;But my recommendation is to use Linux with WSL.&lt;/p&gt;
&lt;h3&gt;
  
  
  Installation on Linux
&lt;/h3&gt;

&lt;p&gt;You can head to the official &lt;a href="https://developer.hashicorp.com/terraform/install#linux" rel="noopener noreferrer"&gt;Terraform installation document&lt;/a&gt; and click on the tab for your distro.&lt;/p&gt;

&lt;p&gt;If you are using Arch Linux and have &lt;code&gt;yay&lt;/code&gt; tool installed , you can simply install Terraform with the commands below.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yay &lt;span class="nt"&gt;-S&lt;/span&gt; terraform
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Create an AWS Service Account for Terraform
&lt;/h2&gt;

&lt;p&gt;If you have a service account for the terraform, you can skip this step. &lt;/p&gt;

&lt;p&gt;To create a service account, you can follow the tutorial below step by step. &lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://burakberk.dev/how-to-create-a-service-account-on-aws-for-terraform/" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fburakberk.dev%2Fcontent%2Fimages%2F2024%2F03%2FTerraform-Service-Account.png" height="800" class="m-0" width="800"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://burakberk.dev/how-to-create-a-service-account-on-aws-for-terraform/" rel="noopener noreferrer" class="c-link"&gt;
          Creating a Service Account on AWS For Terraform
        &lt;/a&gt;
      &lt;/h2&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fburakberk.dev%2Fcontent%2Fimages%2Fsize%2Fw256h256%2F2024%2F02%2Fwebsite-logo2.jpeg" width="60" height="60"&gt;
        burakberk.dev
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;



&lt;h2&gt;
  
  
  Create an SSH Key For Linux Server Authentication
&lt;/h2&gt;

&lt;p&gt;You can skip this section if you already have an SSH key to use on a Linux server.&lt;/p&gt;

&lt;p&gt;To enhance Linux server security, generate an SSH key pair using the &lt;code&gt;ssh-keygen&lt;/code&gt; command, enabling secure authentication by pairing a private key on the client with the server's authorized public key.&lt;/p&gt;

&lt;p&gt;A SSH key pair consists of 2 files, public and private. You should keep the private one safe and secure. You can think that a private file opens the locks. You should use the public one to lock something like a Linux server.&lt;/p&gt;

&lt;p&gt;In summer, we will use a public key to lock our server SSH on our Terraform configuration. After the server is up and running, we will use the private one to connect to the server.&lt;/p&gt;

&lt;p&gt;To create a SSH key pair, you can use this command on your macOS or Linux computer.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-f ~/.ssh/aws-ec2&lt;/code&gt;: The file path and name where you want to create the key pair.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-C "contact@burakberk.dev"&lt;/code&gt;: The comment can be anything.&lt;/li&gt;
&lt;li&gt;Once you run the command below, it will ask you to enter a passphrase. This is password protection for the private file. You should use a secure and strong password.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh-keygen &lt;span class="nt"&gt;-t&lt;/span&gt; ed25519 &lt;span class="nt"&gt;-f&lt;/span&gt; ~/.ssh/aws-ec2 &lt;span class="nt"&gt;-C&lt;/span&gt; &lt;span class="s2"&gt;"contact@burakberk.dev"&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;To view the private file that we will use to connect to the server, you can run:&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;cat&lt;/span&gt; ~/.ssh/aws-ec2 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;To view the public file that we will use on Terraform, you can run:&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;cat&lt;/span&gt; ~/.ssh/aws-ec2.pub
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Create AWS Credentials Environment Variables
&lt;/h2&gt;

&lt;p&gt;Since Terraform must be authenticated to your AWS account, we will use the access keys we created earlier.&lt;/p&gt;

&lt;p&gt;There are multiple ways to use those keys. But in this tutorial, I will use the environment variables method, which is unsafe for the long term.&lt;br&gt;&lt;br&gt;
For more details about AWS authentication, you can read the &lt;a href="https://registry.terraform.io/providers/hashicorp/aws/latest/docs" rel="noopener noreferrer"&gt;AWS Terraform documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We could run the &lt;code&gt;export&lt;/code&gt; command below directly, but this will save the secret access keys in the shell history, which is very unsafe. So we will create a file and put the keys into it.&lt;/p&gt;

&lt;p&gt;Create a file named &lt;code&gt;terraform-aws.sh&lt;/code&gt; with &lt;code&gt;vim&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vim terraform-aws.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Copy this template and paste it into the file.&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="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;AWS_ACCESS_KEY_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;YourAccessKeyId
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;AWS_SECRET_ACCESS_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;YourSecretAccessKey
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Press the &lt;code&gt;i&lt;/code&gt; button, move the cursor with the arrow buttons on your keyboard, and edit the &lt;code&gt;AWS_ACCESS_KEY_ID&lt;/code&gt; and &lt;code&gt;AWS_SECRET_ACCESS_KEY&lt;/code&gt; variables with yours.&lt;/p&gt;

&lt;p&gt;Press &lt;code&gt;esc&lt;/code&gt;, &lt;code&gt;colon (:)&lt;/code&gt; and write &lt;code&gt;wq!&lt;/code&gt; and hit &lt;code&gt;enter&lt;/code&gt; on your keyboard to save the changes and exit the editor.&lt;/p&gt;

&lt;p&gt;❗Keep this file safe and secure. Whoever gets access to the file controls all resources on your AWS account.&lt;/p&gt;

&lt;p&gt;Now you can use this file to use your keys.&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;source &lt;/span&gt;terraform-aws.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;📚Note: If you close your terminal or open a new one, you should run the &lt;code&gt;source&lt;/code&gt; command each time before running &lt;code&gt;terraform&lt;/code&gt; commands.&lt;br&gt;&lt;br&gt;
If your AWS variables get lost and you run &lt;code&gt;terraform&lt;/code&gt; commands, you will get an error, like in the example below:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Planning failed. Terraform encountered an error while generating this plan.

Error: configuring Terraform AWS Provider: no valid credential sources for Terraform AWS Provider found.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Download the Sample Terraform Files From Github
&lt;/h2&gt;

&lt;p&gt;You should create a couple of files. Instead of creating them manually, you can just download them from the Github repository.&lt;/p&gt;

&lt;p&gt;Open a terminal and change the directory to the home directory. You can choose anywhere you want.&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; &lt;span class="nv"&gt;$HOME&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Then you can download the Terraform files from the Github repository.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone &lt;span class="nt"&gt;--depth&lt;/span&gt; 1 &lt;span class="nt"&gt;--branch&lt;/span&gt; blog-tutorial https://github.com/burakberkkeskin/personal_infra.git &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\ &lt;/span&gt;
&lt;span class="nb"&gt;cd &lt;/span&gt;personal_infra/main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Once the download is finished and you are in the Terraform configuration directory, you can run &lt;code&gt;terraform init&lt;/code&gt; to see if Terraform configuration is ready to be used.&lt;/p&gt;

&lt;p&gt;❗Be aware that you are in the &lt;code&gt;personal_infra/main&lt;/code&gt; directory. The &lt;code&gt;terraform&lt;/code&gt; commands below should also run in this directory too.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Configure and Customize Terraform Variables
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Add the SSH Key
&lt;/h3&gt;

&lt;p&gt;Print the public key you created earlier and copy it.&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;cat&lt;/span&gt; ~/.ssh/aws-ec2.pub
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Open the &lt;code&gt;variables.auto.tfvars&lt;/code&gt; file with a file editor.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vim variables.auto.tfvars
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Press the &lt;code&gt;i&lt;/code&gt; button, move to a new line with the arrow buttons on your keyboard, and create a new variable named &lt;code&gt;ec2_public_key&lt;/code&gt; like in the example below:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight terraform"&gt;&lt;code&gt;&lt;span class="c1"&gt;// general variables&lt;/span&gt;
 &lt;span class="nx"&gt;project_name&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"main"&lt;/span&gt;
 &lt;span class="nx"&gt;aws_region&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"eu-central-1"&lt;/span&gt;
 &lt;span class="nx"&gt;aws_zone&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"eu-central-1a"&lt;/span&gt;

 &lt;span class="nx"&gt;ec2_public_key&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ssh-ed25519 SuperSecretKeylZDI1NTE5AAAAINa3hu5qHgD3cS7dxMlO6I3dTTx/AFU5HqhNZnM6rnEJ contact@burakberk.dev"&lt;/span&gt;

 &lt;span class="err"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Press &lt;code&gt;esc&lt;/code&gt;, &lt;code&gt;colon (:)&lt;/code&gt; and write &lt;code&gt;wq!&lt;/code&gt; and hit &lt;code&gt;enter&lt;/code&gt; on your keyboard to save the changes and exit the editor.&lt;/p&gt;

&lt;p&gt;You can also configure other variables as you wish, like the &lt;code&gt;aws_region&lt;/code&gt;, &lt;code&gt;project_name&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Terraform Plan
&lt;/h2&gt;

&lt;p&gt;To see if everything is ready to use, you can run &lt;code&gt;terraform plan&lt;/code&gt; command to see the resources that will be created.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform plan
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;If you see that there are resources that will be created as a plan, it means you have configured terraform correctly ✅&lt;/p&gt;
&lt;h2&gt;
  
  
  Terraform Apply
&lt;/h2&gt;

&lt;p&gt;Once you are ready to create the resources you saw in the &lt;code&gt;terraform plan&lt;/code&gt; output, you can run &lt;code&gt;terraform apply&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;terraform apply
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;It will ask you to be sure.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only &lt;span class="s1"&gt;'yes'&lt;/span&gt; will be accepted to approve.

  Enter a value:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Write &lt;code&gt;yes&lt;/code&gt; and hit enter. Within a few minutes, your resources will be ready to use.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Apply &lt;span class="nb"&gt;complete&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt; Resources: 23 added, 0 changed, 0 destroyed.

Outputs:
ec2_instance_private_ip &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"10.10.20.136"&lt;/span&gt;
ec2_instance_public_ip &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"35.158.26.83"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;To check from the AWS Console, you can head to the EC2 instance. You can also see the IP address of the instance.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fk0rm8214b7u8qmnx0c3r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fk0rm8214b7u8qmnx0c3r.png" width="800" height="482"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ta da 🥳 Your Ubuntu Linux server is ready to use.&lt;/p&gt;
&lt;h2&gt;
  
  
  SSH Into the Server For Testing
&lt;/h2&gt;

&lt;p&gt;You have already seen the IP address of the instance. To connect, you can open a terminal and run &lt;code&gt;ssh&lt;/code&gt; command:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-i ~/.ssh/safaws&lt;/code&gt;: The path to the private SSH key.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ubuntu&lt;/code&gt;: Default username of the Ubuntu AMI on the AWS.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;35.158.26.83&lt;/code&gt;: Public IPv4 address.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh &lt;span class="nt"&gt;-i&lt;/span&gt; ~/.ssh/safaws ubuntu@35.158.26.83
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;If it is the first time that you are connecting to a server, it will ask if you are sure to connect. Write &lt;code&gt;yes&lt;/code&gt; enter hit Enter.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Are you sure you want to &lt;span class="k"&gt;continue &lt;/span&gt;connecting &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;yes&lt;/span&gt;/no/[fingerprint]&lt;span class="o"&gt;)&lt;/span&gt;? &lt;span class="nb"&gt;yes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;If you have followed the tutorial until now, congratulations, You are on the Linux server!&lt;/p&gt;

&lt;p&gt;You can use this server however you like. For example, you can host a website, make it a VPN server, a database server, or anything else you want.&lt;/p&gt;
&lt;h2&gt;
  
  
  Example Nginx Container
&lt;/h2&gt;

&lt;p&gt;In this step, you will see how to deploy a nginx container. The docker should be already installed in the instance. All you need to do is run the &lt;code&gt;docker run&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;Let's run a  Nginx container.&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;sudo &lt;/span&gt;docker run &lt;span class="nt"&gt;--name&lt;/span&gt; &lt;span class="s2"&gt;"website"&lt;/span&gt; &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s2"&gt;"80:80"&lt;/span&gt; nginx 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;To test if everything works, you can simple open a browser and head to the public IPv4 address like:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://35.158.26.83
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Destroying the All Resources
&lt;/h2&gt;

&lt;p&gt;If you want to destroy all the resources for some reason, like the end of the free tier, you can destroy all resources easily.&lt;/p&gt;

&lt;p&gt;First, you should change the directory to the Terraform you downloaded earlier.&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; ~/personal_infra/main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;You should activate the AWS keys again for authentication.&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;source &lt;/span&gt;terraform-aws.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now, it is time to destroy all resources.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform destroy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;It will ask you to be sure. Write &lt;code&gt;yes&lt;/code&gt; and hit Enter.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Do you really want to destroy all resources?
  Terraform will destroy all your managed infrastructure, as shown above.
  There is no undo. Only &lt;span class="s1"&gt;'yes'&lt;/span&gt; will be accepted to confirm.

  Enter a value: &lt;span class="nb"&gt;yes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Once all resources are destroyed, you will see an output like below.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Destroy &lt;span class="nb"&gt;complete&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt; Resources: 23 destroyed.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Re-Use on Another Account
&lt;/h2&gt;

&lt;p&gt;If you want to use the exact same configuration, you can just change the AWS access keys in the &lt;code&gt;terraform-aws.sh.&lt;/code&gt; file and apply the same configuration. With that, you can change AWS accounts under 10 minutes!&lt;/p&gt;
&lt;h2&gt;
  
  
  For More
&lt;/h2&gt;

&lt;p&gt;If you like the post, you can head to my personal blog site and read more about DevOps, Linux, System Engineering!&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://burakberk.dev/" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fburakberk.dev%2Fcontent%2Fimages%2F2024%2F09%2Fwallpaperflare-cropped--1-.jpg" height="449" class="m-0" width="800"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://burakberk.dev/" rel="noopener noreferrer" class="c-link"&gt;
          Burak Berk Keskin
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          Blog of a DevOps &amp;amp; System Engineer
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fburakberk.dev%2Fcontent%2Fimages%2Fsize%2Fw256h256%2F2024%2F02%2Fwebsite-logo2.jpeg" width="60" height="60"&gt;
        burakberk.dev
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;



</description>
      <category>aws</category>
      <category>terraform</category>
      <category>cloud</category>
      <category>instance</category>
    </item>
    <item>
      <title>Creating a Service Account on AWS For Terraform</title>
      <dc:creator>Berk</dc:creator>
      <pubDate>Sun, 03 Mar 2024 10:31:52 +0000</pubDate>
      <link>https://dev.to/berk/creating-a-service-account-on-aws-for-terraform-3lhd</link>
      <guid>https://dev.to/berk/creating-a-service-account-on-aws-for-terraform-3lhd</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;For Terraform to create resources on your AWS account, it should get some access keys to authenticate to your account. In this step, we will create a service account for Terraform to use.&lt;/p&gt;

&lt;p&gt;We will create an admin user group, then create a Terraform user and add it to the admin group. Then create access keys for the Terraform user. You can follow the steps below to create them all.&lt;/p&gt;

&lt;p&gt;When you are in the AWS Console, search for the IAM service.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fszc2ib3m139lasyx07sw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fszc2ib3m139lasyx07sw.png" width="800" height="482"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Head to "User groups" and click on the "Create group" button.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fxjayu575u6edywdbiuzd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fxjayu575u6edywdbiuzd.png" width="800" height="481"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Enter your group name, search for &lt;code&gt;administratorAccess&lt;/code&gt; and select it, and hit the "Create group" button.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fyfe55s7gc9knqh281epj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fyfe55s7gc9knqh281epj.png" width="800" height="482"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on the "Users" menu, then click the "Create user" button to create a user for Terraform.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fym2d3s1ke5u97e1gsntl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fym2d3s1ke5u97e1gsntl.png" width="800" height="482"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Enter the "User name" and hit the "Next" button.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F74xho52h9xl6cepldkdc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F74xho52h9xl6cepldkdc.png" width="800" height="481"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Add the new user to the group previously created. So the user will have "Administrator Access" permissions.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F4pa2jxtr7iwa9syf725k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F4pa2jxtr7iwa9syf725k.png" width="800" height="482"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Review the user and hit "Create user" to continue.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fk9zrg3pi2s979ndmhscl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fk9zrg3pi2s979ndmhscl.png" width="800" height="481"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To create a access keys for the new user, hit the username.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fyb8xage1txnwqovcf641.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fyb8xage1txnwqovcf641.png" width="800" height="482"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Change the tab to "Security credentials" and hit the "Create access key" button.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fn488xjesuk2rxl1eb658.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fn488xjesuk2rxl1eb658.png" width="800" height="481"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Change the "Other" type and hit the "Next" button.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Feoo8dgq5a9gb4owz9czo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Feoo8dgq5a9gb4owz9czo.png" width="800" height="482"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can write a description of why you have created this access key. Hit the "Create access key" button to continue.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F6nw2yxy159v0bqo60f08.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F6nw2yxy159v0bqo60f08.png" width="800" height="481"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now you can see the access keys. Copy both of them and paste them somewhere else securely. Hit "Done" to continue.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fpbim46iku5ktrn3e4sm4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fpbim46iku5ktrn3e4sm4.png" width="800" height="482"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can use those keys in the Terraform configuration.&lt;/p&gt;

&lt;p&gt;❗Keep these access keys safe and secure. Whoever gets access to the keys controls all resources on your AWS account.&lt;/p&gt;

&lt;p&gt;If you enjoyed this DevOps article and crave more insights into System Administration, visit my blog for additional resources and tutorials. Thank you for exploring the world of efficient software development with me, and stay tuned for more on my blog!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://burakberk.dev" rel="noopener noreferrer"&gt;https://burakberk.dev&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Creating Fullchain Self Signed SSL With 3 Commands</title>
      <dc:creator>Berk</dc:creator>
      <pubDate>Thu, 21 Dec 2023 09:38:19 +0000</pubDate>
      <link>https://dev.to/berk/creating-fullchain-self-signed-ssl-with-3-commands-1i0i</link>
      <guid>https://dev.to/berk/creating-fullchain-self-signed-ssl-with-3-commands-1i0i</guid>
      <description>&lt;h2&gt;
  
  
   Overview
&lt;/h2&gt;

&lt;p&gt;I wrote about how to create a fullchain ssl certificate manually in a previous post. Today, I will show you how you can create fullchain ssl cert with only 3 commands. &lt;/p&gt;

&lt;p&gt;We will use a tool named crtforge which is free and open-source application that you can find on &lt;a href="https://github.com/safderun/crtforge" rel="noopener noreferrer"&gt;Github&lt;/a&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
   Install &lt;code&gt;crtforge&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;To install &lt;code&gt;crtforge&lt;/code&gt;, you need Linux or macOS. You can also use the &lt;code&gt;crtforge&lt;/code&gt; on Windows with wsl.&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;sudo &lt;/span&gt;curl &lt;span class="nt"&gt;-L&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /usr/bin/crtforge https://github.com/burakberkkeskin/crtForge/releases/latest/download/crtforge-&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;uname&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;-&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;uname&lt;/span&gt; &lt;span class="nt"&gt;-m&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nb"&gt;sudo chmod&lt;/span&gt; +x /usr/bin/crtforge
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These two command will install crtforge binary to your system.&lt;/p&gt;

&lt;h2&gt;
  
  
   Create a fullchain cert.
&lt;/h2&gt;

&lt;p&gt;You can directly run &lt;code&gt;crtforge&lt;/code&gt; with a appname and domains that app needs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;crtforge websiteApp myapp.com app.myapp.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Congratulations 🎉, you will have your fullchain with 3 commands in total.&lt;/p&gt;

&lt;p&gt;You can get the certs from the &lt;code&gt;$HOME/.config/crtforge/default/websiteApp&lt;/code&gt; directory. &lt;/p&gt;

&lt;p&gt;For detailed usage like custom root CA, custom intermediate CA and trusting the root CAs, you can check the readme of the &lt;a href="https://github.com/safderun/crtForge" rel="noopener noreferrer"&gt;repository&lt;/a&gt;. &lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to Test SMTP Settings under 5 Minutes</title>
      <dc:creator>Berk</dc:creator>
      <pubDate>Thu, 21 Dec 2023 09:35:42 +0000</pubDate>
      <link>https://dev.to/berk/how-to-test-smtp-settings-under-5-minutes-1p07</link>
      <guid>https://dev.to/berk/how-to-test-smtp-settings-under-5-minutes-1p07</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;In this tutorial, you will see how to test SMTP settings with a tool named &lt;code&gt;gomtp&lt;/code&gt; on Linux and macOS cli.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;gomtp&lt;/code&gt; is a open-source and free software to test SMTP settings. You can see the source code on the &lt;a href="https://github.com/safderun/gomtp" rel="noopener noreferrer"&gt;Github page&lt;/a&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Install the &lt;code&gt;gomtp&lt;/code&gt; tool.&lt;/li&gt;
&lt;li&gt;Configure the SMTP settings.&lt;/li&gt;
&lt;li&gt;Test the configuration.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Install gomtp
&lt;/h2&gt;

&lt;p&gt;To install the &lt;code&gt;gomtp&lt;/code&gt;, you can simply run the command below:&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;sudo &lt;/span&gt;curl &lt;span class="nt"&gt;-L&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /usr/local/bin/gomtp &lt;span class="s2"&gt;"https://github.com/burakberkkeskin/gomtp/releases/latest/download/gomtp-&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;uname&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;-&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;uname&lt;/span&gt; &lt;span class="nt"&gt;-m&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nb"&gt;sudo chmod&lt;/span&gt; +x /usr/local/bin/gomtp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  SMTP configuration.
&lt;/h2&gt;

&lt;p&gt;To test SMTP settings, you first need to configure a yaml file.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a file named &lt;code&gt;gomtp.yaml&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vim gomtp.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;❗The file name must be &lt;code&gt;gomtp.yaml&lt;/code&gt; by default.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Configure the SMTP settings for your needs.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;##### Gmail Example #####&lt;/span&gt;
 &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;from@gmail.com'&lt;/span&gt;
 &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;appPassword'&lt;/span&gt;
 &lt;span class="na"&gt;from&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;from@gmail.com'&lt;/span&gt;
 &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;to@example.com'&lt;/span&gt;
 &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;smtp.gmail.com'&lt;/span&gt;
 &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;587&lt;/span&gt;
 &lt;span class="na"&gt;ssl&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
 &lt;span class="na"&gt;tls&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
 &lt;span class="na"&gt;auth&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;LOGIN'&lt;/span&gt;
 &lt;span class="na"&gt;subject&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Testing&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Email'&lt;/span&gt;
 &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
   &lt;span class="s"&gt;this is line 1&lt;/span&gt;
   &lt;span class="s"&gt;This is line 2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ℹ You can find some other example configurations under &lt;a href="https://github.com/safderun/gomtp/blob/master/gomtp.yml" rel="noopener noreferrer"&gt;the repository&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test the Configuration
&lt;/h2&gt;

&lt;p&gt;Now it's time to test the configuration.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Be sure that you are in the same directory with the &lt;code&gt;gomtp.yaml&lt;/code&gt; file you have just created previously.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Run the &lt;code&gt;gomtp&lt;/code&gt; directly with no argument.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gomtp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;If the configuration is valid, you will see this output.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;gomtp
Email sent successfully!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;If the configuration is invalid, you will see an error message that describe the problem.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;gomtp
2023/12/21 11:44:33 535 5.7.8 Error: authentication failed: Invalid user or password! 1703148273-WiJ7lX77XKo0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>smtp</category>
      <category>go</category>
      <category>testing</category>
      <category>mail</category>
    </item>
  </channel>
</rss>
