<?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: Saurabh Bomble</title>
    <description>The latest articles on DEV Community by Saurabh Bomble (@saurabh619).</description>
    <link>https://dev.to/saurabh619</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%2F297853%2F41854971-6985-4c17-9e58-0fe2026d9b8e.png</url>
      <title>DEV Community: Saurabh Bomble</title>
      <link>https://dev.to/saurabh619</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/saurabh619"/>
    <language>en</language>
    <item>
      <title>Basic load balancer with NGINX</title>
      <dc:creator>Saurabh Bomble</dc:creator>
      <pubDate>Tue, 16 May 2023 06:20:00 +0000</pubDate>
      <link>https://dev.to/saurabh619/basic-load-balancer-with-nginx-11df</link>
      <guid>https://dev.to/saurabh619/basic-load-balancer-with-nginx-11df</guid>
      <description>&lt;p&gt;NGINX is an advanced web browser that can be used as a reverse proxy, load balancer, mail proxy, and caching mechanism. In this short tutorial, we scale a golang REST API service with docker-compose and distribute all the load from the client to these multiple service instances.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--43p84Kry--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pf317d3mk45n58cjiqwn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--43p84Kry--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pf317d3mk45n58cjiqwn.png" alt="System diagram" width="800" height="359"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The client makes an API call to &lt;code&gt;http://localhost:8000/&lt;/code&gt; endpoint, which hits the nginx service that internally proxies the request to one of the 3 instances of the REST servers running on the port &lt;code&gt;8000&lt;/code&gt;. We will be using the &lt;a href="https://www.nginx.com/resources/glossary/round-robin-load-balancing/"&gt;Round robin&lt;/a&gt; load-balancing technique that can help us to almost evenly distribute the load across every instance.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;build golang servers image with Dockerfile&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;golang:1.18-alpine&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;builder&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; /app
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nv"&gt;CGO_ENABLED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0 &lt;span class="nv"&gt;GOOS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;linux go build &lt;span class="nt"&gt;-o&lt;/span&gt; app cmd/api/main.go

&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;alpine:latest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;production&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=builder /app/app .&lt;/span&gt;

&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; [ "./app" ]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;docker-compose file -&lt;/strong&gt; run the golang servers and nginx load balancer&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;version: "3.8"

services:
  rest_api:
    build:
      context: ./server
      dockerfile: Dockerfile
    environment:
      - PORT=:8000
    networks:
      - server-network
    command: /start

  nginx:
    image: nginx:latest
    volumes:
      - ./conf.d/nginx.conf:/etc/nginx/nginx.conf
    depends_on:
      - rest_api
    ports:
      - 8000:8000
    networks:
      - server-network

networks:
  server-network:
    driver: bridge
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;nginx conf file&lt;/strong&gt; - We'll define events and set the expected maximum client concurrent connections to 1024. We can define a group of REST servers(image=&lt;strong&gt;&lt;em&gt;rest_api&lt;/em&gt;&lt;/strong&gt;) inside the &lt;strong&gt;upstream block.&lt;/strong&gt; We can also mention the load balancing method inside the &lt;strong&gt;upstream block&lt;/strong&gt;. NGINX server will listen on the port &lt;code&gt;8000&lt;/code&gt; of the host. NGINX will proxy all the requests hitting at &lt;code&gt;/&lt;/code&gt; route to &lt;code&gt;app_servers&lt;/code&gt; group.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="k"&gt;events&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;worker_connections&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;http&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;upstream&lt;/span&gt; &lt;span class="s"&gt;app_servers&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;# default load balancing method is Round Robin&lt;/span&gt;
        &lt;span class="c1"&gt;# other ex. least_conn, ip_hash, etc&lt;/span&gt;
        &lt;span class="kn"&gt;server&lt;/span&gt; &lt;span class="s"&gt;rest_api:8000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kn"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;8000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kn"&gt;proxy_pass&lt;/span&gt; &lt;span class="s"&gt;http://app_servers&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;Host&lt;/span&gt; &lt;span class="nv"&gt;$host&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;X-Real-IP&lt;/span&gt; &lt;span class="nv"&gt;$remote_addr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;X-Forwarded-For&lt;/span&gt; &lt;span class="nv"&gt;$proxy_add_x_forwarded_for&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

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

&lt;p&gt;Now we can start multiple instances of golang REST API servers with the following command -&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;docker-compose up &lt;span class="nt"&gt;--build&lt;/span&gt; &lt;span class="nt"&gt;--scale&lt;/span&gt; &lt;span class="nv"&gt;rest_api&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;NGINX will serve the same request through different REST server instances -&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GiKTCb6F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b2o7ikp6dpnh5dxy26mh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GiKTCb6F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b2o7ikp6dpnh5dxy26mh.png" alt="Output 1" width="800" height="264"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XE4RvcbN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wfu0xksf3dcfasoex108.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XE4RvcbN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wfu0xksf3dcfasoex108.png" alt="Output 2" width="800" height="264"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EnVbRhR7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kqsnakfuip0ctz4l6bs1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EnVbRhR7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kqsnakfuip0ctz4l6bs1.png" alt="Output 3" width="800" height="262"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>systemdesign</category>
      <category>nginx</category>
      <category>go</category>
    </item>
    <item>
      <title>Twelve Factor app</title>
      <dc:creator>Saurabh Bomble</dc:creator>
      <pubDate>Tue, 25 Apr 2023 07:51:02 +0000</pubDate>
      <link>https://dev.to/saurabh619/twelve-factor-app-1lpf</link>
      <guid>https://dev.to/saurabh619/twelve-factor-app-1lpf</guid>
      <description>&lt;p&gt;The twelve factor methodology is a language and platform agnostic set of design principles that can help to build portable, scalable, maintainable, compatible, and robust apps rapidly. It was started by the Heroku engineering team.&lt;/p&gt;

&lt;p&gt;Reading - &lt;a href="https://12factor.net/"&gt;https://12factor.net/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;As per the documentation -&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The twelve-factor app is a methodology for building software-as-a-service apps that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Use &lt;strong&gt;declarative&lt;/strong&gt; formats for setup automation, to minimize time and cost for new developers joining the project.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Have a &lt;strong&gt;clean contract&lt;/strong&gt; with the underlying operating system, offering &lt;strong&gt;maximum portability&lt;/strong&gt; between execution environments.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Are suitable for &lt;strong&gt;deployment&lt;/strong&gt; on modern &lt;strong&gt;cloud platforms&lt;/strong&gt;, obviating the need for servers and systems administration.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Minimize divergence&lt;/strong&gt; between development and production, enabling &lt;strong&gt;continuous deployment&lt;/strong&gt; for maximum agility.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;And can &lt;strong&gt;scale up&lt;/strong&gt; without significant changes to tooling, architecture, or development practices.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;The Twelve Factors&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Codebase
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;one codebase for an app tracked by version control where team members push the code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;microservices can have different codebases since they are essentially different apps.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;within each codebase, we can have multiple deployments - dev/staging/test/prod envs.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Explicitly declare and isolate dependencies
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;twelve-factor app declares all the dependencies completely and exactly, via a &lt;em&gt;dependency declaration&lt;/em&gt; manifest ex. requirements.txt, package.json files.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;we can install app-related dependencies by creating virtual environments for the app to avoid interference from outside system dependencies. ex. node_modules, python venvs, etc.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;docker containers help to run our apps in a self-contained environment that is isolated from the host system.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Config
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;An app’s &lt;em&gt;config&lt;/em&gt; is everything likely to vary between deploys (staging, production, developer environments, etc). This includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Resource handles to the database, Memcached, and other &lt;em&gt;backing services&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Credentials to external services such as Amazon S3 or Twitter.&lt;/li&gt;
&lt;li&gt;Per-deploy values such as the canonical hostname for the deploy.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;&lt;p&gt;twelve-factor app stores configs of the app in env files that are different for different deployment environments.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Backing services
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;backing services are shared resources that are attached externally to twelve-factor apps.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;examples include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;databases&lt;/em&gt; - MySQL, Postgres, Mongo, etc.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;messaging/queueing systems&lt;/em&gt; - RabbitMQ, MQTT, Beanstalked, etc.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;SMTP&lt;/em&gt; - postfix &lt;/li&gt;
&lt;li&gt;
&lt;em&gt;caching systems&lt;/em&gt; - Redis, Memcached, etc.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5. Build, release, run
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Strictly separate build, release, and run stages.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;build stage -&lt;/strong&gt; converts a code repo into an executable bundle known as a build(an executable file)&lt;em&gt;.&lt;/em&gt; The build stage fetches dependencies and compiles binaries, and assets.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;release stage -&lt;/strong&gt; build from the previous stage along with configs makes a release with a unique release version/timestamp/id. The release is ready to be executed immediately in the execution environment. Releases are append-only ledgers and a release cannot be mutated once it is created. Every small change in the codebase should create a new release. twelve-factor app allows rollbacks to previous releases.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;run stage (aka runtime) -&lt;/strong&gt; runs the app in an execution environment against the release.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  6. Processes
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Twelve-factor processes are stateless and &lt;a href="http://en.wikipedia.org/wiki/Shared_nothing_architecture"&gt;&lt;strong&gt;share-nothing&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;.&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If the same app is running on multiple processes and any information that is needed to be shared across all processes should be stored in a stateful &lt;em&gt;backing service&lt;/em&gt;, typically a database/cache.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The data stored on a process won’t be available across other apps running across other processes.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  7. Port binding
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;All the services needed to be exported should be connected with ports.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The web app &lt;strong&gt;exports HTTP as a service by binding to a port&lt;/strong&gt;, and listening to requests coming in on that port.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  8. Concurrency
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;In the twelve-factor app, processes are first-class citizens.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Apps should scale out horizontally not vertically by running multiple instances of the app on different machines concurrently.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The app should be built keeping concurrency in mind.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  9. Disposability
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The twelve-factor app’s processes are &lt;em&gt;disposable&lt;/em&gt;, meaning they can be started or stopped at a moment’s notice.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This facilitates fast elastic scaling, rapid deployment of code or config changes, and robustness of production deploys.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Processes should strive to &lt;strong&gt;minimize startup time.&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;codebase should not have any complex start scripts.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Processes &lt;strong&gt;shut down gracefully when they receive a&lt;/strong&gt; &lt;a href="http://en.wikipedia.org/wiki/SIGTERM"&gt;&lt;strong&gt;SIGTERM&lt;/strong&gt;&lt;/a&gt; signal from the process manager.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;docker stop&lt;/code&gt; sends a &lt;code&gt;SIGTERM&lt;/code&gt; signal and after a grace period if the container is not stopped docker sends a &lt;code&gt;SIGKILL&lt;/code&gt; signal to forcefully terminate the process running inside the container.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;During the grace period after &lt;code&gt;SIGTERM&lt;/code&gt; signal, apps/processes can stop accepting new requests and complete current requests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The app should be able to handle &lt;code&gt;SIGTERM&lt;/code&gt; signals to avoid any discrepancies.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  10. Dev/Prod parity
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Keep development, staging, and production as similar as possible.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The twelve factor app is designed for continuous deployment by keeping the gap between development and production small.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Possible gaps :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Make the &lt;strong&gt;time gap&lt;/strong&gt; small: a developer may write code and have it deployed hours or even just minutes later.&lt;/li&gt;
&lt;li&gt;Make the &lt;strong&gt;personnel gap&lt;/strong&gt; small: developers who wrote code are closely involved in deploying it and watching its behaviour in production.&lt;/li&gt;
&lt;li&gt;Make the &lt;strong&gt;tools gap&lt;/strong&gt; small: keep development and production as similar as possible.&lt;/li&gt;
&lt;li&gt;The twelve-factor developer resists the urge to use different backing services between development and production.&lt;/li&gt;
&lt;li&gt;
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1fgh-qsR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ivpjb3570rfy7n1hyrih.png" alt="Image description" width="800" height="200"&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  11. Logs
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Treat logs as event streams.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Logs are the stream of aggregated, time-ordered events collected from the output streams of all running processes and backing services.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We can’t store logs on the containers as they get destroyed and recreated very often, so we can lose them.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Writing logs to a centralized backing service is also discouraged as it leads to tight coupling.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  12. Admin processes
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;one-time admin operations involve running a migration, seeding a database, or resetting some database records.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;All the one-time admin operations should be run on different processes but on an identical setup.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>backend</category>
      <category>cleancode</category>
      <category>python</category>
      <category>node</category>
    </item>
    <item>
      <title>Aggregation in MongoDB</title>
      <dc:creator>Saurabh Bomble</dc:creator>
      <pubDate>Fri, 15 Apr 2022 10:45:27 +0000</pubDate>
      <link>https://dev.to/saurabh619/aggregation-in-mongodb-2b4c</link>
      <guid>https://dev.to/saurabh619/aggregation-in-mongodb-2b4c</guid>
      <description>&lt;p&gt;Hello, devs 👋&lt;/p&gt;

&lt;p&gt;In this blog, we will learn the basics of the MongoDB aggregation framework to filter, sort, group, and transform our MongoDB results. MongoDB helps us to do all these operations through aggregation pipelines which are a series of operations that process data documents sequentially.&lt;/p&gt;

&lt;p&gt;For practice, we can use - &lt;a href="https://mongoplayground.net/"&gt;Mongo playground&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Input docs
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[
  {
    "key": 1,
    username: "saurabh",
    age: 18,
    languages: [
      "c",
      "c++"
    ]
  },
  {
    "key": 2,
    username: "leonord",
    age: 22,
    languages: [
      "c",
      "c++",
      "java"
    ]
  },
  {
    "key": 3,
    username: "sheldon",
    age: 14,
    languages: [
      "c",
      "c++",
      "java",
      "python"
    ]
  },
  {
    "key": 4,
    username: "howard",
    age: 32,
    languages: [
      "c",
      "c++",
      "java",
      "python",
      "dart"
    ]
  },
  {
    "key": 5,
    username: "raj",
    age: 5,
    languages: [
      "c",
      "c++",
      "java",
      "python",
      "dart",
      "ts"
    ]
  }
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;1. $group aggregation&lt;/strong&gt; = used for grouping and summarizing documents. We must specify an &lt;code&gt;_id&lt;/code&gt; field with a valid expression.&lt;/p&gt;

&lt;h4&gt;
  
  
  Query
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;db.collection.aggregate([
  {
    $group: {
      _id: "table_stats",
      // Get count of all docs in the collection
      count: {
        $sum: 1
      },
      // Get age stats by grouping age field
      avgAge: {
        $avg: "$age"
      },
      maxAge: {
        $max: "$age"
      },
      minAge: {
        $min: "$age"
      },
      sumAge: {
        $sum: "$age"
      },
      // Get all usernames by grouping username field
      allUsernames: {
        $push: "$username"
      },
      // Get username of first doc
      firstUsername: {
        $first: "$username"
      },
      // Get username of last doc
      lastUsername: {
        $last: "$username"
      }
    }
  }
])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Result
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[
  {
    "_id": "table_stats",
    "allUsernames": [
      "saurabh",
      "leonord",
      "sheldon",
      "howard",
      "raj"
    ],
    "avgAge": 18.2,
    "count": 5,
    "firstUsername": "saurabh",
    "lastUsername": "raj",
    "maxAge": 32,
    "minAge": 5,
    "sumAge": 91
  }
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. $match aggregation&lt;/strong&gt; = This is used to reduce the number of docs in the result by filtering.&lt;/p&gt;

&lt;h4&gt;
  
  
  Query
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Match all docs where `age` is greater than 20 or equal to 20

db.collection.aggregate([
  {
    "$match": {
      age: {
        $gte: 20
      }
    }
  }
])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Result
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[
  {
    "_id": ObjectId("5a934e000102030405000001"),
    "age": 22,
    "key": 2,
    "languages": [
      "c",
      "c++",
      "java"
    ],
    "username": "leonord"
  },
  {
    "_id": ObjectId("5a934e000102030405000003"),
    "age": 32,
    "key": 4,
    "languages": [
      "c",
      "c++",
      "java",
      "python",
      "dart"
    ],
    "username": "howard"
  }
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Query
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Match all docs that have languages either `python` or `dart` or both

db.collection.aggregate([
  {
    "$match": {
      languages: {
        $in: [
          "python",
          "dart"
        ]
      }
    }
  }
])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Result
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[
  {
    "_id": ObjectId("5a934e000102030405000002"),
    "age": 14,
    "key": 3,
    "languages": [
      "c",
      "c++",
      "java",
      "python"
    ],
    "username": "sheldon"
  },
  {
    "_id": ObjectId("5a934e000102030405000003"),
    "age": 32,
    "key": 4,
    "languages": [
      "c",
      "c++",
      "java",
      "python",
      "dart"
    ],
    "username": "howard"
  },
  {
    "_id": ObjectId("5a934e000102030405000004"),
    "age": 5,
    "key": 5,
    "languages": [
      "c",
      "c++",
      "java",
      "python",
      "dart",
      "ts"
    ],
    "username": "raj"
  }
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Query
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Match all docs with username `saurabh`

db.collection.aggregate([
  {
    "$match": {
      username: {
        $eq: "saurabh"
      }
    }
  }
])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Result
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[
  {
    "_id": ObjectId("5a934e000102030405000000"),
    "age": 18,
    "key": 1,
    "languages": [
      "c",
      "c++"
    ],
    "username": "saurabh"
  }
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Some of the match operators &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;$gte&lt;/code&gt; = Matches if values are greater or equal to the given value.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;$lte&lt;/code&gt; = Matches if values are less or equal to the given value.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;$lt&lt;/code&gt; = Matches if values are less than the given value.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;$gt&lt;/code&gt; = Matches if values are greater than the given value.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;$eq&lt;/code&gt; = Matches values that are equal to the given value.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;$ne&lt;/code&gt; = Matches values that are not equal to the given value.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;$in&lt;/code&gt; = Matches any of the values in an array.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;$nin&lt;/code&gt; = Matches none of the values specified in an array.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. $skip and $limit aggregation&lt;/strong&gt; = $skip takes a positive integer that specifies the maximum number of documents to skip. $limit limits the number of documents to look at, by the given number starting from the current positions.&lt;/p&gt;

&lt;h5&gt;
  
  
  Without skip and limit
&lt;/h5&gt;

&lt;h4&gt;
  
  
  Query
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Get all docs with username lexicographically less than or equal to "saurabh"

db.collection.aggregate([
  {
    "$match": {
      username: {
        $lte: "saurabh"
      }
    }
  },
  // ignore this aggregation, for now, we'll look into it later
  {
    $project: {
      "languages": 0,
      "key": 0,
      "id": 0
    }
  }
])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Result
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[
  {
    "_id": ObjectId("5a934e000102030405000000"),
    "age": 18,
    "username": "saurabh"
  },
  {
    "_id": ObjectId("5a934e000102030405000001"),
    "age": 22,
    "username": "leonord"
  },
  {
    "_id": ObjectId("5a934e000102030405000003"),
    "age": 32,
    "username": "howard"
  },
  {
    "_id": ObjectId("5a934e000102030405000004"),
    "age": 5,
    "username": "raj"
  }
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Without skip = 1 and limit = 2
&lt;/h5&gt;

&lt;h4&gt;
  
  
  Query
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Skip the first doc ($skip) and return next 2 docs ($limit)

db.collection.aggregate([
  {
    "$match": {
      username: {
        $lte: "saurabh"
      }
    }
  },
  {
    $skip: 1
  },
  {
    $limit: 2
  },
  // ignore this aggregation for now
  {
    $project: {
      "languages": 0,
      "key": 0,
      "id": 0
    }
  }
])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Result
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[
  {
    "_id": ObjectId("5a934e000102030405000001"),
    "age": 22,
    "username": "leonord"
  },
  {
    "_id": ObjectId("5a934e000102030405000003"),
    "age": 32,
    "username": "howard"
  }
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4. $sort aggregation&lt;/strong&gt; = Sorts all input documents and returns them to the pipeline in sorted order. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;1 = sort ascending,    -1 = sort descending.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Query
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Get all the docs sorted in ascending order on the `age` field

db.collection.aggregate([
  {
    $sort: {
      age: 1
    }
  },
  // ignore this aggregation for now
  {
    $project: {
      "languages": 0,
      "key": 0,
      "id": 0
    }
  }
])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Result
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[
  {
    "_id": ObjectId("5a934e000102030405000003"),
    "age": 32,
    "username": "howard"
  },
  {
    "_id": ObjectId("5a934e000102030405000001"),
    "age": 22,
    "username": "leonord"
  },
  {
    "_id": ObjectId("5a934e000102030405000000"),
    "age": 18,
    "username": "saurabh"
  },
  {
    "_id": ObjectId("5a934e000102030405000002"),
    "age": 14,
    "username": "sheldon"
  },
  {
    "_id": ObjectId("5a934e000102030405000004"),
    "age": 5,
    "username": "raj"
  }
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;*&lt;em&gt;5. $unwind aggregation *&lt;/em&gt; = This is used to unwind documents that are using arrays. &lt;/p&gt;

&lt;h4&gt;
  
  
  Query
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;db.collection.aggregate([
  {
    $unwind: "$languages"
  },
])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Result
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[
  {
    "_id": ObjectId("5a934e000102030405000000"),
    "age": 18,
    "key": 1,
    "languages": "c",
    "username": "saurabh"
  },
  {
    "_id": ObjectId("5a934e000102030405000000"),
    "age": 18,
    "key": 1,
    "languages": "c++",
    "username": "saurabh"
  },
  {
    "_id": ObjectId("5a934e000102030405000001"),
    "age": 22,
    "key": 2,
    "languages": "c",
    "username": "leonord"
  },
  {
    "_id": ObjectId("5a934e000102030405000001"),
    "age": 22,
    "key": 2,
    "languages": "c++",
    "username": "leonord"
  },
  {
    "_id": ObjectId("5a934e000102030405000001"),
    "age": 22,
    "key": 2,
    "languages": "java",
    "username": "leonord"
  },
  {
    "_id": ObjectId("5a934e000102030405000002"),
    "age": 14,
    "key": 3,
    "languages": "c",
    "username": "sheldon"
  },
  {
    "_id": ObjectId("5a934e000102030405000002"),
    "age": 14,
    "key": 3,
    "languages": "c++",
    "username": "sheldon"
  },
  {
    "_id": ObjectId("5a934e000102030405000002"),
    "age": 14,
    "key": 3,
    "languages": "java",
    "username": "sheldon"
  },
  {
    "_id": ObjectId("5a934e000102030405000002"),
    "age": 14,
    "key": 3,
    "languages": "python",
    "username": "sheldon"
  },
  {
    "_id": ObjectId("5a934e000102030405000003"),
    "age": 32,
    "key": 4,
    "languages": "c",
    "username": "howard"
  },
  {
    "_id": ObjectId("5a934e000102030405000003"),
    "age": 32,
    "key": 4,
    "languages": "c++",
    "username": "howard"
  },
  {
    "_id": ObjectId("5a934e000102030405000003"),
    "age": 32,
    "key": 4,
    "languages": "java",
    "username": "howard"
  },
  {
    "_id": ObjectId("5a934e000102030405000003"),
    "age": 32,
    "key": 4,
    "languages": "python",
    "username": "howard"
  },
  {
    "_id": ObjectId("5a934e000102030405000003"),
    "age": 32,
    "key": 4,
    "languages": "dart",
    "username": "howard"
  },
  {
    "_id": ObjectId("5a934e000102030405000004"),
    "age": 5,
    "key": 5,
    "languages": "c",
    "username": "raj"
  },
  {
    "_id": ObjectId("5a934e000102030405000004"),
    "age": 5,
    "key": 5,
    "languages": "c++",
    "username": "raj"
  },
  {
    "_id": ObjectId("5a934e000102030405000004"),
    "age": 5,
    "key": 5,
    "languages": "java",
    "username": "raj"
  },
  {
    "_id": ObjectId("5a934e000102030405000004"),
    "age": 5,
    "key": 5,
    "languages": "python",
    "username": "raj"
  },
  {
    "_id": ObjectId("5a934e000102030405000004"),
    "age": 5,
    "key": 5,
    "languages": "dart",
    "username": "raj"
  },
  {
    "_id": ObjectId("5a934e000102030405000004"),
    "age": 5,
    "key": 5,
    "languages": "ts",
    "username": "raj"
  }
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Query
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;db.collection.aggregate([
  {
    $unwind: "$languages"
  },
  {
    $match: {
      username: "saurabh"
    }
  }
])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Result
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[
  {
    "_id": ObjectId("5a934e000102030405000000"),
    "age": 18,
    "key": 1,
    "languages": "c",
    "username": "saurabh"
  },
  {
    "_id": ObjectId("5a934e000102030405000000"),
    "age": 18,
    "key": 1,
    "languages": "c++",
    "username": "saurabh"
  }
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;6. $project aggregation&lt;/strong&gt; = Get some specific fields from a collection by giving the keys values as 0 (exclude) or 1 (include)&lt;/p&gt;

&lt;h4&gt;
  
  
  Basic Query
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;db.collection.aggregate([
  {
    $project: {
      username: 1,
      languages: 1
    }
  },
  {
    $unwind: "$languages"
  },
  {
    $match: {
      username: "saurabh"
    }
  }
])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Result
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[
  {
    "_id": ObjectId("5a934e000102030405000000"),
    "languages": "c",
    "username": "saurabh"
  },
  {
    "_id": ObjectId("5a934e000102030405000000"),
    "languages": "c++",
    "username": "saurabh"
  }
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Query with update column names
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;db.collection.aggregate([
  {
    $project: {
      "system_username": "$username",
      "system_languages": "$languages"
    }
  },
  {
    $unwind: "$system_languages"
  },
  {
    $match: {
      system_username: "saurabh"
    }
  }
])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Result
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[
  {
    "_id": ObjectId("5a934e000102030405000000"),
    "system_languages": "c",
    "system_username": "saurabh"
  },
  {
    "_id": ObjectId("5a934e000102030405000000"),
    "system_languages": "c++",
    "system_username": "saurabh"
  }
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Follow for more cool articles &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://hashnode.com/@saurabh-107"&gt;Hashnode&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/saurabh619"&gt;Dev.to&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks 😎&lt;/p&gt;

</description>
      <category>mongodb</category>
      <category>backend</category>
      <category>node</category>
      <category>database</category>
    </item>
    <item>
      <title>Dockerize your MERN + Flask app</title>
      <dc:creator>Saurabh Bomble</dc:creator>
      <pubDate>Thu, 03 Feb 2022 09:40:42 +0000</pubDate>
      <link>https://dev.to/saurabh619/dockerize-your-mern-flask-app-4flj</link>
      <guid>https://dev.to/saurabh619/dockerize-your-mern-flask-app-4flj</guid>
      <description>&lt;p&gt;Hello developers, &lt;/p&gt;

&lt;p&gt;In this short😂 article, we will try to understand why and how to use docker in your next project.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why should I dockerize my project?
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Suppose, we have a new developer joining our team, rather than wasting other developers' time in setting up the project, the new member can just run &lt;code&gt;docker-compose up&lt;/code&gt; and get all the services up and running🚀&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JMD18k-U--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1643831750662/0JDPKqlkr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JMD18k-U--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1643831750662/0JDPKqlkr.png" alt="it-works-on-my-machine.png" width="617" height="851"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;There have many instances where code runs on a local machine but breaks on someone else's or in the production. It happens cuz of different versions of libraries, configs, and services like databases or cache. Docker installs all the services and runs them in an isolated environment as per the given instructions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Docker also helps to build workflows and automation for testing and linting with CI/CD pipelines which makes it easier to deploy to production.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt; - This tutorial is not for absolute beginners but I'll still recommend reading it. If you don't have docker installed on your machine, please check it out on youtube.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  App Description
&lt;/h3&gt;

&lt;p&gt;Suppose your app has &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Two servers running on - &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Express.js API - &lt;code&gt;http://localhost:8000&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Flask API - &lt;code&gt;http://localhost:5000&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


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

&lt;p&gt;Two services running for Express server - &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mongo Db - &lt;code&gt;mongodb://localhost:27017/db_name&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Redis - &lt;code&gt;redis://localhost:6379&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;&lt;p&gt;React/Next.js frontend running - &lt;code&gt;&lt;a href="http://localhost:3000"&gt;http://localhost:3000&lt;/a&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Glossary -
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Containers vs Images&lt;/strong&gt; - We can consider Images as classes of OOPs and Containers as instances of those images. Images are mostly huge files that are built based on the Dockerfile and containers are isolated environments that run instances of those images. Images are stored locally but can be pushed to the Docker registry &lt;a href="https://registry.hub.docker.com/"&gt;https://registry.hub.docker.com/&lt;/a&gt; to share with other members. With our example, we will build images for every server and service.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Docker compose&lt;/strong&gt; - It's a daunting task to build and run images for every service for a bigger project. So, we use docker compose to consolidate all these docker images and make them build and run together.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Volumes&lt;/strong&gt; - Volumes are storages used for persistence. If we don't use volumes in services like mongo DB and Redis, then all the data will be lost as soon as the container is stopped or removed and can't be accessed after running the container again. &lt;br&gt;
We also use volumes to &lt;strong&gt;map/mirror&lt;/strong&gt; local code/files with the code/files inside the environment so that any changes made in local code gets mirrored and the server can be rerun with tools like &lt;strong&gt;nodemon&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Dockerfile&lt;/strong&gt; - Dockerfile has the set of instructions to build the image. It's kinda like GitHub actions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;.dockerignore&lt;/strong&gt; - This file is like .gitignore file and has a list of excluded modules and files that you don't want in your isolated environment. ex. node_modules.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;FROM&lt;/strong&gt; - FROM instruction initializes a new build stage and sets the base Image (python for flask project and node for a node-based projects).  A valid Dockerfile must start with a FROM instruction. It will pull the image from the public repo (Dockerhub) if not available locally. Always try to find a lighter version of the image (ex. alpine for node.js) to lower the overall size of the image of the app.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;EXPOSE&lt;/strong&gt; - EXPOSE is used to map the port of the host to the port of the container so that we can use the same port on the localhost as written in the code.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Folder structure of the project
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--D1QZhnLg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e1yzqypgfck2f1uh0v1v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--D1QZhnLg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e1yzqypgfck2f1uh0v1v.png" alt="Project structure" width="588" height="159"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QiRkM5qY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/63982501mfhmi2iv3m6b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QiRkM5qY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/63982501mfhmi2iv3m6b.png" alt="Project structure Detail" width="586" height="603"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/dpsUFSR9ZHjwfrVAg9/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/dpsUFSR9ZHjwfrVAg9/giphy.gif" alt="Let's go" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Dockerfiles for Services
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Flask API - 

&lt;ul&gt;
&lt;li&gt;Running flask will need python. &lt;/li&gt;
&lt;li&gt;set working directory inside environment (directory &lt;code&gt;ai-models&lt;/code&gt; will be created by docker).&lt;/li&gt;
&lt;li&gt;copy requirements.txt file from the host into the container.&lt;/li&gt;
&lt;li&gt;RUN the command to install dependencies mentioned in the requirements.txt.&lt;/li&gt;
&lt;li&gt;Now, COPY all the remaining files inside the container. &lt;/li&gt;
&lt;li&gt;Set required env variables inside the container.&lt;/li&gt;
&lt;li&gt;Enter the final command for running the server with CMD.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Dockerfile -&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM python:3.7-slim-buster

WORKDIR /usr/src/ai-models

COPY requirements.txt .

RUN pip3 install -r requirements.txt

COPY . .


# To use flask run instead of python main.py
ENV FLASK_APP=main.py

CMD ["flask", "run", "--host", "0.0.0.0"]

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

&lt;/div&gt;



&lt;p&gt;.dockerignore - I have used virtual environment (skip this if you haven't)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/venv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Build and Spin up the container alone - If you want to a single server, you can build the image of that server and spin up a container for that image.&lt;/p&gt;

&lt;p&gt;a. Move into the API directory&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; cd flask-api

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

&lt;/div&gt;



&lt;p&gt;b. Build an image - Next step is to build the image with a tag(i.e name of the image) and Dockerfile location ( '.' =&amp;gt; current directory)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker build -t app-flask-api  .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;c. Run the container - Map the ports(-p) and spin up the container in detached mode (-d) to get API working&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 -dp 5000:5000 api-flask-api
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Express API - 

&lt;ul&gt;
&lt;li&gt;Running Express will need nodejs as a base image&lt;/li&gt;
&lt;li&gt;Use labels to describe the image (optional)&lt;/li&gt;
&lt;li&gt;set working directory inside environment&lt;/li&gt;
&lt;li&gt;copy package.json and package-lock.json files from the host into the container&lt;/li&gt;
&lt;li&gt;RUN a command to install dependencies mentioned in the package.json. If you use &lt;code&gt;npm ci&lt;/code&gt;, it's important to have package-lock.json file inside the environment.&lt;/li&gt;
&lt;li&gt;Now, COPY all the remaining files inside the container. &lt;/li&gt;
&lt;li&gt;Set required env variables inside the container (if any or want to run it alone)&lt;/li&gt;
&lt;li&gt;Enter the final command for running the server with CMD&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Dockerfile -&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM node:alpine

LABEL version="1.0.0"
LABEL description="Community API server's image"

WORKDIR /usr/src/api

COPY package*.json .

# RUN yarn install --immutable
RUN npm ci

COPY . .

# CMD [ "yarn", "dev" ]
CMD [ "npm", "run", "dev" ]

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

&lt;/div&gt;



&lt;p&gt;.dockerignore - To avoid errors do not copy &lt;code&gt;node_modules&lt;/code&gt; into your container.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;node_modules
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;React/Next.js frontend - 

&lt;ul&gt;
&lt;li&gt;React's image can be build by following the same steps as Express API.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Dockerfile -&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM node:alpine

LABEL version="1.0.0"
LABEL description="Next.js frontend image"

WORKDIR /usr/src/web

COPY package*.json . 
COPY yarn.lock .

# RUN npm ci
RUN yarn install --immutable

COPY . .

# CMD [ "npm", "run", "dev" ]
CMD [ "yarn", "dev" ]

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

&lt;/div&gt;



&lt;p&gt;.dockerignore - To avoid errors do not copy &lt;code&gt;node_modules&lt;/code&gt; into your container.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;node_modules
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Docker compose - We will set instructions in &lt;code&gt;docker-compose.yml&lt;/code&gt; file needed to spin up all the services and API containers with a single command.&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;We will use version 3.8 of docker-compose file formatting&lt;/li&gt;
&lt;li&gt;Every image that is needed to spin up the container is a service 
a. Redis - cache_service (can be named anything)
b. Mongo Database - db_service
c. Flask API for AI models - api_models
d. Express API - api_community
e. Frontend web server - web&lt;/li&gt;
&lt;li&gt;For Redis and Mongo DB services, we will use prebuilt images from the public repository (Dockerhub). For other services, we will build the images based on the Dockerfiles that we have written.&lt;/li&gt;
&lt;li&gt;We will use named volumes for the persistence of the data (in Redis and Mongo DB services) and for mapping the files between host and container (in APIs and frontend). We need to create the volumes before using them inside any service.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;restart = always&lt;/code&gt; makes sure that services will be restarted after every crash&lt;/li&gt;
&lt;li&gt; Mention all of the env variables under &lt;code&gt;environment&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;By default Compose sets up a single network for your app that is shared between different services but we can specify our own custom network(here, shared_network) that could be different for different services. When we run &lt;code&gt;docker-compose up&lt;/code&gt;, all the containers will join specified networks.&lt;/li&gt;
&lt;li&gt;Hosts of the Redis and Mongo DB will not be localhost anymore but the corresponding service. 

&lt;ul&gt;
&lt;li&gt;Redis - redis://cache_service:6379&lt;/li&gt;
&lt;li&gt;Mongo db - mongodb://db_service:27017/db_name&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Map all the required ports, so that they can be accessible from the host&lt;/li&gt;
&lt;li&gt;Mention that express API &lt;code&gt;depends_on&lt;/code&gt; cache_service and db_service
docker-compose.yml -
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version: "3.8"
services:
  cache_service:
    container_name: cache_service
    image: redis:6.2-alpine
    restart: always
    volumes:
      - cache_service:/data/
    ports:
      - 6379:6379
    networks:
      - shared_network

  db_service:
    container_name: db_service
    image: mongo
    restart: always
    volumes:
      - db_service:/data/db 
    ports:
      - 27017:27017
    networks:
      - shared_network

  api_models:
    container_name: api_models
    build: 
      context: ./flask-api
      dockerfile: Dockerfile
    volumes:
      - ./flask-api:/usr/src/ai-models
    ports:
      - 5000:5000
    restart: always
    networks:
      - shared_network

  api_community:
    container_name: api_community
    depends_on:
      - cache_service
      - db_service
    build: 
      context: ./express-api # Path to the directory of Express server
      dockerfile: Dockerfile # name of the Dockerfile 
    restart: always
    volumes:
      # Map local code to the code inside container and exclude node_modules
      - ./express-api:/usr/src/api 
      - /usr/src/api/node_modules 
    ports:
      - 8000:8000
    environment: 
      - PORT=8000
      - DB_URI=mongodb://db_service:27017/db_name 
      - REDIS_URL=redis://cache_service:6379
      - ACCESS_TOKEN_SECRET=12jkbsjkfbasjfakb12j4b12jbk4
      - REFRESH_TOKEN_SECRET=lajsbfqjb2l1b2l4b1lasasg121
    networks:
      - shared_network

  web:
    container_name: web
    depends_on:
      - api_community
    build: 
      context: ./web-app
      dockerfile: Dockerfile
    restart: always
    volumes:
      - ./web-app:/usr/src/web
      - /usr/src/web/node_modules 

    ports:
      - 3000:3000
    networks:
      - shared_network


volumes:
  db_service: 
    driver: local
  cache_service: 
    driver: local

# [optional] If the network is not created, docker will create by itself
networks:
  shared_network: 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And we are done, I think&lt;/p&gt;

&lt;p&gt;To run all the containers, go to the root directory where docker-compose.yml resides and -&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;&lt;a href="https://i.giphy.com/media/5VKbvrjxpVJCM/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/5VKbvrjxpVJCM/giphy.gif" alt="Wow" width="470" height="376"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To stop the containers&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 down
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;If you have made it till here, WOW&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Follow for more cool articles &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://dev.to/saurabh619"&gt;Dev.to&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://hashnode.com/@saurabh-107"&gt;Hashnode&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks 😎&lt;/p&gt;

</description>
      <category>devops</category>
      <category>javascript</category>
      <category>mongodb</category>
      <category>redis</category>
    </item>
    <item>
      <title>Basics of Solidity</title>
      <dc:creator>Saurabh Bomble</dc:creator>
      <pubDate>Sat, 27 Nov 2021 21:23:33 +0000</pubDate>
      <link>https://dev.to/saurabh619/basics-of-solidity-3fhb</link>
      <guid>https://dev.to/saurabh619/basics-of-solidity-3fhb</guid>
      <description>&lt;p&gt;Hello Developers 👋&lt;/p&gt;

&lt;p&gt;In this article, we are going to learn the basics of solidity. Solidity is a new, high-level programming language created specifically to implement smart contracts on the Ethereum blockchain. &lt;/p&gt;

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

&lt;ol&gt;
&lt;li&gt;
Features of Solidity
&lt;/li&gt;
&lt;li&gt;Access Modifiers&lt;/li&gt;
&lt;li&gt;memory vs storage&lt;/li&gt;
&lt;li&gt;Basic Types&lt;/li&gt;
&lt;li&gt;Variables&lt;/li&gt;
&lt;li&gt;Data Structures&lt;/li&gt;
&lt;li&gt;Conditionals and Loops&lt;/li&gt;
&lt;li&gt;Functions&lt;/li&gt;
&lt;li&gt;Error handling&lt;/li&gt;
&lt;li&gt;Inheritance&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Features of Solidity
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Object-oriented programming language just like C++ or Java.&lt;/li&gt;
&lt;li&gt;Statically typed language like Typescript - helps to catch bugs in the early stage of the development process.&lt;/li&gt;
&lt;li&gt;Highly influenced by other programming languages such as Javascript, Python, and C++.&lt;/li&gt;
&lt;li&gt;Supports Inheritance of contracts and runs on Ethereum Virtual Machine(EVM).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br&gt;
&lt;a href="https://i.giphy.com/media/WpyPNxnkbaz6bb0v3g/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/WpyPNxnkbaz6bb0v3g/giphy.gif" alt="Let's begin" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Access Modifiers
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;There are four basic access modifiers used by variables and functions&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;Public: The value of the variables and functions can be accessed within the contract, child contract, and from external functions.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;contract MyContract {
    uint256 public myPublicVar;
    function getVar() public view returns(uint) { 
        return myPublicVar;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;External: The value of the variables and functions can be accessed only from external functions.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;contract MyContract {
    uint256 external externalVar; 
    function getVar() external view returns(uint) { 
        return externalVar;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Internal: The value of the variables and functions can be accessed within the contract and child contract.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;contract MyContract  {
    uint256 internal internalVar; 
    function getVar() internal view returns(uint) { 
        return internalVar;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Private: The value of the variables and functions can be accessed within the same contract only.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;contract MyContract { 
    uint256 private privateVar; 
    function getVar() private view returns(uint) { 
        return privateVar;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  memory vs storage
&lt;/h3&gt;

&lt;p&gt;We can consider &lt;strong&gt;&lt;em&gt;memory&lt;/em&gt;&lt;/strong&gt; as a RAM and &lt;strong&gt;&lt;em&gt;storage&lt;/em&gt;&lt;/strong&gt; as a Hard disk. Any value that is stored in a &lt;strong&gt;&lt;em&gt;memory&lt;/em&gt;&lt;/strong&gt; variable will be temporary and will be wiped after execution stops while the value in the &lt;strong&gt;&lt;em&gt;storage&lt;/em&gt;&lt;/strong&gt; variable will be stored permanently on the blockchain and after the new execution, the variable will still have the previously stored value. The structure of &lt;strong&gt;&lt;em&gt;storage&lt;/em&gt;&lt;/strong&gt; can never be changed after the deployment of the contract but values inside it can be.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;memory&lt;/em&gt;&lt;/strong&gt; consumes comparatively less gas. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;memory&lt;/em&gt;&lt;/strong&gt; can only be used in methods, not at the contract level (state variable).&lt;/li&gt;
&lt;li&gt;Solidity tries to declare variables in &lt;strong&gt;&lt;em&gt;storage&lt;/em&gt;&lt;/strong&gt;  if the &lt;strong&gt;&lt;em&gt;memory&lt;/em&gt;&lt;/strong&gt; keyword is not used.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;memory&lt;/em&gt;&lt;/strong&gt; creates a new copy of the variable while &lt;strong&gt;&lt;em&gt;storage&lt;/em&gt;&lt;/strong&gt;  points to the same location and can alter the values of the original variable.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;h5&gt;
  
  
  Example
&lt;/h5&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pragma solidity &amp;gt;=0.8.7;

// Creating a contract
contract MemoryContract
{ 
    // state variable (always in storage)
    uint[] public numbers;

    function addNumbers() public  {
        numbers.push(1);
        numbers.push(2);  
        // numbers = [1, 2]

        //1. Creating a new memory instance 
        uint[] memory myMemoryNumbers = numbers;
        myMemoryNumbers[0] = 10;
        // myMemoryNumber = [10, 2]
        // numbers = [1, 2]  


        //2. Creating a new storage instance
        uint[] storage myStorageNumbers = numbers;
        myStorageNumbers[0] = 10;
        // myStorageNumbers = [10, 2]
        // numbers = [10, 2] 
    } 
}

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Basic Types
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;h5&gt;
  
  
  Example
&lt;/h5&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// specify the version of solidity
pragma solidity &amp;gt;=0.8.7;   

// Creating a contract
contract BasicTypes {   

    // Boolean value
    bool public myBoolean = false;

    // Integer variable
    int32 public myInt = -60313;
    // unsigned Integer
    uint public myUInt = 60313; // alias for uint256

    // String variable
    string public myStr = "Saurabh";
    // Byte string (uses less gas)
    bytes32 public myByteString = "Bomble";

    // Byte variable
    bytes1 public b = "a";

    // Defining an enumerator
    enum myEnum { ACCEPTED, PENDING, REJECTED }  
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Variables
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Syntax
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;type&amp;gt; &amp;lt;access modifier&amp;gt; &amp;lt;variable name&amp;gt;; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;h4&gt;
  
  
  Types of variables
&lt;/h4&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;State variables - These variables are the variables that are stored permanently in the contract storage on the blockchain. &lt;/li&gt;
&lt;li&gt;Local variables - These variables are not stored on blockchain but are created within a scope (e.g function) to help write business logic.&lt;/li&gt;
&lt;li&gt;Global variables - These variables exist in the global namespace and can be invoked from anywhere in the contract. Global variables hold information about different transactions and blockchain properties. eg. block, msg, and tx.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;h5&gt;
  
  
  Example
&lt;/h5&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pragma solidity &amp;gt;=0.8.7;

contract VariableType {
    // State variables =&amp;gt; stored on blockchain  
    uint myUint = 1;  
    //160-bit ethereum address 
    address public myAddress = 0xE9Bc4d002161aA50E15728ba19aDC3aA34a91D98; 

    constructor() {
        // msg is global variable
        myAddress = msg.sender  // address of user who deployed the contract
    }

    function getValue() public pure returns(uint) {
        myAddress = msg.sender  // address of current caller
        uint value = 1; // local variable
        return value;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Data Structures
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Array - We can store a collection of elements of the same type in an array. We can access, push, and pop an element from an array and can calculate the length of the array. Arrays in solidity are 0-indexed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Struct - Struct allows us to create user-defined data types.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Mapping - Mapping in solidity is like unordered_map in C++ or dictionary in python. It is used to store key-value pairs. Here, keys can be of any built-in data type and values can be of any type including user-defined types.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;h5&gt;
  
  
  Example
&lt;/h5&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pragma solidity &amp;gt;=0.8.7;

contract DataStructure {
    // Array
    uint[] public myIntArray = [1, 2, 3];
    string[] public myStringArray = ["apple", "banana"];
    uint[][] public array2D = [ [1,2,3], [4,5,6] ];

    function addValue(string memory _value) public {
        myStringArray.push(_value);
    }

    function valueCount() public view returns(uint) {
        return myStringArray.length;
    } 

    // Mapping (key-value store)
    mapping(uint =&amp;gt; string) public names;

    constructor() {
        names[1] = "Saurabh";
        names[2] = "John";
        names[3] = "Doe"; 
    }

    struct Book {
        string title;
        string author;
    }


    mapping(uint =&amp;gt; Book) books; // key = id of book(unit), value = Book
    // Nested mapping
    mapping(address =&amp;gt; mapping(uint =&amp;gt; Book)) public myBooks; 

    function addBook(uint _id, string memory _title, string memory _author) public {
        books[_id] = Book(_title, _author);
    }

    function getBook(uint _id) public view returns(string memory, string memory){
        string memory _title = books[_id].title;
        string memory _author = books[_id].author; 
        return (_title, _author);
    }

    function addMyBook(uint _id, string memory _title, string memory _author) public {
        myBooks[msg.sender][_id] = Book(_title, _author);
    } 
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Conditionals and Loops
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Conditionals  - Conditionals include if-else, ternary operator&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For Loop - similar to c++ loop. Takes three arguments separated by a semi-colon. viz. &lt;strong&gt;&lt;em&gt;initialization&lt;/em&gt;&lt;/strong&gt;,  &lt;strong&gt;&lt;em&gt;condition&lt;/em&gt;&lt;/strong&gt;, and &lt;strong&gt;&lt;em&gt;iteration&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;While loop -  Execute a statement or block of statements repeatedly as far as the condition is true and once the condition becomes false the loop terminates. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Do while - Similar to while loop except the condition check happens at the end of the loop &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;h5&gt;
  
  
  Example
&lt;/h5&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pragma solidity &amp;gt;=0.8.7;

contract ConditionalsLoops {
    // Loop
    uint[] public numbers = [1,2,3,4,5];
    address public owner;

    constructor() {
        owner = msg.sender;
    }

    function countEven() public view returns(uint count) {
        count = 0;
        for(uint i = 0; i &amp;lt; numbers.length; i++) {
            count += isEven(numbers[i]) ? 1 : 0;
        } 
    }

    // Conditionals (just like js)
    function isEven(uint _value) public pure returns(bool) {
        return _value % 2 == 0; 
    }

    function isOwner() public view returns(bool) {
        if(msg.sender == owner) return true;
        return false;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Functions
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;View functions - This function can only read the state variables.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pure functions - This function can neither read nor modify the state variables.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;returns(type) - denotes return type of the function.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;h5&gt;
  
  
  Example
&lt;/h5&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pragma solidity &amp;gt;=0.8.7;

contract FunctionContract {  
    uint myUint = 1;

    function getValue() public pure returns(uint) {
        uint value = 1; 
        return value;
    }

    function getMyUint() public view returns(uint) { 
        return myUint;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Error handling
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;revert(string memory msg) - aborts the execution and revert any changes done to the state. returns the msg.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;h5&gt;
  
  
  Example
&lt;/h5&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if(currentStatus == Status.VACANT) {
     revert("Currently occupied");
} 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;require(bool condition, string memory message) − If the condition is not met, this method call reverts to its original state and throws a custom message.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;h5&gt;
  
  
  Example
&lt;/h5&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;require(currentStatus == Status.VACANT, "Currently occupied");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Inheritance
&lt;/h3&gt;

&lt;p&gt;Inheritance is one of the most important features of the object-oriented programming language. It makes code scalable, reusable, and more organized. Parent contract is known as base contract and the contract that inherits methods and properties from the base contract is called a derived contract.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A derived contract can access all public and internal features of the base contract.&lt;/li&gt;
&lt;li&gt;Function overriding is allowed provided the function signature remains the same. &lt;/li&gt;
&lt;li&gt;super keyword in the child contract helps to call the constructor of the parent. &lt;/li&gt;
&lt;li&gt;Contracts can inherit other contracts by using the &lt;strong&gt;&lt;em&gt;is&lt;/em&gt;&lt;/strong&gt; keyword.&lt;/li&gt;
&lt;li&gt;Function to be overridden by a child contract must be declared as virtual.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pragma solidity &amp;gt;=0.8.7; 

contract BaseContract {  
    uint public a;   
    uint public b;    

    // Wrong defination to be corrected in derived 
    function getDiff() public view virtual returns(uint) {
        return(a*b);
    }
} 

// Defining child contract 
contract DerivedContract is BaseContract{   
    constructor(uint _a, uint _b) {
        a = _a;
        b = _b;
        super;
    }

    // Correct defination with same signature
    function getDiff() public view virtual override returns(uint) {
        return(a-b);
    }
} 

// Defining calling contract
contract CallerContract {
    DerivedContract derivedContract;
    constructor(uint _val1, uint _val2) {
        derivedContract = new DerivedContract(_val1, _val2); 
    }

    function getDiffAandB() public view returns(uint) { 
        return derivedContract.getDiff();
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Thanks for reading🙏. That's it for this chapter. We have learned most of the basic concepts in solidity to get started to write our smart contracts.&lt;/p&gt;

&lt;p&gt;Follow me on &lt;strong&gt;dev.to&lt;/strong&gt; for &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Upcoming articles on Blockchain technology.&lt;/li&gt;
&lt;li&gt;Web development (React.js+Nest.js)&lt;/li&gt;
&lt;li&gt;App development (Flutter, React Native)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/VB5WwlZIt8eRy/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/VB5WwlZIt8eRy/giphy.gif" alt="Finally" width="500" height="207"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>beginners</category>
      <category>web3</category>
    </item>
    <item>
      <title>Best portfolio web designs</title>
      <dc:creator>Saurabh Bomble</dc:creator>
      <pubDate>Thu, 30 Sep 2021 10:19:20 +0000</pubDate>
      <link>https://dev.to/saurabh619/best-portfolio-web-designs-2odc</link>
      <guid>https://dev.to/saurabh619/best-portfolio-web-designs-2odc</guid>
      <description>&lt;h3&gt;
  
  
  Hello Developers 👋🏼
&lt;/h3&gt;

&lt;p&gt;I am Saurabh, a beginner in the design world.&lt;br&gt;
In this article, we'll see some of the best web designs that I use to get my inspirations and to get my research started. I hope this will help you too.&lt;/p&gt;

&lt;p&gt;Portfolio websites are the best way to boast about your front-end skills. A portfolio website is nothing less than a resume for a developer. All of these listed websites are portfolio sites of wonderful designers and developers.&lt;/p&gt;

&lt;p&gt;Some tips for your next design&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; Do your research regarding the project.&lt;/li&gt;
&lt;li&gt; Keep it simple and stupid.&lt;/li&gt;
&lt;li&gt;Keep it clean.&lt;/li&gt;
&lt;li&gt;Don't use multiple fonts or colours.&lt;/li&gt;
&lt;li&gt;Create typography hierarchy and font styles first. &lt;/li&gt;
&lt;li&gt;Consistency always makes your design look professional - use consistent icons, illustrations, and images.&lt;/li&gt;
&lt;li&gt;Check contrast and space - need to have good contrast between element and background. Appropriate breathing space inside cards and buttons is the key.
&lt;/li&gt;
&lt;li&gt;Use grids and rulers to keep components aligned perfectly.&lt;/li&gt;
&lt;li&gt;Keep yourself updated with new trends. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Best practices - &lt;a href="https://developer.apple.com/design/resources/" rel="noopener noreferrer"&gt;Apple's Guide&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Let's get started 🚀&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://leonidkostetskyi.com/" rel="noopener noreferrer"&gt;1. Leonid Kostetskyi&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Leonid Kostetskyi is a Ukraine based web developer with a mind-blowing portfolio site. Wavy images with WebGL, parallax content, cool typography are some of the USPs. He's been awarded multiple times by AWWWARDS and Behance.   &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1632755264151%2Fpqx0TYulr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1632755264151%2Fpqx0TYulr.png" alt="1. Leonid landing image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://www.alexfrisondeisla.com/" rel="noopener noreferrer"&gt;2. Alex Frison de Isla&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Alex is Paris based freelance web developer and has a portfolio website with elegant design with smooth transitions, subtle animations, a clean colour palette, and dope assets. &lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1632755332149%2FCL9E6OVJB.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1632755332149%2FCL9E6OVJB.png" alt="2. Alex landing image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="http://www.benmingo.com/" rel="noopener noreferrer"&gt;3. Ben Mingo&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Ben Mingo is a South California, USA based graphic designer. His portfolio website is just bonkers. Clean UI, black-white colour pattern, custom cursor, smooth transitions, and scrolling. worth a visit. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1632755337688%2F7nN1SL-Yq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1632755337688%2F7nN1SL-Yq.png" alt="3. Ben landing image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://abhishekjha.me/mobile.html" rel="noopener noreferrer"&gt;4. Abhishek Jha&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Abhishek Jha is Delhi, India-based UI/UX designer. His portfolio website is quite an experience with unique colour choices, smooth scrolling, text and image transitions.   &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1632755406784%2F9pc_B5PlE.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1632755406784%2F9pc_B5PlE.png" alt="4. Abhishek landing image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://kuon.space/" rel="noopener noreferrer"&gt;5. Kuon Yagi&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Kuon Yagi is Okinawa based web designer. Full page transitions, cool assets, crazy transitions, and unique colour choices make this site a great inspiration.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1632755506574%2FljwoKws9u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1632755506574%2FljwoKws9u.png" alt="5. Kuon landing image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://brittanychiang.com/" rel="noopener noreferrer"&gt;6. Brittany Chiang&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Brittany Chiang is a software engineer who has worked as UI Designer at Apple before. Her portfolio website has 3,763 stars and 1,735 forks on Github as of now. Clean UI with two colours, great projects, definitely justifies the hype. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1632755524621%2F-inKCfYPL.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1632755524621%2F-inKCfYPL.png" alt="6. Brittany landing image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="http://stephencalvillodesign.com/" rel="noopener noreferrer"&gt;7. Stephen calvillo&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Stephen is a product manager from California, USA. Clean and minimal UI with great contrast, subtle animations, and colour choices make this website special. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1632755544755%2FMuNTnZKhF.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1632755544755%2FMuNTnZKhF.png" alt="7. Stephen landing image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you have read the chapter till here, please feel free to roast &lt;strong&gt;my portfolio website&lt;/strong&gt; in the comment section. It's still under development (media queries 😥) but would like to get your valuable suggestions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1632848082462%2FgMjDg0bSB.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1632848082462%2FgMjDg0bSB.png" alt="Saurabh Bomble"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Preview -  &lt;a href="https://saurabhbomble.me" rel="noopener noreferrer"&gt;https://saurabhbomble.me&lt;/a&gt;
&lt;/h4&gt;

&lt;h4&gt;
  
  
  Design - &lt;a href="https://www.figma.com/file/xkJIOgaIamG04roANGJHRF/Portfolio-2021?node-id=0%3A1" rel="noopener noreferrer"&gt;Figma file&lt;/a&gt;
&lt;/h4&gt;

&lt;h4&gt;
  
  
  Code- &lt;a href="https://github.com/saurabh-619/portfolio-2021/tree/main/client-v1" rel="noopener noreferrer"&gt;Github&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;Thanks 😊 for reading. Hope you got some inspiration to get started with your portfolio site or to finish it. That's it for this chapter, will see you all in the next one.&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%2Fmedia.giphy.com%2Fmedia%2FB37cYPCruqwwg%2Fgiphy.gif%3Fcid%3Decf05e47j6x416807sfk6r5wkp7ihtcsmtj4daklw5mh18yz%26rid%3Dgiphy.gif%26ct%3Dg" 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%2Fmedia.giphy.com%2Fmedia%2FB37cYPCruqwwg%2Fgiphy.gif%3Fcid%3Decf05e47j6x416807sfk6r5wkp7ihtcsmtj4daklw5mh18yz%26rid%3Dgiphy.gif%26ct%3Dg" alt="Byee"&gt;&lt;/a&gt; &lt;/p&gt;

</description>
      <category>design</category>
      <category>portfolio</category>
      <category>gatsby</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
