<?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>Forem: Mr Shanas</title>
    <description>The latest articles on Forem by Mr Shanas (@mrshanas).</description>
    <link>https://forem.com/mrshanas</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%2F824336%2Fe3783648-4833-4636-88c3-e5c1e94b0fe3.jpg</url>
      <title>Forem: Mr Shanas</title>
      <link>https://forem.com/mrshanas</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/mrshanas"/>
    <language>en</language>
    <item>
      <title>HTTPS on Docker Containers using Nginx and LetsEncrypt</title>
      <dc:creator>Mr Shanas</dc:creator>
      <pubDate>Sat, 21 Jan 2023 21:19:56 +0000</pubDate>
      <link>https://forem.com/mrshanas/https-on-docker-containers-using-nginx-and-letsencrypt-3nfa</link>
      <guid>https://forem.com/mrshanas/https-on-docker-containers-using-nginx-and-letsencrypt-3nfa</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;By default, when docker containers are deployed they run on normal HTTP but most times it's better to run web services using HTTPS which is a secure protocol over the internet. So we're going to see how to enable an SSL certificate on docker containers using &lt;a href="https://letsencrypt.org" rel="noopener noreferrer"&gt;LetsEncrypt&lt;/a&gt; and Certbot&lt;/p&gt;

&lt;h1&gt;
  
  
  Prerequisites
&lt;/h1&gt;

&lt;p&gt;Certbot requires a live domain for it to be assigned an SSL certificate to it, you can obtain a domain at your chosen registrar, In this article, I'll be using my own domain mrshanas.com. I've created a subdomain for it.&lt;/p&gt;

&lt;p&gt;Also, a virtual server is required with &lt;code&gt;docker&lt;/code&gt; and &lt;code&gt;docker-compose&lt;/code&gt; installed in it, I'm using Digitalocean droplets that have docker installed in it from the market place but you can use any of your choices but make sure the above-mentioned are installed&lt;/p&gt;

&lt;h1&gt;
  
  
  Getting Started
&lt;/h1&gt;

&lt;p&gt;Create a simple project with a &lt;code&gt;Dockerfile&lt;/code&gt; and &lt;code&gt;docker-compose.yaml&lt;/code&gt; files and a &lt;code&gt;config&lt;/code&gt; directory that contains an empty &lt;code&gt;nginx.conf&lt;/code&gt; .&lt;/p&gt;

&lt;h5&gt;
  
  
  &lt;strong&gt;&lt;em&gt;Dockerfile&lt;/em&gt;&lt;/strong&gt;
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM nginx:1.21.1-alpine
RUN rm /etc/nginx/conf.d/default.conf
COPY ./nginx.conf /etc/nginx/conf.d

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

&lt;/div&gt;



&lt;p&gt;The Dockerfile contains a script to pull the Nginx image, delete the default config file, and then copy the defined config file from our project&lt;/p&gt;

&lt;h5&gt;
  
  
  &lt;strong&gt;nginx.conf&lt;/strong&gt;
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;server {
    listen 80;
    listen [::]:80;

    server_name test.mrshanas.com;
    server_tokens off;

    location /.well-known/acme-challenge/ {
        allow all;
        root /tmp/acme-challenge;
    }

    location / {
        return 301 https://$host$request_uri;
    }
}

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

&lt;/div&gt;



&lt;p&gt;This will enable Nginx to run locally at HTTP, and listen on port 80, and all incoming requests will be redirected to https.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;the line &lt;code&gt;listen [::]:80&lt;/code&gt; means for IPv6 addresses.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Change the server name to the domain you want to enable the certificate. For me, it is &lt;code&gt;test.mrshanas.com&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Certbot makes a challenge to the server by making a request to the special URL &lt;code&gt;${your_domain}/.well-known/acme-challenge/&lt;/code&gt; so we want to enable it to access the URL and verify the challenge for it to generate the certificate&lt;/p&gt;

&lt;h5&gt;
  
  
  &lt;strong&gt;docker-compose.yml&lt;/strong&gt;
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version: "3"

services:
  nginx:
    container_name: "nginx_server"
    build:
      context: ./config
    ports:
      - 80:80
      - 443:443
    volumes:
      - ./config:/config
      - /etc/letsencrypt:/etc/letsencrypt:ro
      - /tmp/acme-challenge:/tmp/acme-challenge
    networks:
      - app
    restart: always

  letsencrypt:
    container_name: "certbot"
    image: certbot/certbot
    command: sh -c "certbot certonly --webroot -w /tmp/acme-challenge/ -d test.mrshanas.com --text --agree-tos --email shanas@mrshanas.com --rsa-key-size 4096 --verbose --keep-until-expiring --preferred-challenges=http"
    entrypoint: ""
    volumes:
      - "/etc/letsencrypt:/etc/letsencrypt"
      - "/tmp/acme-challenge:/tmp/acme-challenge"
    environment:
      - TERM=xterm

networks:
  app:
    driver: bridge

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

&lt;/div&gt;



&lt;p&gt;The above file defines two docker containers &lt;code&gt;nginx&lt;/code&gt; and &lt;code&gt;letsencrypt&lt;/code&gt; that will make the task successful.&lt;/p&gt;

&lt;h1&gt;
  
  
  Running Containers on HTTP
&lt;/h1&gt;

&lt;p&gt;The Nginx container is based on the &lt;code&gt;Dockerfile&lt;/code&gt; we created and exposes ports 80 and 443 and volumes that will contain the generated SSL certificates&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The certificates will be stored in &lt;code&gt;/etc/letsencrypt&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now run &lt;code&gt;docker-compose up --build nginx&lt;/code&gt; and visit your domain name and If it's successful you will see like below&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%2Fq0aqpc4ylspqoybdv2sp.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%2Fq0aqpc4ylspqoybdv2sp.png" width="359" height="35"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That means the container ran but it is not running on HTTPS, so let's see how to make it secure.&lt;/p&gt;

&lt;p&gt;The letsencrypt container pulls the certbot image from docker hub and runs the command &lt;code&gt;certbot certonly --webroot -w /tmp/acme-challenge/ -d test.mrshanas.com --text --agree-tos --email shanas@mrshanas.com --rsa-key-size 4096 --verbose --keep-until-expiring --preferred-challenges=http&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Make sure to replace the domain name with the one you want to configure SSL and the email with your email&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Generating SSL Certificates with certbot image
&lt;/h1&gt;

&lt;p&gt;Open a new terminal while the Nginx container is running and run &lt;code&gt;docker-compose up --build letsencrypt&lt;/code&gt; , If it's successful you will see the output below&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%2Fosbmqv36uugddlbxttp0.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%2Fosbmqv36uugddlbxttp0.png" width="800" height="337"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That means certbot was successful and generated certificates that are stored in the directory &lt;code&gt;etc/letsencrypt/live/&amp;lt;your_domain&amp;gt;&lt;/code&gt; .&lt;/p&gt;

&lt;h1&gt;
  
  
  Enabling HTTPS on the domain
&lt;/h1&gt;

&lt;p&gt;Add the following lines below the &lt;code&gt;server&lt;/code&gt; block in the &lt;code&gt;nginx.conf&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;server {
    listen 443 ssl;
    listen [::]:443 ssl http2;

    server_name test.mrshanas.com;

    ssl_certificate /etc/letsencrypt/live/test.mrshanas.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/test.mrshanas.com/privkey.pem;
}

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

&lt;/div&gt;



&lt;p&gt;Replace &lt;code&gt;test.mrshanas.com&lt;/code&gt; with your domain whose the certificate belongs to, and stop the Nginx container then rebuild it again with the command &lt;code&gt;docker-compose up --build -d nginx&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;-d&lt;/code&gt; flag means the container will run in detached mode&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If the above command was successful then navigate to your domain and you should see as below&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%2Fegv3qee9uf0sqt950d2n.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%2Fegv3qee9uf0sqt950d2n.png" width="204" height="31"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That means the process was successful and your domain is running on HTTPS.&lt;/p&gt;

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

&lt;p&gt;With the configuration, you can deploy your projects using Docker and make them run on HTTPS with ease. You can find the complete sample code in my &lt;a href="https://github.com/mrshanas/https-docker" rel="noopener noreferrer"&gt;GitHub repo&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>career</category>
      <category>discuss</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Custom File Uploader</title>
      <dc:creator>Mr Shanas</dc:creator>
      <pubDate>Sun, 15 Jan 2023 03:06:58 +0000</pubDate>
      <link>https://forem.com/mrshanas/custom-file-uploader-507c</link>
      <guid>https://forem.com/mrshanas/custom-file-uploader-507c</guid>
      <description>&lt;p&gt;Hello there it's 2023 and are you bored of the default tedious file input that &lt;em&gt;HTML&lt;/em&gt; offers?, well I want to share how you can create a custom file input using &lt;code&gt;HTML&lt;/code&gt; with little &lt;code&gt;TS&lt;/code&gt; 😅 oh sorry!! had you there, I meant &lt;code&gt;js&lt;/code&gt; .&lt;/p&gt;

&lt;p&gt;Firstly generate a plain HTML project and paste the code below&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;input type="file" name="" id="file-input" hidden /&amp;gt;

    &amp;lt;div
      class=""
      style="
        width: 200px;
        height: 200px;
        border: 1px dashed #aaa;
        margin: 0 auto;
        display: grid;
        place-items: center;
        cursor: pointer;
      "
    &amp;gt;
      &amp;lt;p style="color: #00f"&amp;gt;Click here to upload&amp;lt;/p&amp;gt;
    &amp;lt;/div&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;The HTML code above contains two tags, the &lt;code&gt;input&lt;/code&gt; tag is hidden because we don't want that but we'll use its functionality. The code will roughly be displayed as shown below(Don't mind my CSS 😅)&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%2Fazp6aqfqyw2a1jbipo8d.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%2Fazp6aqfqyw2a1jbipo8d.png" width="237" height="215"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now for the fun part let's see some &lt;code&gt;js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;     const fileInput = document.getElementById("file-input");
     const div = document.querySelector("div");

    div.addEventListener("click", () =&amp;gt; {
      fileInput.click();
    });

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

&lt;/div&gt;



&lt;p&gt;The code above retrieves the &lt;code&gt;input&lt;/code&gt; and &lt;code&gt;div&lt;/code&gt; elements using their id's and assigns an event listener to the &lt;code&gt;div&lt;/code&gt; element that when clicked it triggers the click event on the file input that allows your users to select any file for uploading, from here you can choose to do anything with the image.&lt;/p&gt;

</description>
      <category>rust</category>
      <category>learning</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
