<?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: Semir Teskeredzic</title>
    <description>The latest articles on DEV Community by Semir Teskeredzic (@semirteskeredzic).</description>
    <link>https://dev.to/semirteskeredzic</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%2F227326%2Fce260985-2009-45a1-b67a-ea97aee47bf2.jpeg</url>
      <title>DEV Community: Semir Teskeredzic</title>
      <link>https://dev.to/semirteskeredzic</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/semirteskeredzic"/>
    <language>en</language>
    <item>
      <title>Middleware Functions</title>
      <dc:creator>Semir Teskeredzic</dc:creator>
      <pubDate>Mon, 06 Dec 2021 08:13:01 +0000</pubDate>
      <link>https://dev.to/semirteskeredzic/middleware-functions-1hpo</link>
      <guid>https://dev.to/semirteskeredzic/middleware-functions-1hpo</guid>
      <description>&lt;p&gt;Hello all, in this post I will go through middleware functions, like the one used in NodeJS with ExpressJS. So let's start. Middleware is the code that runs on server between receiving a request and sending a response.&lt;/p&gt;

&lt;p&gt;According to &lt;a href="https://expressjs.com/"&gt;expressjs.com&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Middleware functions are functions that have access to the request object (req), the response object (res), and the next function in the application’s request-response cycle. The next function is a function in the Express router which, when invoked, executes the middleware succeeding the current middleware.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There are several tasks that middleware functions can perform:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Execute any code&lt;/li&gt;
&lt;li&gt;Make changes to the request and response objects&lt;/li&gt;
&lt;li&gt;End the request-response cycle.&lt;/li&gt;
&lt;li&gt;Call the next middleware in stack.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One thing that you should always remember is that middleware functions are executed from top to bottom. Which means that when one middleware function ends the cycle the rest of functions will not be executed.&lt;/p&gt;

&lt;h1&gt;
  
  
  When does middleware function end cycle?
&lt;/h1&gt;

&lt;p&gt;It ends when the middleware function runs but does not invoke next function so it stops after executing.&lt;br&gt;
It also ends the cycle when the response is sent to the browser. So if you have a GET with a route '/', every time someone visits that route, the request is received and the response is sent ending the cycle. All functions that are located below that function won't fire.&lt;br&gt;
It is important to mention that functions with &lt;code&gt;GET&lt;/code&gt; &lt;code&gt;POST&lt;/code&gt; requests will be executed only when a request from a specified route arrives.&lt;/p&gt;
&lt;h1&gt;
  
  
  Common usages for Middleware
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Log of all requests&lt;/li&gt;
&lt;li&gt;Auth check for protected routes&lt;/li&gt;
&lt;li&gt;Return 404 pages&lt;/li&gt;
&lt;li&gt;Parse JSON data from requests&lt;/li&gt;
&lt;li&gt;Expose folders or files&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;
  
  
  Examples
&lt;/h1&gt;
&lt;h2&gt;
  
  
  404 Pages
&lt;/h2&gt;

&lt;p&gt;In this example we will see how middleware function is used to display 404 page:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
app.listen(3000)

app.get('/', (req, res) =&amp;gt; {
  const homePage = [
    {title: 'Section One', text: 'This is the first section'},
    {title: 'Section Two', text: 'This is the second section'}
  ]
  res.render('index', {title: 'Home', homePage})
})

app.get('/about-us',(req, res) =&amp;gt; {
  res.render('about-us', {title: 'This is About us'})
}

app.get('/faq',(req, res) =&amp;gt; {
  res.render('faq', {title: 'These are Frequently asked questions'})
}

app.use((req, res) =&amp;gt; {
  res.status(404).render('404', {title: '404'})
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When user arrives to &lt;code&gt;/&lt;/code&gt; the response is sent and the cycle is stopped, and if request doesn't match any of the provided then it must be 404 page so we use middleware function with &lt;code&gt;.use&lt;/code&gt; to send a response. If we wan't it to be executed when no route is found then it must be at the bottom.&lt;/p&gt;

&lt;h2&gt;
  
  
  Logging requests
&lt;/h2&gt;

&lt;p&gt;We can log every request by placing a middleware function at the very top of our functions like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
app.listen(3000)

app.use((req, res) =&amp;gt; {
  console.log('Request')
  console.log('host: ', req.hostname)
  console.log('path: ', req.path)
  console.log('method: ', req.method)
}

app.get('/', (req, res) =&amp;gt; {
  const homePage = [
    {title: 'Section One', text: 'This is the first section'},
    {title: 'Section Two', text: 'This is the second section'}
  ]
  res.render('index', {title: 'Home', homePage})
})

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

&lt;/div&gt;



&lt;p&gt;When we run the application we will get the log when we visit any route. But it is not working right, currently it will 'freeze' so we won't get any content from any of our routes. This is due to the fact that the middleware function was executed and it stopped the cycle because it didn't invoke the next one. We can fix it by using &lt;code&gt;next()&lt;/code&gt;, we will just add it to existing function&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
app.use((req, res, next) =&amp;gt; {
  console.log('Request')
  console.log('host: ', req.hostname)
  console.log('path: ', req.path)
  console.log('method: ', req.method)
  next()
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now when we run our app, all routes are accessible and we get a log each time request has been received.&lt;/p&gt;

&lt;h2&gt;
  
  
  Expose Static files
&lt;/h2&gt;

&lt;p&gt;If need to use images, css files, or other assets we won't be able to access it from the browser. We can fix this with middleware function that will expose a folder where all our static files will be located. It is quite simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const express = require('express')

const app = express()

app.listen(3000)

app.use(express.static('public'))
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is it, we just need to create a &lt;code&gt;public&lt;/code&gt; folder in our root directory and put in all files that we need to have accessible by browser. If you do a &lt;code&gt;&amp;lt;link href="/..."&amp;gt;&lt;/code&gt; you don't need to include &lt;code&gt;public&lt;/code&gt; folder to the path since our code is looking automatically inside the &lt;code&gt;public&lt;/code&gt; folder.&lt;/p&gt;

&lt;p&gt;Hope you've learned something new and useful. &lt;br&gt;
Thank you for reading, stay safe and have a great day.&lt;/p&gt;

</description>
      <category>node</category>
      <category>javascript</category>
      <category>express</category>
      <category>middleware</category>
    </item>
    <item>
      <title>State &amp; DOM Manipulation with AlpineJS</title>
      <dc:creator>Semir Teskeredzic</dc:creator>
      <pubDate>Thu, 16 Sep 2021 19:07:48 +0000</pubDate>
      <link>https://dev.to/semirteskeredzic/state-dom-manipulation-with-alpinejs-3l4h</link>
      <guid>https://dev.to/semirteskeredzic/state-dom-manipulation-with-alpinejs-3l4h</guid>
      <description>&lt;p&gt;In my previous post I introduced this great lightweight JavaScript framework - AlpineJS. You can read about it &lt;a href="https://dev.to/semirteskeredzic/fancy-a-modern-alternative-to-jquery-meet-alpinejs-1lap"&gt;here&lt;/a&gt;. In this post I will go through some of the concepts that AlpineJS uses for state management and DOM manipulation.&lt;/p&gt;

&lt;h2&gt;
  
  
  State
&lt;/h2&gt;

&lt;p&gt;You can say that the State is the magic ingredient and I will agree with you, but essentially State is a data object that enables us to do many things on the frontend side. Alpine lets you provide data within specific &lt;code&gt;HTML&lt;/code&gt; element(s) or make it accessible from anywhere on your page. Let's start with the local one.&lt;/p&gt;

&lt;h3&gt;
  
  
  x-data
&lt;/h3&gt;

&lt;p&gt;This attribute is simple and straightforward, you declare it inside the &lt;code&gt;HTML&lt;/code&gt; element and the entire block has the access to it. In the example below &lt;code&gt;h1&lt;/code&gt; and &lt;code&gt;p&lt;/code&gt; will have no problem accessing toggle value and additionally if they depend on it, they will react automatically.&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;div x-data="{ toggle: true }"&amp;gt;
...
  &amp;lt;h1&amp;gt;&amp;lt;/h1&amp;gt;
  &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;
...
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also nest data and access parent data from the child. Let's see that in the example&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;div x-data="{ toggle: false }"&amp;gt;
  &amp;lt;div x-data="{ title: 'I am the title' }"&amp;gt;
    &amp;lt;h1 x-text="title"&amp;gt;&amp;lt;/h1&amp;gt;
    &amp;lt;p x-show="toggle"&amp;gt;Paragraph&amp;lt;/p&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Data can also be used within the same element, you can also pass only the &lt;code&gt;x-data&lt;/code&gt; directive without expression if you need to.&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;button x-data="{ label: 'Buy Now' }" x-text="label"&amp;gt;&amp;lt;/button&amp;gt;
&amp;lt;button x-data @click="alert('Button is clicked')"&amp;gt;Alert&amp;lt;/button&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Alpine.store(...)
&lt;/h3&gt;

&lt;p&gt;When you need your data to be available to every component on the page, you can use &lt;code&gt;Alpine.store&lt;/code&gt; that stands for global store on the page level. You are registering it with &lt;code&gt;Alpine.store(...)&lt;/code&gt; and referencing it with the &lt;code&gt;$store()&lt;/code&gt; method. First we will register the store:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Alpine.store('tabs', {
  current: 'overview',
  items: ['overview','description','specification'],
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can now access it or modify it anywhere on the page&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;div x-data&amp;gt;
  &amp;lt;template x-for="tab in $store.tabs.items"&amp;gt;
    ...
  &amp;lt;/template&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;div x-data&amp;gt;
  &amp;lt;button @click="$store.tabs.current = 'overview'"&amp;gt;Overview&amp;lt;/button&amp;gt;
  &amp;lt;button @click="$store.tabs.current = 'description'"&amp;gt;Description&amp;lt;/button&amp;gt;
  &amp;lt;button @click="$store.tabs.current = 'spoecification'"&amp;gt;Specification&amp;lt;/button&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  DOM Manipulation
&lt;/h2&gt;

&lt;p&gt;Alpine makes DOM manipulation available through the use of various directives. We will go through some of the most common ones here.&lt;/p&gt;

&lt;h3&gt;
  
  
  Text content
&lt;/h3&gt;

&lt;p&gt;We can use directive &lt;code&gt;x-text&lt;/code&gt; to essentially control the text content of the element:&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;div x-data="{ paragraph: 'This is the paragraph' }"&amp;gt;
  &amp;lt;p x-text="paragraph"&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this directive you can use any JavaScript expression and it will evaluate as the content of the element.&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;div x-data="{a: 1, b: 4}"&amp;gt;
  &amp;lt;p x-text="b &amp;gt; a"&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will output &lt;code&gt;true&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Toggling elements
&lt;/h3&gt;

&lt;p&gt;You will require this directive when you create modals, dropdowns and similar content that has 'on-off' logic. We can use &lt;code&gt;x-show&lt;/code&gt; and &lt;code&gt;x-if&lt;/code&gt; here to toggle elements on the page. Behind the scenes Alpine is adding &lt;code&gt;display: none&lt;/code&gt; to the element it needs to hide&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;div x-data="{ toggle: false }"&amp;gt;
    &amp;lt;button @click="toggle = ! toggle"&amp;gt;Show More&amp;lt;/button&amp;gt;
    &amp;lt;div x-show="toggle"&amp;gt;
        My Content...
    &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can use &lt;code&gt;x-if&lt;/code&gt; to achieve the same goal&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;div x-data="{ toggle: false }"&amp;gt;
    &amp;lt;button @click="toggle = ! toggle"&amp;gt;Show More&amp;lt;/button&amp;gt;
    &amp;lt;template x-if="toggle"&amp;gt;
      &amp;lt;div&amp;gt;
        My Content...
      &amp;lt;/div&amp;gt;
    &amp;lt;/template&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Binding attributes
&lt;/h3&gt;

&lt;p&gt;We can add &lt;code&gt;HTML&lt;/code&gt; attributes to elements using &lt;code&gt;x-bind&lt;/code&gt; directive&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;button
    x-data="{ green: false }"
    x-bind:class="green ? 'bg-green' : ''"
    @click="green = !green"
&amp;gt;
    Toggle Green
&amp;lt;/button&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can use syntax without &lt;code&gt;x-bind&lt;/code&gt; only on &lt;code&gt;class&lt;/code&gt; bindings like so:&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;div x-data="{ open: true }"&amp;gt;
  &amp;lt;p :class="{ 'hidden': !open }"&amp;gt;...&amp;lt;/p&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we will have &lt;code&gt;hidden&lt;/code&gt; class added to the &lt;code&gt;p&lt;/code&gt; element whenever &lt;code&gt;open&lt;/code&gt; is false.&lt;/p&gt;

&lt;h3&gt;
  
  
  Looping elements
&lt;/h3&gt;

&lt;p&gt;We've seen &lt;code&gt;x-for&lt;/code&gt; earlier when we iterated through tabs in &lt;code&gt;Alpine.store(...)&lt;/code&gt; example. As you've seen there, &lt;code&gt;x-for&lt;/code&gt; allows us to iterate through our data. Note that it has to be applied within &lt;code&gt;&amp;lt;template&amp;gt;&lt;/code&gt; tag though.&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;div x-data="{ seasons: ['spring', 'summer', 'autumn', 'winter'] }"&amp;gt;
    &amp;lt;template x-for="season in seasons"&amp;gt;
        &amp;lt;div x-text="season"&amp;gt;&amp;lt;/div&amp;gt;
    &amp;lt;/template&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Inner HTML
&lt;/h3&gt;

&lt;p&gt;You can also control &lt;code&gt;HTML&lt;/code&gt; content with the &lt;code&gt;x-html&lt;/code&gt; directive like so:&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;div x-data="{ title: '&amp;lt;h1&amp;gt;I am the Title&amp;lt;/h1&amp;gt;' }"&amp;gt;
    &amp;lt;div x-html="title"&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hope some of the examples will help you in your work, hobbies, and projects. Thank you for reading and stay safe.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Fancy a modern alternative to jQuery? Meet AlpineJS</title>
      <dc:creator>Semir Teskeredzic</dc:creator>
      <pubDate>Thu, 19 Aug 2021 08:54:33 +0000</pubDate>
      <link>https://dev.to/semirteskeredzic/fancy-a-modern-alternative-to-jquery-meet-alpinejs-1lap</link>
      <guid>https://dev.to/semirteskeredzic/fancy-a-modern-alternative-to-jquery-meet-alpinejs-1lap</guid>
      <description>&lt;p&gt;Couple of days ago I stumbled upon a great video from Fireship on YouTube. It was about creating a same todo app in 9 JS frameworks and in vanilla JS. In my opinion it is a piece worth watching, you can watch it &lt;a href="https://www.youtube.com/watch?v=cuHDQhDhvPE"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I've also never been much of a fan of jQuery, yeah it gets the job done and it can pull you out from some difficult situations but it never really grew on me. That's why AlpineJS sounded so appealing at first.&lt;/p&gt;

&lt;p&gt;It is ultra lightweight and consists of 15 attributes, 6 properties, and 2 methods. It has bindings, listening for events, looping, and even a store.&lt;br&gt;
Without a further ado I'll guide you through some basic examples for you to see how cool and simple it really is.&lt;/p&gt;

&lt;p&gt;Let's create a toggling dropdown. &lt;/p&gt;
&lt;h2&gt;
  
  
  Toggling Dropdown component
&lt;/h2&gt;

&lt;p&gt;Let's start by creating a regular &lt;code&gt;html&lt;/code&gt; file named something like &lt;code&gt;baby-steps-alpinejs.html&lt;/code&gt;&lt;br&gt;
You won't need any libraries from &lt;code&gt;npm&lt;/code&gt; everything is imported through the cdn link like so:&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;html&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;script defer src="https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js"&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As for structure we will need our main &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;, then a &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt; that will do the toggling, and finally a &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; that will house our content.&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;body&amp;gt;
  &amp;lt;div x-data="{open: false}"&amp;gt;
    &amp;lt;button x-on:click="open = !open"&amp;gt;Toggle&amp;lt;/button&amp;gt;
    &amp;lt;div x-show="open" @click.outside="open = false"&amp;gt;Our Dropdown contents&amp;lt;/div&amp;gt;
  &amp;lt;div&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now what is happening here, let's start from the beginning. The &lt;code&gt;x-data&lt;/code&gt; is simply a directive in Alpine that declares the object of data, it is worth mentioning that every property inside this object is available to other directives inside that HTML element. Here we declare our variable &lt;code&gt;open&lt;/code&gt; with the value &lt;code&gt;false&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Next, there is a button that has an event listener expressed with &lt;code&gt;x-on&lt;/code&gt; directive, in this case we are listening to the &lt;code&gt;click&lt;/code&gt; event on this element. When this button is clicked we toggle the value of the previously declared variable &lt;code&gt;open&lt;/code&gt;. So far so good.&lt;/p&gt;

&lt;p&gt;Latest element is a div that houses the content. Here we see another Alpine directive &lt;code&gt;x-show&lt;/code&gt;, what it does is showing and hiding a block of &lt;code&gt;HTML&lt;/code&gt; on a page based on the input, in this case it is evaluating our variable &lt;code&gt;open&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It might be a little confusing to see &lt;code&gt;@click&lt;/code&gt; all of a sudden, it is a shorter way to implement &lt;code&gt;x-on&lt;/code&gt; directive. Another thing is &lt;code&gt;.outside&lt;/code&gt; attached to the &lt;code&gt;@click&lt;/code&gt; directive. This is a modifier that is created for making your life easier. It will listen to the clicks outside of the element and apply given logic, in this case &lt;code&gt;open = false&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Another handy modifier is used with &lt;code&gt;submit&lt;/code&gt; event in forms to, you guessed it, prevent default behaviour upon form submission. It is applied simply as &lt;code&gt;@submit.prevent="..."&lt;/code&gt; simple as that. Modifiers like &lt;code&gt;window&lt;/code&gt;, &lt;code&gt;document&lt;/code&gt;, &lt;code&gt;outside&lt;/code&gt;, &lt;code&gt;debounce&lt;/code&gt; and others are there to help you with implementations of behaviours that would otherwise be a little tricky to set. They are of great help, that's for sure.&lt;/p&gt;

&lt;p&gt;I want to show you another directive that we didn't use here - &lt;code&gt;x-text&lt;/code&gt; it is a directive that is used for setting the text content of the element. You can set it to the variable &lt;code&gt;open&lt;/code&gt; in which case it will display textual boolean value &lt;code&gt;true&lt;/code&gt; because the &lt;code&gt;open&lt;/code&gt; is always &lt;code&gt;true&lt;/code&gt; when it's open. We can also declare another variable in the &lt;code&gt;x-data&lt;/code&gt; and use &lt;code&gt;x-text&lt;/code&gt; to display it like so:&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;body&amp;gt;
  &amp;lt;div x-data="{open: false, content: 'Our newest content'}"&amp;gt;
    &amp;lt;button x-on:click="open = !open"&amp;gt;Toggle&amp;lt;/button&amp;gt;
    &amp;lt;div x-show="open" @click.outside="open = false" x-text="content"&amp;gt;&amp;lt;/div&amp;gt;
  &amp;lt;div&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will show the text &lt;code&gt;Our newest content&lt;/code&gt; when we toggle our element.&lt;/p&gt;

&lt;p&gt;I hope you enjoyed a short glimpse inside the &lt;code&gt;AlpineJS&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Thank you for reading and stay happy, productive, and safe.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>html</category>
    </item>
    <item>
      <title>Spread Syntax ( ... )</title>
      <dc:creator>Semir Teskeredzic</dc:creator>
      <pubDate>Fri, 06 Aug 2021 09:33:46 +0000</pubDate>
      <link>https://dev.to/semirteskeredzic/spread-syntax-53ne</link>
      <guid>https://dev.to/semirteskeredzic/spread-syntax-53ne</guid>
      <description>&lt;p&gt;MDN Web docs state following for the spread syntax:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Spread syntax (...) allows an iterable such as an array expression or string to be expanded in places where zero or more arguments (for function calls) or elements (for array literals) are expected, or an object expression to be expanded in places where zero or more key-value pairs (for object literals) are expected.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Spreading the arrays
&lt;/h2&gt;

&lt;p&gt;In day to day coding we are mostly using spread syntax to copy the array or the object to the new array. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let companies = ['Nestle', 'Volvo', 'Klarna'];
let newCompany = 'Adobe';
companies = [ ...companies, newCompany];
// This returns ['Nestle', 'Volvo', 'Klarna', 'Adobe']
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So basically we use spread syntax when we want to include all elements from either array or object to some kind of list. &lt;/p&gt;

&lt;h2&gt;
  
  
  Use case with ReactJS
&lt;/h2&gt;

&lt;p&gt;This comes handy in handling state in React when you want to have previous state and include a new piece of data like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, {useState} from 'react'

export default function App() {

    const [colors, setColors] = useState(['Red','Green','Blue']);

    const changeColor = (colorName) =&amp;gt; {
     setColors((prevState) =&amp;gt; [...prevState, colorName])
    }

  return (
    &amp;lt;div className="App"&amp;gt;
      &amp;lt;h1&amp;gt;Colors&amp;lt;/h1&amp;gt;
      {colors.map((color) =&amp;gt; &amp;lt;p&amp;gt;{color}&amp;lt;/p&amp;gt;)}
`     &amp;lt;button onClick={() =&amp;gt; changeColor('Gold')}&amp;gt;Gold&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  );
} 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we initialise the state with primary colours &lt;code&gt;Red, Green, and Blue&lt;/code&gt;. Then we use &lt;code&gt;prevState&lt;/code&gt; and spreading it inside a new state so we can get all the elements in the previous state and add a new element.&lt;br&gt;
We just hardcoded &lt;code&gt;Gold&lt;/code&gt; here but we could make a dropdown or input field to add whatever we like.&lt;/p&gt;
&lt;h2&gt;
  
  
  Spreading multidimensional arrays
&lt;/h2&gt;

&lt;p&gt;When we are not copying multidimensional arrays, we indeed create a copy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let first = [1, 2, 3, 4]
let second = [...first]

console.log('First', first)
// First (4) [1, 2, 3, 4]
console.log('Second', second)
// Second (4) [1, 2, 3, 4]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now if we remove the element from the &lt;code&gt;second&lt;/code&gt; array, the change will happen only in the second array.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let first = [1, 2, 3, 4]
let second = [...first]

second.shift()

console.log('First', first)
// First (4) [1, 2, 3, 4]
console.log('Second', second)
// Second (3) [2, 3, 4]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is because the &lt;code&gt;second&lt;/code&gt; array is an actual copy in the memory. However, when we deal with multidimensional arrays we get a red note from MDN docs:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: Spread syntax effectively goes one level deep while copying an array. Therefore, it may be unsuitable for copying multidimensional arrays, as the following example shows. (The same is true with Object.assign() and spread syntax.)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So when we have a multidimensional array we don't get a copy but a reference, therefore changing data in the "copied" array will affect the original.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let first = [[1], [2], [3], [4]]
let second = [...first]

console.log('First', first)
// First(4) [Array(1), Array(1), Array(1), Array(1)]
console.log('Second', second)
// Second(4) [Array(1), Array(1), Array(1), Array(1)]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So far it is behaving as expected, but when we change one of the elements, we also get the change in the original array:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let first = [[1], [2], [3], [4]]
let second = [...first]

second.shift().shift()

console.log('First', first)
// First(4) [Array(0), Array(1), Array(1), Array(1)]
console.log('Second', second)
// Second(3) [Array(1), Array(1), Array(1)]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is one of the things one has to keep in mind if the multidimensional arrays are spread and therefore referenced.&lt;/p&gt;

&lt;p&gt;Thank you for reading.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
    </item>
    <item>
      <title>Building a Blog with React, Strapi &amp; GraphQL - Create Post &amp; Display it in Frontend</title>
      <dc:creator>Semir Teskeredzic</dc:creator>
      <pubDate>Thu, 24 Jun 2021 21:51:10 +0000</pubDate>
      <link>https://dev.to/semirteskeredzic/building-a-blog-with-react-strapi-graphql-create-post-display-it-in-frontend-3e19</link>
      <guid>https://dev.to/semirteskeredzic/building-a-blog-with-react-strapi-graphql-create-post-display-it-in-frontend-3e19</guid>
      <description>&lt;p&gt;Hey there, this is the second part of the mini series in Building an app with React, Strapi, and GraphQL. In the first part that you can find &lt;a href="https://dev.to/semirteskeredzic/first-steps-in-building-app-with-react-strapi-apollo-graphql-1g64"&gt;here&lt;/a&gt;, we went through first steps in prepping the backend and frontend for our app.&lt;br&gt;
In this part we will go through creating a blog post and displaying it in the list.&lt;/p&gt;
&lt;h1&gt;
  
  
  Add Blog Post to the Strapi
&lt;/h1&gt;

&lt;p&gt;First of all, spin up your Strapi environment with the command in the terminal from the directory that houses Strapi:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ yarn develop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will start the Strapi server so you can now navigate to &lt;code&gt;http://localhost:1337/admin/&lt;/code&gt;, once you are there enter the login data for the admin user. &lt;br&gt;
Now in the left sidebar, chose &lt;code&gt;Content-Types Builder&lt;/code&gt; and this will bring you to the list of your content type so click &lt;code&gt;Create Content Type&lt;/code&gt;.&lt;br&gt;
As a name enter &lt;code&gt;BlogPost&lt;/code&gt; and press Continue, next you will be prompted to select a field for our content type:&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%2Fvkc6yhmtyawgv33tb2a7.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%2Fvkc6yhmtyawgv33tb2a7.png" alt="Strapi content type fields"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For a proper Blog post we need following fields:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Title (Text - Short text)&lt;/li&gt;
&lt;li&gt;Body (Text - Long text)&lt;/li&gt;
&lt;li&gt;Tags (Text- Short text)&lt;/li&gt;
&lt;li&gt;CreatedAt (Date - datetime)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Go on and create those fields by selecting the type from the parentheses. Don't forget to click save after you have added them.&lt;/p&gt;
&lt;h1&gt;
  
  
  Add a Blog post
&lt;/h1&gt;

&lt;p&gt;In this case we will also use our Strapi backend. Make sure that the Strapi server is running and navigate to &lt;code&gt;http://localhost:1337&lt;/code&gt;.&lt;br&gt;
In the collection type section of the left sidebar under Collection Types click on BlogPosts. This will open a list of current BlogPosts with the button to add a new Blog post, press that button to add a new Blog post.&lt;br&gt;
Fill out all the fields as you like and click Save and after that click Publish.&lt;br&gt;
Now when you click on Collection Types BlogPosts you will see our new post in the list.&lt;br&gt;
Next we will show the list of blog posts in the frontend of our application.&lt;/p&gt;
&lt;h1&gt;
  
  
  Show the list of blog posts in frontend
&lt;/h1&gt;

&lt;p&gt;If you followed steps from the first part in frontend folder we have everything ready to fetch the data from the Strapi backend.&lt;br&gt;
In the &lt;code&gt;frontend&lt;/code&gt; folder create a new directory under &lt;code&gt;src&lt;/code&gt; named &lt;code&gt;queries&lt;/code&gt; there create a new file named &lt;code&gt;blogPosts.js&lt;/code&gt;.&lt;br&gt;
In this file we will write a GraphQL query that will fetch us needed data from Strapi.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;frontend/src/queries/blogPosts.js&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { gql } from '@apollo/client'

export const GET_BLOGPOSTS = gql`
  query {
  blogPosts {
    id
    Title
    Body
    Tags
    CreatedAt
  }
}`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;You can test queries by navigating to &lt;a href="http://localhost:1337/graphql" rel="noopener noreferrer"&gt;http://localhost:1337/graphql&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Now we need to write a component that will call this query and populate our table with the data, so let's create a &lt;code&gt;ListBlogPosts.js&lt;/code&gt; inside &lt;code&gt;frontend/src/components&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;frontend/src/components/ListBlogPosts.js&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from 'react'
import { GET_BLOGPOSTS } from "../queries/blogPosts"
import {useQuery} from "@apollo/client";

function ListBlogPosts() {

    const {data, error, loading} = useQuery(GET_BLOGPOSTS)

    if(loading) return 'Loading...'
    if(error) return `Oops there has been an error: ${error}`
    if(data) return console.log(data)
}

export default ListBlogPosts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will use this to test whether our query actually works!&lt;br&gt;
If you save this, run the server with &lt;code&gt;yarn start&lt;/code&gt; and navigate to &lt;code&gt;http://localhost:3000&lt;/code&gt; you will see ..this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Oops there has been an error: Error: Forbidden
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that is OK! It shows that our connection with Strapi works, that our basic error handler works because we are forbidden to read this data so this is Strapi issue.&lt;br&gt;
Let's go back to Strapi backend and fix this, open Strapi backend and go to &lt;code&gt;Settings&lt;/code&gt; and under &lt;code&gt;Users &amp;amp; Permissions Plugin&lt;/code&gt; section select &lt;code&gt;Roles&lt;/code&gt;. There you will see our &lt;code&gt;BLOG-POSTS&lt;/code&gt; with all checkboxes deactivated, use &lt;code&gt;select all&lt;/code&gt; to check all boxes and save it.&lt;br&gt;
Now when you refresh &lt;code&gt;http://localhost:3000&lt;/code&gt; you will see nothing but when you open console you will see we get the object. Success! Now let's show that in a way we humans understand it. Remove the line with &lt;code&gt;if(data)...&lt;/code&gt; and create this return instead:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;frontend/src/components/ListBlogPosts.js&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
if(error) return `Oops there has been an error: ${error}`

return(
        &amp;lt;div&amp;gt;
            &amp;lt;h1&amp;gt;List of Blog Posts&amp;lt;/h1&amp;gt;
            &amp;lt;table&amp;gt;
                &amp;lt;thead&amp;gt;
                    &amp;lt;tr&amp;gt;
                        &amp;lt;th&amp;gt;ID&amp;lt;/th&amp;gt;
                        &amp;lt;th&amp;gt;Title&amp;lt;/th&amp;gt;
                        &amp;lt;th&amp;gt;Body&amp;lt;/th&amp;gt;
                        &amp;lt;th&amp;gt;Tags&amp;lt;/th&amp;gt;
                        &amp;lt;th&amp;gt;Created&amp;lt;/th&amp;gt;
                    &amp;lt;/tr&amp;gt;
                &amp;lt;/thead&amp;gt;
                {data?.blogPosts &amp;amp;&amp;amp; data?.blogPosts.length !== 0 ?
                    &amp;lt;tbody&amp;gt;
                    {data?.blogPosts.map(({id, Title, Body, Tags, CreatedAt}) =&amp;gt; (
                        &amp;lt;tr key={id}&amp;gt;
                            &amp;lt;td&amp;gt;{id}&amp;lt;/td&amp;gt;
                            &amp;lt;td&amp;gt;{Title}&amp;lt;/td&amp;gt;
                            &amp;lt;td&amp;gt;{Body}&amp;lt;/td&amp;gt;
                            &amp;lt;td&amp;gt;{Tags}&amp;lt;/td&amp;gt;
                            &amp;lt;td&amp;gt;{CreatedAt}&amp;lt;/td&amp;gt;
                        &amp;lt;/tr&amp;gt;
                    ))}
                    &amp;lt;/tbody&amp;gt; : &amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;No Blog Posts to show!&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;}
            &amp;lt;/table&amp;gt;
        &amp;lt;/div&amp;gt;
)

export default ListBlogPosts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What did we do here? We created a simple table and we filled it with the data from Strapi. As you can notice we are using &lt;code&gt;data?.&lt;/code&gt; with question mark, that is &lt;strong&gt;optional chaining&lt;/strong&gt; because we don't want our code to throw exception if the data is somehow not ok. First we are checking whether blogPosts are there and whether we have blogPosts, we use &lt;code&gt;.length&lt;/code&gt; here because we get an array of blogPosts so if there are blogPosts the &lt;code&gt;.length&lt;/code&gt; won't be 0. If there are no blogPosts we show short info that there is no blog posts to show while if there are blogPosts we show them in the table through the map function. &lt;/p&gt;

&lt;p&gt;Now we see a simple table with all the data we entered in the Strapi backend. In the next steps we will add editing and removing options to this table so we can handle it directly from the frontend client.&lt;/p&gt;

&lt;p&gt;Thank you for reading!&lt;/p&gt;

</description>
      <category>react</category>
      <category>graphql</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>First steps in building app with React, Strapi &amp; Apollo GraphQL</title>
      <dc:creator>Semir Teskeredzic</dc:creator>
      <pubDate>Thu, 17 Jun 2021 13:10:38 +0000</pubDate>
      <link>https://dev.to/semirteskeredzic/first-steps-in-building-app-with-react-strapi-apollo-graphql-1g64</link>
      <guid>https://dev.to/semirteskeredzic/first-steps-in-building-app-with-react-strapi-apollo-graphql-1g64</guid>
      <description>&lt;p&gt;I have to say I fell in love with Strapi from the day I found it. For all of those who never heard of Strapi be sure to checkout &lt;a href="https://strapi.io/"&gt;Strapi.io&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As per Strapi.io:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Strapi is the leading open-source Headless CMS. Strapi gives developers the freedom to use their favorite tools and frameworks while allowing editors to easily manage their content and distribute it anywhere.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And it just connects with anything, since I love working with React as well I had to give it a try. Instead of using REST I went with GraphQL and Apollo since it is steady becoming an essential tool in building scalable and performant web applications.&lt;/p&gt;

&lt;p&gt;In this post I will go through first steps and share the way I catch GraphQL errors in more meaningful way along with setting up InMemoryCache.&lt;/p&gt;

&lt;h1&gt;
  
  
  Create &amp;amp; Start a project
&lt;/h1&gt;

&lt;p&gt;Open terminal window and then create a folder for our project, cd into it and create projects for our Strapi backend and React frontend:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mkdir BestestApp
$ cd BestestApp
$ yarn create strapi-app backend --quickstart
$ npx create-react-app frontend
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will create two folders in our project folder so you have to open two tabs in Terminal in order to start both applications. In one tab cd into &lt;code&gt;BestestApp/backend&lt;/code&gt; and start the server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ yarn develop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will start Strapi so you can open this address in your browser: &lt;a href="http://localhost:1337/admin"&gt;http://localhost:1337/admin&lt;/a&gt;. Follow the onscreen instructions and create Admin user. Login and you are in! Welcome to Strapi!&lt;br&gt;
In the second tab navigate to &lt;code&gt;BestestApp/frontend&lt;/code&gt; and type&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ yarn start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will start React application that by default runs on &lt;a href="http://localhost:3000/"&gt;http://localhost:3000/&lt;/a&gt; so go on and open it in another tab.&lt;/p&gt;

&lt;h1&gt;
  
  
  Install Packages
&lt;/h1&gt;

&lt;p&gt;In order for us to work with Apollo we have to install some packages so let's do that. Open another Terminal tab navigate to &lt;code&gt;BestestApp/frontend&lt;/code&gt; and install packages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ yarn add @apollo/client apollo-link apollo-link-error graphql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Configure GraphQL and Entry point
&lt;/h1&gt;

&lt;p&gt;Make sure that Strapi server is running and enter the Strapi through the browser using &lt;a href="http://localhost:1337/admin"&gt;http://localhost:1337/admin&lt;/a&gt;. Then go to the Marketplace in the sidebar and make sure that the GraphQL plugin is installed, if it is not, then go ahead and install it. And don't worry if you sometimes get an error here, just refresh the page.&lt;/p&gt;

&lt;p&gt;You can now enter your GraphQL endpoints using &lt;a href="http://localhost:1337/graphql"&gt;http://localhost:1337/graphql&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We will now go into editing &lt;code&gt;Index.js&lt;/code&gt; in our Frontend so open your favorite IDE or any other editor you use for coding and open &lt;code&gt;BestestApp/frontend/src/Index.js&lt;/code&gt;.&lt;br&gt;
We will now implement a GraphQL error check that will show you in the console when something is not right with your request. We will add errorLink creator and a little Apollo magic:&lt;br&gt;
/frontend/src/Index.js&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
import { ApolloProvider, createHttpLink } from '@apollo/client';
import { ApolloClient } from '@apollo/client';
import { onError } from 'apollo-link-error';
import { ApolloLink } from 'apollo-link';

const errorLink = onError(({ graphQLErrors, networkError }) =&amp;gt; {
  if (graphQLErrors) {
    console.log('graphQLErrors', graphQLErrors);
  }
  if (networkError) {
    console.log('networkError', networkError);
  }
});

const httpLink = createHttpLink({
  uri: 'http://localhost:1337/graphql',
});

const link = ApolloLink.from([errorLink, httpLink]);

export const client = new ApolloClient({link});

ReactDOM.render(
  &amp;lt;ApolloProvider client={client}&amp;gt;
    &amp;lt;App /&amp;gt;
  &amp;lt;/ApolloProvider&amp;gt;,
  document.getElementById('root')
);
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We used onError to catch GraphQL and Network errors and show them to console, and we are using the GraphQL endpoint for Strapi &lt;code&gt;http://localhost:1337/graphql&lt;/code&gt;. Next we initiate our ApolloClient using a link that uses our errorLink and httpLink. Finally we reference the client in the ApolloProvider wrapping our  as the entry to our app.&lt;/p&gt;

&lt;h1&gt;
  
  
  Configure InMemoryCache
&lt;/h1&gt;

&lt;p&gt;Great thing about Apollo is that it uses in-memory cache which enables our client to respond to queries for the same data with better performance and without unnecessary requests.&lt;br&gt;
We just need to add it to our options config when instantiating new Apollo client with the appropriate data for our types. In this example we have Parts and Products:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
import { ApolloClient, InMemoryCache } from '@apollo/client';
...
export const client = new ApolloClient({
  link,
  cache: new InMemoryCache({
    typePolicies: {
      Query: {
        Part: {
          parts: {
            fields: {
              merge(existing, incoming) {
                return incoming;
              }
            }
          }
        },
        Product: {
          products: {
            fields: {
              merge(existing,incoming) {
                return incoming;
              }
            }
          }
        }
      }
    }
  })
});
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can find more on configuring caching &lt;a href="https://www.apollographql.com/docs/react/caching/cache-configuration/"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Congrats! You are now ready to use GrapQL to read data from the Strapi backend. In some later posts I will go through queries and mutations that are needed for fetching and updating data.&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

</description>
      <category>react</category>
      <category>graphql</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Add Notifications to your React application</title>
      <dc:creator>Semir Teskeredzic</dc:creator>
      <pubDate>Sun, 13 Jun 2021 20:32:24 +0000</pubDate>
      <link>https://dev.to/semirteskeredzic/add-notifications-to-your-react-application-epc</link>
      <guid>https://dev.to/semirteskeredzic/add-notifications-to-your-react-application-epc</guid>
      <description>&lt;p&gt;Proper notifications are crucial for functional UI. Imagine you are using one of many web applications and you enter a wrong password or any kind of input just to see that nothing happens and you are left baffled. That is why integrating notifications, alerts or other kind of signals what has happened is important for any application with user interface.&lt;/p&gt;

&lt;p&gt;In this post I will go through the simple integration of &lt;code&gt;react-notifications-component&lt;/code&gt; library that has some 23k of weekly downloads on npmjs.com.&lt;/p&gt;

&lt;h1&gt;
  
  
  Add package to your project
&lt;/h1&gt;

&lt;p&gt;You can use npm to add this package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npm i react-notifications-component
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then you need to build library:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npm run build:library:dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You are ready to go! Now you can start your application&lt;/p&gt;

&lt;h1&gt;
  
  
  Import and Setup
&lt;/h1&gt;

&lt;p&gt;Now in your App.js you need to import &lt;code&gt;ReactNotification&lt;/code&gt; and its &lt;code&gt;css&lt;/code&gt; file like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import ReactNotification from 'react-notifications-component'
import 'react-notifications-component/dist/theme.css'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we put &lt;code&gt;ReactNotification&lt;/code&gt; component alongdside of our main app content in order not to collide with other absolute positioned elements:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function App() {
  return (
    &amp;lt;div&amp;gt;
        &amp;lt;ReactNotification /&amp;gt;
        &amp;lt;Application /&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}

export default App;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are now ready to use notification when we need it.&lt;/p&gt;

&lt;h1&gt;
  
  
  Use in Component
&lt;/h1&gt;

&lt;p&gt;Let's say you have a small component that throws a great success notification when you enter your name and click hello button and it throws bad red notification when you don't enter your name but nevertheless click hello button.&lt;/p&gt;

&lt;p&gt;First we import &lt;code&gt;store&lt;/code&gt; from our new package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { store } from 'react-notifications-component'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notification is called like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;store.addNotification({
  title: "Success!",
  message: "You have been successful!",
  type: "success",
  insert: "top",
  container: "top-right",
  animationIn: ["animate__animated", "animate__fadeIn"],
  animationOut: ["animate__animated", "animate__fadeOut"],
  dismiss: {
    duration: 5000,
    onScreen: false
  }
});

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

&lt;/div&gt;



&lt;p&gt;To see the notification in action we will create a component that will evaluate if the user entered name, if yes then success notification will be executed if not then danger notification will be executed. So here is a simple component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useState } from "react";
import { store } from "react-notifications-component";

function Application() {
  const [name, setName] = useState("");

  const handleChange = (e) =&amp;gt; {
    setName(e.target.value);
  };

  const handleSubmit = (e) =&amp;gt; {
    e.preventDefault();
    if (name) {
      store.addNotification({
        title: "Great",
        message: `Hello ${name}`,
        type: "success",
        insert: "top",
        container: "top-right",
        animationIn: ["animate__animated", "animate__fadeIn"],
        animationOut: ["animate__animated", "animate__fadeOut"],
        dismiss: {
          duration: 5000,
          onScreen: false
        }
      });
      setName("");
    } else {
      store.addNotification({
        title: "OOh OOh!",
        message: "Don't be shy!",
        type: "danger",
        insert: "top",
        container: "top-right",
        animationIn: ["animate__animated", "animate__fadeIn"],
        animationOut: ["animate__animated", "animate__fadeOut"],
        dismiss: {
          duration: 5000,
          onScreen: false
        }
      });
    }
  };

  return (
    &amp;lt;&amp;gt;
      &amp;lt;input
        value={name}
        onChange={(e) =&amp;gt; handleChange(e)}
        placeholder="Enter name here!"
      /&amp;gt;
      &amp;lt;button onClick={(e) =&amp;gt; handleSubmit(e)}&amp;gt;Say Hello&amp;lt;/button&amp;gt;
    &amp;lt;/&amp;gt;
  );
}

export default Application;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Simple setup is available in codesandbox &lt;a href="https://codesandbox.io/s/old-http-dznz8?file=/src/Application.js"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can configure notifications object with values:&lt;/p&gt;

&lt;h3&gt;
  
  
  Position:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;container:
- top-left
- top-right
- top-center
- center
- bottom-left
- bottom-right
- bottom-center
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Types:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type:
- success
- danger
- info
- default
- warning
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can find more in the package documentation &lt;a href="https://www.npmjs.com/package/react-notifications-component"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thank you for reading and happy notifying!&lt;/p&gt;

</description>
      <category>react</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Create Forms with Firebase and Formik</title>
      <dc:creator>Semir Teskeredzic</dc:creator>
      <pubDate>Tue, 08 Jun 2021 22:51:00 +0000</pubDate>
      <link>https://dev.to/semirteskeredzic/create-forms-with-firebase-and-formik-3cla</link>
      <guid>https://dev.to/semirteskeredzic/create-forms-with-firebase-and-formik-3cla</guid>
      <description>&lt;p&gt;Whatever is the application you are building, the data is in the heart of it. In this post I will go through building a simple but functional form with Formik and storing the data to Firebase database. I will use React functional component for this example so you can follow along or use it with your React project.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;First you will need to create a Project at &lt;a href="https://firebase.google.com/" rel="noopener noreferrer"&gt;Firebase&lt;/a&gt; (or use an existing one).&lt;/li&gt;
&lt;li&gt;You need to create a database within the Firebase project you want to use (or use an existing one) and set up the write rule to &lt;code&gt;true&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;React application (using Create React App or other)&lt;/li&gt;
&lt;li&gt;Following packages (you can also use &lt;code&gt;npm i&lt;/code&gt; instead of &lt;code&gt;yarn add&lt;/code&gt;):
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ yarn add firebase formik
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Configure Firebase
&lt;/h1&gt;

&lt;p&gt;When you arrive to your &lt;a href="https://console.firebase.google.com/" rel="noopener noreferrer"&gt;Firebase dashboard&lt;/a&gt; you will enter your project and grab a configuration object by pressing the code icon &amp;lt;/&amp;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%2F540zd6kk3l5ollsamwjg.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%2F540zd6kk3l5ollsamwjg.png" alt="Screenshot 2021-06-08 at 18.45.26"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then you will get something similar to this:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;firebaseConfig.js&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var firebaseConfig = {
    apiKey: "xxxxxxxx",
    authDomain: "firebaseformikproject-xxxxx.firebaseapp.com",
    projectId: "firebaseformikproject-xxxxx",
    storageBucket: "firebaseformikproject-xxxxx.appspot.com",
    messagingSenderId: "xxxxxxxxxxxxx",
    appId: "x:xxxxxxxxxxx:web:xxxxxxxxxxxxxxxxxx"
  };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will use this object to configure Firebase in our React app.&lt;/p&gt;

&lt;p&gt;Create a new file in your project directory/src named &lt;code&gt;firebaseConfig.js&lt;/code&gt; and paste the object.&lt;br&gt;
Next replace &lt;code&gt;var&lt;/code&gt; with &lt;code&gt;let&lt;/code&gt; and add &lt;code&gt;export default firebaseConfig&lt;/code&gt; outside of the object&lt;/p&gt;

&lt;p&gt;Go to the &lt;code&gt;index.js&lt;/code&gt; or entry point of your application and add following line above of &lt;code&gt;ReactDOM.render()&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;index.js&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
import { firebase } from '@firebase/app';
import firebaseConfig from './firebaseConfig';

firebase.initializeApp(firebaseConfig);

ReactDOM.render(
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: If your &lt;code&gt;firebaseConfig.js&lt;/code&gt; file is not in the same directory as your &lt;code&gt;index.js&lt;/code&gt; then you have to adjust the route in the import statement.&lt;/p&gt;

&lt;p&gt;Now the Firebase initializes on your application start.&lt;/p&gt;

&lt;h1&gt;
  
  
  Add Formik form
&lt;/h1&gt;

&lt;p&gt;We will now create a simple form with Formik. Create a new file named &lt;code&gt;RegisterForm.js&lt;/code&gt; and place it into current directory.&lt;/p&gt;

&lt;p&gt;We will use React, Firebase for updating the database and Formik hook for handling the form so we need to import them:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;RegisterForm.js&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from 'react'
import Firebase from 'firebase'
import { useFormik } from 'formik'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next we will pass initial values and the onSubmit method to our functional component. We will ask our users to write their first name, username, and email. We will then save that data in the Firebase database when the user clicks submit:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;RegisterForm.js&lt;/em&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 RegisterForm = () =&amp;gt; {

const formik = useFormik({
  initialValues: {
    firstName: '',
    username: '',
    email: '',
  },
  onSubmit: values =&amp;gt; {
    let ref1 = Firebase.database().ref().child('users').push()
    ref1.set(values)
  },
});
  return (
    &amp;lt;form onSubmit={formik.handleSubmit}&amp;gt;
      &amp;lt;label htmlFor="firstName"&amp;gt;First Name&amp;lt;/label&amp;gt;
      &amp;lt;input
        id="firstName"
        name="firstName"
        type="text"
        onChange={formik.handleChange}
        value={formik.values.firstName}
      /&amp;gt;

      &amp;lt;label htmlFor="username"&amp;gt;Username&amp;lt;/label&amp;gt;
      &amp;lt;input
        id="username"
        name="username"
        type="text"
        onChange={formik.handleChange}
        value={formik.values.username}
       /&amp;gt;

      &amp;lt;label htmlFor="email"&amp;gt;Email Address&amp;lt;/label&amp;gt;
      &amp;lt;input
        id="email"
        name="email"
        type="email"
        onChange={formik.handleChange}
        value={formik.values.email}
      /&amp;gt;

      &amp;lt;button type="submit"&amp;gt;Submit&amp;lt;/button&amp;gt;
    &amp;lt;/form&amp;gt;
 );
};

export default RegisterForm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And voila! Our registration form is ready and working. We used Formik helper functions &lt;code&gt;handleChange&lt;/code&gt; and &lt;code&gt;handleSubmit&lt;/code&gt; so it kept our code quite clean.&lt;/p&gt;

&lt;p&gt;If you want to test it, open App.js and import &lt;code&gt;RegisterForm.js&lt;/code&gt; and use it as a component.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;App.js&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import RegisterForm from "./RegisterForm";

export default function App() {
  return (
    &amp;lt;div className="App"&amp;gt;
      &amp;lt;RegisterForm /&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Firebase and unique ID
&lt;/h1&gt;

&lt;p&gt;If you worked with relational databases you are familiar with the id for each entry that is usually a primary key i.e. it is unique and can be referred only to one entry.&lt;br&gt;
In Firebase each entry gets a unique key so one our example entries looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;users
  |_ -MEIwCAwrPBePyp4mVv1
        |_ firstName: "John"
        |_ username: "johnwayne"
        |_ email: "john.w@mail.com"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each new entry gets this unique key, but what if you want to catch it and store it along with all the data for one user? It is simple, we will just edit our onSubmit method:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;RegisterForm.js&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
    onSubmit: values =&amp;gt; {
    let ref1 = Firebase.database().ref().child('users').push()
    let key = ref1.key
    values.id = key
    ref1.set(values)
  },
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We first grab a key from our &lt;code&gt;ref1&lt;/code&gt; and then we put that value to the values object. We will then have this in the database:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;users
  |_ -MEIwCAwrPBePyp4mVv1
        |_ firstName: "John"
        |_ username: "johnwayne"
        |_ email: "john.w@mail.com"
        |_ id: "-MEIwCAwrPBePyp4mVv1"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can use this key to find and target the particular user with specific child.&lt;/p&gt;

&lt;p&gt;Formik is a great tool for creating efficient forms while firebase offers quick setup and authentication options, deployment is also easy to setup through github actions.&lt;/p&gt;

&lt;p&gt;Thank you for reading!&lt;/p&gt;

</description>
      <category>firebase</category>
      <category>formik</category>
      <category>react</category>
    </item>
    <item>
      <title>Create a Private Docker Registry</title>
      <dc:creator>Semir Teskeredzic</dc:creator>
      <pubDate>Sun, 06 Jun 2021 20:34:46 +0000</pubDate>
      <link>https://dev.to/semirteskeredzic/create-a-private-docker-registry-17li</link>
      <guid>https://dev.to/semirteskeredzic/create-a-private-docker-registry-17li</guid>
      <description>&lt;p&gt;Dockerized applications and automated pipelines mean that you will eventually need a docker registry sooner or later.&lt;/p&gt;

&lt;h1&gt;
  
  
  What is a Docker Registry?
&lt;/h1&gt;

&lt;p&gt;It is essentially a place where you store Docker images organized in repositories. You can push images to the remote Docker registry and pull images where you want them.&lt;/p&gt;

&lt;h1&gt;
  
  
  Docker Hub
&lt;/h1&gt;

&lt;p&gt;Nifty service that Docker.com runs is Docker hub or a Docker Registry that has many things automated so you don't have to bother with configuring it on your own server (which we will get to in a bit).&lt;/p&gt;

&lt;p&gt;Free tier is also fairly generous at Docker hub because it provides you with unlimited public repositories and one private repository. More private repositories are available in paid tiers and you can find pricing info here: &lt;a href="https://www.docker.com/pricing"&gt;Docker Pricing&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Create your own private registry
&lt;/h1&gt;

&lt;p&gt;If you want to house your Docker images on your own server, then you have to create a private registry or how the Docker documentation states it, deploy a registry server.&lt;/p&gt;

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

&lt;p&gt;Before deploying a private registry, you will need to have several prerequisites checked:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Server running Ubuntu (preferably latest Ubuntu 20.04) that is properly configured. You can read about it in the post here: &lt;a href="https://dev.to/semirteskeredzic/configure-new-ubuntu-20-04-server-4p4b"&gt;Configure New Ubuntu Server&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Docker &amp;amp; Docker-compose properly installed on the server that will host the Docker registry. You can read about it here: &lt;a href="https://dev.to/semirteskeredzic/docker-docker-compose-on-ubuntu-20-04-server-4h3k"&gt;Install Docker &amp;amp; Docker-compose on Ubuntu server&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Properly installed Nginx. You can read about it here: &lt;a href="https://dev.to/semirteskeredzic/install-nginx-on-ubuntu-20-04-server-12ni"&gt;Install Nginx on Ubuntu server&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Domain name that resolves to your host server (where you will host registries)&lt;/li&gt;
&lt;li&gt;SSL Secured Nginx on your host server&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Installing &amp;amp; Configuring
&lt;/h1&gt;

&lt;p&gt;Since we have to run registry from a docker image there are two ways we will go through here,&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Quick - running with &lt;code&gt;docker&lt;/code&gt; command from the CLI&lt;/li&gt;
&lt;li&gt;Using docker-compose - running with the &lt;code&gt;yml&lt;/code&gt; file using &lt;code&gt;docker-compose&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Before going through each one, go on and create a few directories to keep the things organized:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mkdir docker-registry
$ cd ~/docker-registry
$ mkdir data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Quick
&lt;/h2&gt;

&lt;p&gt;While in our &lt;code&gt;docker-registry&lt;/code&gt; folder, we can run docker registry with just one line of code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker run -d -p 5000:5000 --restart=always --name registry registry:2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will run our registry from the image &lt;code&gt;registry&lt;/code&gt; in background mode with the usage of the port 5000.&lt;br&gt;
This is a great first step just to see it working. However it is not secure enough or configured enough for production-based environments.&lt;br&gt;
Go on and stop the running container by running this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker container stop registry
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Proceed with removing the container alltogether:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker container rm -v registry
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we want to store data to our host server filesystem instead of relying on the data inside the docker volume, we could use this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run -d \
  -p 5000:5000 \
  --restart=always \
  --name registry \
  -v ~/docker-registry/data:/var/lib/registry \
  registry:2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Note: when writing a docker command in multiple lines just use backslash &lt;code&gt;\&lt;/code&gt; at the end of the line and press enter.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Using docker-compose
&lt;/h2&gt;

&lt;p&gt;You can write entire configuration in one &lt;code&gt;yml&lt;/code&gt; file and run it with docker-compose, this way you see the configuration more clearly and you are able to make modifications and see previous configurations.&lt;br&gt;
While in your &lt;code&gt;docker-registry&lt;/code&gt; directory, create and enter edit mode using nano:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ nano docker-compose.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can now enter following code to the file:&lt;br&gt;
&lt;/p&gt;

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

services:
  registry:
    image: registry:2
    restart: always
    ports:
    - "5000:5000"
    environment:
      REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data
    volumes:
      - ./data:/data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can already see that we are using same image, utilizing same port and using volume location &lt;code&gt;~/data&lt;/code&gt; in our filesystem.&lt;br&gt;
You can exit and save using &lt;code&gt;CTRL+X&lt;/code&gt; then &lt;code&gt;Y&lt;/code&gt; and then &lt;code&gt;ENTER&lt;/code&gt;&lt;br&gt;
Run the docker-compose with:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Now your docker registry is up and running.&lt;/p&gt;

&lt;h1&gt;
  
  
  Configure HTTP Authentication
&lt;/h1&gt;

&lt;p&gt;We can put HTTP Authentication with the Nginx using username and password so the access to our server hosting registries is secured with those credentials.&lt;br&gt;
First update local packages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo apt update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then install a package we will use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo apt install apache2-utils -y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will store our credentials in separate folder so go create one and enter it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mkdir ~/docker-registry/auth
$ cd ~/docker-registry/auth
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will now enter following command and you replace &lt;code&gt;username&lt;/code&gt; with the username you want it to be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ htpasswd -Bc registry.password username
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will be prompted for password so enter it as required. If we used a docker-compose file, we need to update it to include credentials. Open docker-compose file using &lt;code&gt;nano&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;$ nano ~/docker-registry/docker-compose.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now alter existing docker-compose using following template:&lt;br&gt;
&lt;/p&gt;

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

services:
  registry:
    image: registry:2
    restart: always
    ports:
    - "5000:5000"
    environment:
      REGISTRY_AUTH: htpasswd
      REGISTRY_AUTH_HTPASSWD_REALM: Registry
      REGISTRY_AUTH_HTPASSWD_PATH: /auth/registry.password
      REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data
    volumes:
      - ./auth:/auth
      - ./data:/data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run your docker-compose:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;If you want to use inline CLI &lt;code&gt;docker&lt;/code&gt; command use this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run -d \
  -p 5000:5000 \
  --restart=always \
  --name registry \
  -e REGISTRY_AUTH=htpasswd \
  -e REGISTRY_AUTH_HTPASSWD_REALM=Registry \
  -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/registry.password \
  -v ~/docker-registry/data:/var/lib/registry \
  registry:2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Secure your host server with SSL
&lt;/h1&gt;

&lt;p&gt;In order for docker-registry to function properly you must have secured HTTPS connection and that requires that you install a certificate provided by Certificate Authority. There is a free SSL certificate provided by Let's Encrypt and you can do this with the help of &lt;code&gt;certbot&lt;/code&gt;&lt;br&gt;
Find the guide here: &lt;a href="https://certbot.eff.org/lets-encrypt/ubuntubionic-nginx"&gt;Certbot Ubuntu installation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Remember that you need to have a domain pointing to your host server IP address before being able to activate Let's encrypt.&lt;/p&gt;
&lt;h1&gt;
  
  
  Check firewall
&lt;/h1&gt;

&lt;p&gt;Check the firewall status with the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo ufw status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And make sure to allow all Nginx that includes HTTPS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo ufw allow 'Nginx Full'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Nginx file Upload size
&lt;/h1&gt;

&lt;p&gt;File upload size is set quite low for nginx when you freshly install and configure it. You need to increase that amount so you can push larger images to your docker registry. Open Nginx configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo nano /etc/nginx/nginx.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now edit the line that says &lt;code&gt;client_max_body_size&lt;/code&gt; in the &lt;code&gt;http&lt;/code&gt; section and set the value to &lt;code&gt;8000m&lt;/code&gt; which sets the maximum size to 8GB. Save changes and exit configuration.&lt;br&gt;
After making any changes in Nginx configuration be sure to restart the Nginx:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo systemctl restart nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Congratulations! You now have a private docker registry that is password protected and HTTPS secured. You can push your own images there and pull it wherever you need them. Use &lt;code&gt;docker&lt;/code&gt; commands to login to your docker-registry just as you would with &lt;code&gt;Docker Hub&lt;/code&gt;, and use push and pull commands in the same way.&lt;/p&gt;

&lt;p&gt;Thank you for reading.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>linux</category>
      <category>ubuntu</category>
    </item>
    <item>
      <title>Install Nginx on Ubuntu 20.04 Server</title>
      <dc:creator>Semir Teskeredzic</dc:creator>
      <pubDate>Mon, 31 May 2021 13:28:12 +0000</pubDate>
      <link>https://dev.to/semirteskeredzic/install-nginx-on-ubuntu-20-04-server-12ni</link>
      <guid>https://dev.to/semirteskeredzic/install-nginx-on-ubuntu-20-04-server-12ni</guid>
      <description>&lt;p&gt;Welcome to the short guide on how to install Nginx on your server running Ubuntu 20.04.&lt;/p&gt;

&lt;h1&gt;
  
  
  A bit about Nginx
&lt;/h1&gt;

&lt;p&gt;So what is Nginx? As per &lt;a href="https://nginx.com"&gt;nginx.com&lt;/a&gt;: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Nginx is open source software for web serving, reverse proxying, caching, load balancing, media streaming, and more. It started out as a web server designed for maximum performance and stability. In addition to its HTTP server capabilities, NGINX can also function as a proxy server for email (IMAP, POP3, and SMTP) and a reverse proxy and load balancer for HTTP, TCP, and UDP servers.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So in short, Nginx is a web server that has many capabilities in serving the content on server to the users.&lt;/p&gt;

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

&lt;p&gt;You have to check that the server you want to install Nginx on is properly configured before proceeding so you can install and configure Nginx without any future issues. You can read about it in the article here: &lt;a href="https://dev.to/semirteskeredzic/configure-new-ubuntu-20-04-server-4p4b"&gt;Configure Ubuntu 20.04 Server&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  1 - Install Nginx
&lt;/h1&gt;

&lt;p&gt;As always, it is a good practice to update local package index before installing new packages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo apt update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can proceed by installing Nginx&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo apt install nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  2 - Configure the firewall
&lt;/h1&gt;

&lt;p&gt;Whether you have firewall enabled or disabled you should enable nginx service in the firewall configuration. Get the list of available application configurations by running following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo ufw app list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see the output similar to this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Output
Available applications:
  Nginx Full
  Nginx HTTP
  Nginx HTTPS
  OpenSSH
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, you can enable &lt;code&gt;Nginx Full&lt;/code&gt; which will enable traffic through port &lt;code&gt;:80&lt;/code&gt; and &lt;code&gt;:443&lt;/code&gt; or you can choose one of them depending whether you require encrypted on unencrypted connection.&lt;br&gt;
Go with HTTP if you are initially setting up nginx but you won't be adding SSL certificates, however if you are going to be adding a certificate later on, you can proceed with &lt;code&gt;Nginx Full&lt;/code&gt;.&lt;br&gt;
You enable option by running this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo ufw allow 'Nginx Full'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  3 - Check if everything works
&lt;/h1&gt;

&lt;p&gt;Run the following command for nginx service to see its status:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ systemctl status nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will provide output where you will see whether the service is running or if it encountered an error and it needs troubleshooting.&lt;/p&gt;

&lt;p&gt;You can check if the Nginx runs and if the firewall is allowing connections by typing your server's ip in the address bar of your internet browser. If you don't know your IP, you can find out by running this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ curl -4 icanhazip.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you enter your server IP address in the browser you should be greeted by the Welcome to Nginx page. If you see that page, your server runs as it should.&lt;/p&gt;

&lt;h1&gt;
  
  
  4 - Manage Nginx
&lt;/h1&gt;

&lt;p&gt;We have mentioned &lt;code&gt;systemctl&lt;/code&gt; command earlier. You can use this command on any process in Ubuntu to query or send control commands to the system manager.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Start (activate)
$ sudo systemctl start nginx

// Restart (Start or restart)
$ sudo systemctl restart nginx

// Stop (deactivate)
$ sudo systemctl stop nginx

// Reload (without losing connection)
$ sudo systemctl reload nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Additionally you can use &lt;code&gt;enable&lt;/code&gt; and &lt;code&gt;disable&lt;/code&gt; with &lt;code&gt;systemctl&lt;/code&gt; to prevent the unit from starting automatically or to enable it to start at the boot.&lt;/p&gt;

&lt;h1&gt;
  
  
  5 - Server Blocks (Optional but recommended)
&lt;/h1&gt;

&lt;p&gt;If you worked with Apache you are familiar with &lt;code&gt;VirtualHost&lt;/code&gt;. Instead of &lt;code&gt;VirtualHost&lt;/code&gt;, Nginx uses &lt;code&gt;Server Blocks&lt;/code&gt; - it allows you to run more than one website on a single machine.&lt;/p&gt;

&lt;p&gt;Ubuntu stores Nginx server blocks configuration files in &lt;code&gt;/etc/nginx/sites-available&lt;/code&gt; directory which are enabled through symlinks (symbolic links) to the &lt;code&gt;/etc/nginx/sites-enabled/&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;On Ubuntu 20.04 one server block is enabled by default and it serves files out of the &lt;code&gt;/var/www/html&lt;/code&gt; directory. This configuration is okay if you are having a single site on one machine, however if you want to run multiple websites on a single machine you should create a different directory structure similar to &lt;code&gt;/var/www/your_domain/html&lt;/code&gt;. After creating the directory, you have to assign ownership to the user, and give the owner permissions to read, write, and execute files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo mkdir -p /var/www/your_domain/html
$ sudo chown -R $USER:$USER /var/www/your_domain/html
$ sudo chmod -R 755 /var/www/your_domain
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can now create a simple test html file inside the html directory. With &lt;code&gt;nano&lt;/code&gt; command you can do it immediately:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ nano /var/www/your_domain/html/index.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the HTML code you want, you can keep it simple&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;html&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;h1&amp;gt;Hello from the website!
    &amp;lt;/h1&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save it by typing &lt;code&gt;CTRL&lt;/code&gt; and &lt;code&gt;X&lt;/code&gt; and then typing &lt;code&gt;Y&lt;/code&gt; and then &lt;code&gt;ENTER&lt;/code&gt;.&lt;br&gt;
Now the Nginx will serve this html file after we create a server block in &lt;code&gt;sites-available&lt;/code&gt; and symlink it to &lt;code&gt;sites-enabled&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This is basic blueprint for the server block that you will create by again running &lt;code&gt;nano&lt;/code&gt; command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo nano /etc/nginx/sites-available/your_domain
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When file edit is open paste this (and don't forget to substitute your_domain with your actual domain)&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 80;
        listen [::]:80;

        root /var/www/your_domain/html;
        index index.html index.htm index.nginx-debian.html;

        server_name your_domain www.your_domain;

        location / {
                try_files $uri $uri/ =404;
        }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we are creating a symlink:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo ln -s /etc/nginx/sites-available/your_domain /etc/nginx/sites-enabled/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Test to make sure there are no syntax errors in any of Nginx files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo nginx -t
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If everything checks out, restart Nginx:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo systemctl restart nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Congrats! You have successfully installed and configured Nginx on your Ubuntu 20.04 Server. Thank you for reading!&lt;/p&gt;

</description>
      <category>nginx</category>
      <category>devops</category>
      <category>ubuntu</category>
      <category>linux</category>
    </item>
    <item>
      <title>Docker &amp; Docker-compose on Ubuntu 20.04 Server</title>
      <dc:creator>Semir Teskeredzic</dc:creator>
      <pubDate>Thu, 27 May 2021 12:14:15 +0000</pubDate>
      <link>https://dev.to/semirteskeredzic/docker-docker-compose-on-ubuntu-20-04-server-4h3k</link>
      <guid>https://dev.to/semirteskeredzic/docker-docker-compose-on-ubuntu-20-04-server-4h3k</guid>
      <description>&lt;p&gt;Docker is a powerful application that lets you run your applications in a contained environment so everything that happens is (more or less) isolated through the use of Containers. It is however different from Virtual machines, because it uses OS Kernel from the host machine while Virtual machines spin up their own. You can watch how Nana explains it in this video: &lt;a href="https://www.youtube.com/watch?v=5GanJdbHlAA"&gt;Docker vs Virtual Machine | simply explained || Docker Tutorial 6&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Prerequisite
&lt;/h1&gt;

&lt;p&gt;As a prerequisite for installing and using Docker &amp;amp; Docker-compose on Ubuntu server you will need it initially configured and set up. I've made a post about initial configuration for Ubuntu 20.04 server, so you can read it here: &lt;a href="https://dev.to/semirteskeredzic/configure-new-ubuntu-20-04-server-4p4b"&gt;Configure new Ubuntu 20.04 server&lt;/a&gt; &lt;/p&gt;

&lt;h1&gt;
  
  
  1 - Install Docker
&lt;/h1&gt;

&lt;p&gt;Before installing any new package, it is recommended to update the list of packages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo apt update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(you will need to enter your user account password because you are using &lt;code&gt;sudo&lt;/code&gt; command for elevated privileges)&lt;/p&gt;

&lt;p&gt;Then, you need to install a couple of packages that let &lt;code&gt;apt&lt;/code&gt; use packages over HTTPS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo apt install apt-transport-https ca-certificates curl software-properties-common
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next add GPG key for the Docker repository:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Continue by adding the Docker repository to your APT sources:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Repeat the update of the package database:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo apt update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tell system that you will install Docker from Docker repository:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ apt-cache policy docker-ce
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After seeing the output with the information about candidate installation, go on with installing Docker:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo apt install docker-ce
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Check that the Docker is running with this command:&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo systemctl status docker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  2 - Run Docker command without Sudo (Optional)
&lt;/h1&gt;

&lt;p&gt;If you try to run &lt;code&gt;docker&lt;/code&gt; command without &lt;code&gt;sudo&lt;/code&gt; prefix or if the user is not in the docker group you will get the message that the &lt;code&gt;docker&lt;/code&gt; can't connect to the Docker daemon. In order to fix this, you will need to add your username to the &lt;code&gt;docker&lt;/code&gt; group (you will use this exact command if you want to add the user that you are currently logged in with, if you want to add another user, replace ${USER} with desired username):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo usermod -aG docker ${USER}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To apply the new membership you should log out of the server and log back in.&lt;br&gt;
If you want to check whether the user is in the docker group use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ id -nG
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  3 - Docker images &amp;amp; Containers
&lt;/h1&gt;

&lt;p&gt;Now that the Docker is installed, you can run &lt;code&gt;docker&lt;/code&gt; command, the syntax is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker [option] [command] [arguments]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Containers are built from Docker images, by default Docker pulls those images from the Docker Hub (i.e. a registry for the Docker images).&lt;br&gt;
When you want to access an image you simply run this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker run postgres
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will first try to find image locally, if it doesn't it will pull the image from the Docker hub and create a container from the pulled image.&lt;/p&gt;

&lt;p&gt;You can search available images with browser on Docker Hub: &lt;a href="https://hub.docker.com/search?q=&amp;amp;type=image"&gt;https://hub.docker.com/search?q=&amp;amp;type=image&lt;/a&gt;, or you can use CLI command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker search postgres
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you want to run a Docker container it is a good idea to have shell access to the container. You enable this kind of access with &lt;code&gt;-i&lt;/code&gt; and &lt;code&gt;-t&lt;/code&gt; switches:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker run -it postgres
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can work inside the container and for example run installation of packages for that container only.&lt;/p&gt;

&lt;p&gt;If you want to see running Docker containers you can use this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker ps
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Additionally use &lt;code&gt;-a&lt;/code&gt; switch to see active and inactive containers&lt;/p&gt;

&lt;p&gt;For troubleshooting purposes, you can see logs for the container by copying &lt;code&gt;CONTAINER ID&lt;/code&gt; obtained after &lt;code&gt;docker ps&lt;/code&gt; and running this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker logs [CONTAINER_ID]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  4 - Docker-compose
&lt;/h1&gt;

&lt;p&gt;Before installing Docker-compose we will have to check what is the latest version, you can do that on the &lt;a href="https://github.com/docker/compose/releases"&gt;Release page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;At the moment of writing this post, the latest release is &lt;code&gt;1.29.2&lt;/code&gt; so we will use following commands to install this release (for different release enter a different release number in the following command):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Set permissions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo chmod +x /usr/local/bin/docker-compose
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To verify the installation run:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;We use docker-compose with docker-compose.yml files, in there we can define multiple services with corresponding images and configurations. We execute Docker compose with the &lt;code&gt;up&lt;/code&gt; command (if you want to run in detached mode add &lt;code&gt;-d&lt;/code&gt; switch which will run it in the background):&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;You have to execute this command inside the directory of your &lt;code&gt;docker-compose.yml&lt;/code&gt; file. Similar to &lt;code&gt;docker&lt;/code&gt; commands, running:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;will show you information about the running containers and their state together with port redirections.&lt;/p&gt;

&lt;p&gt;This concludes basic installation and use of Docker and Docker-compose on your Ubuntu server. Thank you for reading!&lt;/p&gt;

</description>
      <category>docker</category>
      <category>devops</category>
      <category>ubuntu</category>
      <category>linux</category>
    </item>
    <item>
      <title>Configure new Ubuntu 20.04 Server</title>
      <dc:creator>Semir Teskeredzic</dc:creator>
      <pubDate>Tue, 25 May 2021 08:04:36 +0000</pubDate>
      <link>https://dev.to/semirteskeredzic/configure-new-ubuntu-20-04-server-4p4b</link>
      <guid>https://dev.to/semirteskeredzic/configure-new-ubuntu-20-04-server-4p4b</guid>
      <description>&lt;p&gt;Probably all server related work will require you to have properly configured server as a prerequisite. Servers that run Ubuntu are widely used so I will go through several necessary steps needed when you spin up new Ubuntu server.&lt;/p&gt;

&lt;p&gt;First you will need to have a root access, whether through Password login or using previously configured SSH key.&lt;/p&gt;

&lt;h1&gt;
  
  
  1 - Log in
&lt;/h1&gt;

&lt;p&gt;In order to do any kind of operations on the server, you will have to log in using SSH tunnel which is basically an encrypted SSH connection with the remote host. You will need to know your server's public ip address so you could use this command in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ssh root@server_public_ip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you are using password authentication, enter your root password in the prompt (in terminal passwords don't appear while you type so just press enter after you are done because it is there even if it seems that it is not).&lt;br&gt;
If you are using SSH key authentication, the server will log you in automatically if everything is ok (if you entered a passphrase for your SSH key while creating it, you will have to enter it again here).&lt;/p&gt;

&lt;p&gt;Since the root user has literally all the privileges, it is not a wise idea from a security and usability perspective to use it as a main user on a day-to-day basis. This is why we will create a new user that will have many administrative privileges that enable you to perform tasks while reducing the security or accidental issues.&lt;/p&gt;
&lt;h1&gt;
  
  
  2 - New non Root User
&lt;/h1&gt;

&lt;p&gt;You will have to perform these steps while you are logged in as root user. Creating user is simple with a &lt;code&gt;adduser&lt;/code&gt; command, we will create a new user named jenny:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# adduser jenny
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will be asked to enter additional information including account password, use a strong one and fill in other prompts as you prefer (or just skip them by pressing enter).&lt;/p&gt;

&lt;h1&gt;
  
  
  3 - Jenny becomes Administrator
&lt;/h1&gt;

&lt;p&gt;Currently, Jenny is a regular user on our server and that means that it is quite limited in terms of Server administration. We need to give Jenny privileges so she can install, update, and manage packages, access restricted files etc. We will add Jenny to &lt;code&gt;sudo&lt;/code&gt; group, this means that Jenny will be able to use sudo command whenever elevated privileges are required. While still logged in as a root enter a following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# usermod -aG sudo jenny
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  4 - Set up a basic firewall (Optional)
&lt;/h1&gt;

&lt;p&gt;If you require restricted access to certain services on your server, you can use UFW firewall to manage that access. You will have to set up access for each service upon installation so it can be accessed. Now, we will set up OpenSSH as allowed in our firewall (OpenSSH is the service we are currently using in order to access our server).&lt;br&gt;
Use this command to see which services have their profile registered with UFW:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# ufw app list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Available applications:
  OpenSSH
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In order to tell the firewall to allow SSH connections, we use allow command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# ufw allow OpenSSH
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After we allowed OpenSSH, we can enable the firewall by using enable command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# ufw enable
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When prompted, enter &lt;code&gt;y&lt;/code&gt; to finish enabling the firewall. You can see the current status with the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# ufw status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  5 - Configure external access for the new user
&lt;/h1&gt;

&lt;p&gt;You can now log out from root account and log in with your newly created account. Type &lt;code&gt;exit&lt;/code&gt; to close the SSH connection with the remote host. Depending on the type of authentication root user uses, you will configure the external access differently.&lt;/p&gt;

&lt;h2&gt;
  
  
  Root account uses password authentication
&lt;/h2&gt;

&lt;p&gt;This means that the password authentication is enabled so you can simply ssh to your remote server by using following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ssh jenny@server_public_ip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will be prompted for password after which you will be logged in as a new user. For any action that requires elevated privileges you will use &lt;code&gt;sudo&lt;/code&gt; command before the desired action. This will again prompt you for the user password so you can type it in and press enter.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo command
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Root account uses SSH key authentication
&lt;/h2&gt;

&lt;p&gt;When root user uses SSH key authentication it means that the password authentication is disabled. We have to make a copy of local public key (which is already in the root account's file on server) to the new user's &lt;code&gt;authorized_keys&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Make sure you are logged in as root user to perform this action.&lt;/p&gt;

&lt;p&gt;We will use &lt;code&gt;rsync&lt;/code&gt; command to copy the files while maintaining proper permissions and ownership. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;bold&lt;/strong&gt;Important:&lt;strong&gt;bold&lt;/strong&gt;&lt;br&gt;
When you use &lt;code&gt;rsync&lt;/code&gt; you need to make sure that the source directory &lt;code&gt;~/.ssh&lt;/code&gt; &lt;strong&gt;bold&lt;/strong&gt;is not*&lt;em&gt;bold&lt;/em&gt;* with trailing slash.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# rsync --archive --chown=jenny:jenny ~/.ssh /home/jenny
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  6 - Server is configured
&lt;/h1&gt;

&lt;p&gt;Congrats! You have initially configured your server and now you can continue with installing services you need to make it work.&lt;/p&gt;

&lt;p&gt;Thank you for reading.&lt;/p&gt;

</description>
      <category>ubuntu</category>
      <category>devops</category>
      <category>linux</category>
    </item>
  </channel>
</rss>
