<?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: wassef ben ahmed </title>
    <description>The latest articles on DEV Community by wassef ben ahmed  (@wassef911).</description>
    <link>https://dev.to/wassef911</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%2F362578%2F61f65136-35aa-48e7-a4ff-2a1db45daad8.jpg</url>
      <title>DEV Community: wassef ben ahmed </title>
      <link>https://dev.to/wassef911</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/wassef911"/>
    <language>en</language>
    <item>
      <title>Deploying Django in Production.</title>
      <dc:creator>wassef ben ahmed </dc:creator>
      <pubDate>Sun, 23 Jun 2024 20:40:38 +0000</pubDate>
      <link>https://dev.to/wassef911/deploying-django-in-production-b1p</link>
      <guid>https://dev.to/wassef911/deploying-django-in-production-b1p</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr94ngxfek647u0zok8bn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr94ngxfek647u0zok8bn.png" alt="Image description" width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This 5-step tutorial will guide you through deploying a Django application using Gunicorn behind a reverse proxy (such as Nginx). &lt;/p&gt;

&lt;p&gt;Its important to note that this greatly depends on the needs of your project, but for most people, this is intended to be a minimal/initial setup. This configuration ensures that your application is served efficiently and securely, straight to production 🚀. &lt;/p&gt;

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

&lt;p&gt;Before starting, ensure you have the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A domain name. (duh)&lt;/li&gt;
&lt;li&gt;A server with root access (e.g. an Ubuntu server).&lt;/li&gt;
&lt;li&gt;A Django application ready for deployment. (eg. being under &lt;strong&gt;/opt/project_name&lt;/strong&gt;)&lt;/li&gt;
&lt;li&gt;A virtual environment. (eg. being under &lt;strong&gt;/opt/project_name/venv&lt;/strong&gt;)&lt;/li&gt;
&lt;li&gt;Basic knowledge of Linux command-line operations.&lt;/li&gt;
&lt;li&gt;Nginx installed on your server.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 0: Setting Up Your Domain and DNS
&lt;/h2&gt;

&lt;p&gt;Before deploying your Django application, ensure your domain points to your server and DNS settings are correctly configured. Here’s a brief guide on how to do this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Domain Registration:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Register your domain with a domain registrar.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Obtain Server IP Address:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Get the public IP address of your server. This is the address that clients will use to access your application.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;DNS Configuration:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Log in to your domain registrar’s control panel and find the DNS settings for your domain.&lt;/li&gt;
&lt;li&gt;Add an A record to point your domain to your server's IP address:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Type:&lt;/strong&gt; A&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Name:&lt;/strong&gt; @ (this represents your domain, e.g., &lt;code&gt;your_domain.com&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Value:&lt;/strong&gt; [Your Server's IP Address]&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TTL:&lt;/strong&gt; Default or 3600 seconds (1 hour)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;If you want to use &lt;code&gt;www.your_domain.com&lt;/code&gt;, add a CNAME record:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Type:&lt;/strong&gt; CNAME&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Name:&lt;/strong&gt; www&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Value:&lt;/strong&gt; your_domain.com&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TTL:&lt;/strong&gt; Default or 3600 seconds (1 hour)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Propagation Time:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;DNS changes may take some time to propagate (up to 48 hours, but usually within a few hours). You can use tools like &lt;code&gt;whatsmydns.net&lt;/code&gt; to check the propagation status.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Verify DNS Settings:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;After DNS propagation, you should be able to verify your domain points to your server by using tools like &lt;code&gt;ping&lt;/code&gt; or &lt;code&gt;dig&lt;/code&gt;:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; ping your_domain.com
&lt;/code&gt;&lt;/pre&gt;

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

&lt;ul&gt;
&lt;li&gt;You should see responses from your server's IP address.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Firewall and Security Group Configuration:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Ensure your server's firewall and any cloud provider security groups allow traffic on ports 80 (HTTP) and 443 (HTTPS).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Once your DNS is set up and pointing to your server, you can proceed with the deployment steps outlined in the tutorial. This setup ensures that visitors accessing your domain will be directed to your server, where Nginx and Gunicorn will handle the requests.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Install Gunicorn
&lt;/h2&gt;

&lt;p&gt;First, activate your virtual environment and install Gunicorn:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;source&lt;/span&gt; /opt/project_name/venv/bin/activate
python3 &lt;span class="nt"&gt;-m&lt;/span&gt; pip &lt;span class="nb"&gt;install &lt;/span&gt;gunicorn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2: Configure Gunicorn
&lt;/h2&gt;

&lt;p&gt;Create a Gunicorn configuration file (optional but recommended) to manage settings like worker processes. Create a file named &lt;code&gt;gunicorn_config.py&lt;/code&gt; in your project directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# gunicorn_config.py
&lt;/span&gt;
&lt;span class="n"&gt;bind&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;127.0.0.1:8000&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;workers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 3: Adjust Django Settings
&lt;/h2&gt;

&lt;p&gt;Update your Django settings to handle the proxy setup correctly. Edit your &lt;code&gt;settings.py&lt;/code&gt; file to include the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# settings.py
&lt;/span&gt;
&lt;span class="c1"&gt;# Static files (CSS, JavaScript, Images)
&lt;/span&gt;&lt;span class="n"&gt;STATIC_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/static/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;span class="n"&gt;STATIC_ROOT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BASE_DIR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;static&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Media files (Uploaded by users)
&lt;/span&gt;&lt;span class="n"&gt;MEDIA_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/media/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;span class="n"&gt;MEDIA_ROOT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BASE_DIR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;media&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Specifies a list of valid host/domain names for the Django site, providing protection against HTTP Host header attacks.
&lt;/span&gt;&lt;span class="n"&gt;ALLOWED_HOSTS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;your_domain.com&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;www.your_domain.com&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;another_domain.com&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;# Tells Django to use the X-Forwarded-Host header from the proxy, allowing it to know the original host requested by the client.
&lt;/span&gt;&lt;span class="n"&gt;USE_X_FORWARDED_HOST&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
&lt;span class="c1"&gt;# Tells Django to use the X-Forwarded-Port header from the proxy, indicating the port number used by the client.
&lt;/span&gt;&lt;span class="n"&gt;USE_X_FORWARDED_PORT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
&lt;span class="c1"&gt;# Instructs Django to trust the X-Forwarded-Proto header, which is set by the proxy server, to determine whether the request is secure (HTTPS).
&lt;/span&gt;&lt;span class="n"&gt;SECURE_PROXY_SSL_HEADER&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;HTTP_X_FORWARDED_PROTO&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;https&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Forces all HTTP requests to be redirected to HTTPS.
&lt;/span&gt;&lt;span class="n"&gt;SECURE_SSL_REDIRECT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;

&lt;span class="c1"&gt;# Ensures that the CSRF cookie is only sent over HTTPS connections.
&lt;/span&gt;&lt;span class="n"&gt;CSRF_COOKIE_SECURE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
&lt;span class="c1"&gt;# Ensures that the session cookie is only sent over HTTPS connections.
&lt;/span&gt;&lt;span class="n"&gt;SESSION_COOKIE_SECURE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;

&lt;span class="c1"&gt;# Enables HTTP Strict Transport Security (HSTS) for the specified duration (in seconds), forcing browsers to only connect via HTTPS.
&lt;/span&gt;&lt;span class="n"&gt;SECURE_HSTS_SECONDS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;31536000&lt;/span&gt;
&lt;span class="c1"&gt;# Applies HSTS policy to all subdomains.
&lt;/span&gt;&lt;span class="n"&gt;SECURE_HSTS_INCLUDE_SUBDOMAINS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
&lt;span class="c1"&gt;# Allows the domain to be included in browsers' HSTS preload list, ensuring maximum protection.
&lt;/span&gt;&lt;span class="n"&gt;SECURE_HSTS_PRELOAD&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;

&lt;span class="c1"&gt;# Enables the X-Content-Type-Options header, preventing browsers from MIME-sniffing a response away from the declared content-type.
&lt;/span&gt;&lt;span class="n"&gt;SECURE_CONTENT_TYPE_NOSNIFF&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
&lt;span class="c1"&gt;# Controls the information sent in the Referer header, improving privacy and security by not sending the referrer from HTTPS to HTTP.
&lt;/span&gt;&lt;span class="n"&gt;SECURE_REFERRER_POLICY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;no-referrer-when-downgrade&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;

&lt;span class="c1"&gt;# SECURE_BROWSER_XSS_FILTER = True
# [Deprecated on 4.0]
# Enables the X-XSS-Protection header, which tells browsers to block detected cross-site scripting (XSS) attacks.
&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Collect Static Files
&lt;/h5&gt;

&lt;p&gt;Django comes with a handy command to collect all static files into the directory specified in STATIC_ROOT.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 &lt;span class="nt"&gt;-m&lt;/span&gt; /opt/project_name/manage.py collectstatic
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 4: Create a Systemd Service for Gunicorn
&lt;/h2&gt;

&lt;p&gt;Create a systemd service file to manage the Gunicorn process. Create a file named &lt;code&gt;gunicorn.service&lt;/code&gt; in &lt;code&gt;/etc/systemd/system/&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="c"&gt;# /etc/systemd/system/gunicorn.service
&lt;/span&gt;
&lt;span class="nn"&gt;[Unit]&lt;/span&gt;
&lt;span class="py"&gt;Description&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;gunicorn daemon&lt;/span&gt;
&lt;span class="py"&gt;After&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;network.target&lt;/span&gt;

&lt;span class="nn"&gt;[Service]&lt;/span&gt;
&lt;span class="py"&gt;User&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;yourusername&lt;/span&gt;
&lt;span class="py"&gt;Group&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;www-data&lt;/span&gt;
&lt;span class="py"&gt;WorkingDirectory&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/opt/project_name&lt;/span&gt;
&lt;span class="py"&gt;ExecStart&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/opt/project_name/venv/bin/gunicorn --config /opt/gunicorn_config.py project_name.wsgi:application&lt;/span&gt;

&lt;span class="nn"&gt;[Install]&lt;/span&gt;
&lt;span class="py"&gt;WantedBy&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;multi-user.target&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace &lt;code&gt;/opt/project_name&lt;/code&gt;, &lt;code&gt;/opt/project_name/venv&lt;/code&gt;, and &lt;code&gt;project_name&lt;/code&gt; with your actual project paths and names.&lt;/p&gt;

&lt;p&gt;Reload the systemd daemon and start the Gunicorn service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl daemon-reload
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl start gunicorn
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;gunicorn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 5: Configure Nginx
&lt;/h2&gt;

&lt;p&gt;Create an Nginx configuration file to proxy requests to Gunicorn. Create a file named &lt;code&gt;project_name&lt;/code&gt; in &lt;code&gt;/etc/nginx/sites-available/&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="c1"&gt;# /etc/nginx/sites-available/project_name&lt;/span&gt;

&lt;span class="k"&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;80&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;server_name&lt;/span&gt; &lt;span class="s"&gt;your_domain.com&lt;/span&gt; &lt;span class="s"&gt;www.your_domain.com&lt;/span&gt; &lt;span class="s"&gt;another_domain.com&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;/favicon.ico&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="kn"&gt;access_log&lt;/span&gt; &lt;span class="no"&gt;off&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="kn"&gt;log_not_found&lt;/span&gt; &lt;span class="no"&gt;off&lt;/span&gt;&lt;span class="p"&gt;;&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;/static/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kn"&gt;alias&lt;/span&gt; &lt;span class="n"&gt;/opt/project_name/static/&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;# Must be the same as STATIC_ROOT&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;/media/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kn"&gt;alias&lt;/span&gt; &lt;span class="n"&gt;/opt/project_name/media/&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;# Must be the same as MEDIA_ROOT&lt;/span&gt;
        &lt;span class="kn"&gt;access_log&lt;/span&gt; &lt;span class="n"&gt;/var/log/nginx/media_access.log&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;error_log&lt;/span&gt; &lt;span class="n"&gt;/var/log/nginx/media_error.log&lt;/span&gt;&lt;span class="p"&gt;;&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_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="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;X-Forwarded-Proto&lt;/span&gt; &lt;span class="nv"&gt;$scheme&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://127.0.0.1:8000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kn"&gt;access_log&lt;/span&gt; &lt;span class="n"&gt;/var/log/nginx/django_access.log&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;error_log&lt;/span&gt; &lt;span class="n"&gt;/var/log/nginx/django_error.log&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="s"&gt;[::]:80&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;/div&gt;



&lt;p&gt;Create a symbolic link to enable the site, and ensure the static and media directories, as well as the log directories, have the correct permissions. &lt;/p&gt;

&lt;p&gt;You need to make sure that the user running Nginx has the necessary read/write permissions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Create directories if they don't exist&lt;/span&gt;
&lt;span class="nb"&gt;sudo mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /opt/project_name/static /opt/project_name/media /var/log/nginx

&lt;span class="c"&gt;# Set ownership (assuming nginx user and group) and permissions&lt;/span&gt;
&lt;span class="nb"&gt;sudo chown&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; nginx:nginx /opt/project_name/static /opt/project_name/media /var/log/nginx
&lt;span class="nb"&gt;sudo chmod&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; 755 /opt/project_name/static /opt/project_name/media /var/log/nginx

&lt;span class="nb"&gt;sudo ln&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; /etc/nginx/sites-available/project_name /etc/nginx/sites-enabled
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Test the Nginx configuration and restart the service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;nginx &lt;span class="nt"&gt;-t&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 6: Configure HTTPS
&lt;/h2&gt;

&lt;p&gt;It's highly recommended to secure your application with HTTPS. Use Certbot to obtain a free SSL certificate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install &lt;/span&gt;certbot python3-certbot-nginx
&lt;span class="nb"&gt;sudo &lt;/span&gt;certbot &lt;span class="nt"&gt;--nginx&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; your_domain.com &lt;span class="nt"&gt;-d&lt;/span&gt; www.your_domain.com &lt;span class="nt"&gt;-d&lt;/span&gt; another_domain.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Follow the prompts to configure SSL.&lt;/p&gt;

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

&lt;p&gt;Your Django application is now deployed using Gunicorn behind an Nginx reverse proxy.&lt;/p&gt;

&lt;p&gt;However, there are several ways you could customize and enhance this deployment:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Load Balancing&lt;/strong&gt;: If you anticipate high traffic, consider setting up multiple Gunicorn instances behind a load balancer to distribute the load evenly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Containerization&lt;/strong&gt;: Using Docker to containerize your application can simplify deployment and provide greater consistency across different environments.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Advanced Security Configurations&lt;/strong&gt;: Additional security measures such as setting up a Web Application Firewall (WAF), regular security audits, and implementing stricter Content Security Policies (CSP) can further protect your application.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Be sure to explore these options and refer to the official documentation for Gunicorn, Nginx, and Django for further customization and advanced configurations. By continuously refining your deployment setup, you can ensure your Django application remains secure, efficient, and scalable.&lt;/p&gt;

</description>
      <category>django</category>
      <category>nginx</category>
      <category>webdev</category>
      <category>python</category>
    </item>
    <item>
      <title>Ship Slightly Better Microservices.</title>
      <dc:creator>wassef ben ahmed </dc:creator>
      <pubDate>Mon, 04 Sep 2023 12:58:33 +0000</pubDate>
      <link>https://dev.to/wassef911/ship-slightly-better-microservices-4i1m</link>
      <guid>https://dev.to/wassef911/ship-slightly-better-microservices-4i1m</guid>
      <description>&lt;h2&gt;
  
  
  Introducing env_should_be
&lt;/h2&gt;

&lt;p&gt;In the fast-paced oblate spheroid we call home, building microservices and multi-environment deployments, ensuring the integrity, security, and compatibility of containers is a monumental challenge. Battling with microservices and incremental development, I've seen firsthand the complexities and frustrations that arise with maintaining consistency across different deployment environments. I was trying to solve this problem and, in doing so, created env_should_be—a PyPI package that might change your approach to building containers… (We’ll see about that!)&lt;/p&gt;

&lt;h2&gt;
  
  
  The Motivation Behind env_should_be
&lt;/h2&gt;

&lt;p&gt;Microservices architecture, with its flexibility and scalability, has become the standard for modern software development. However, it also brings a new set of challenges, one of which is ensuring that containers are running in environments that are compatible and secure. Traditional methods often involve extensive coordination between developers and operations teams, leading to bottlenecks, configurations, and security vulnerabilities.&lt;/p&gt;

&lt;p&gt;The need for a more efficient, automated, and developer-friendly approach became evident. env_should_be was created to address these challenges by allowing developers to define deployment environment requirements using simple JSON or YAML descriptions. This empowers developers to specify the exact conditions under which a container can run, mitigating compatibility issues and enforcing security standards seamlessly… This environment description can either be one or multiple files and can also be a combination for each type of environment…&lt;/p&gt;

&lt;h2&gt;
  
  
  env_should_be in Action
&lt;/h2&gt;

&lt;p&gt;So, how does env_should_be work, and what sets it apart? At its core, env_should_be is a command-line interface (CLI) tool that you can effortlessly integrate into your container deployment pipelines. It takes deployment environment descriptions in JSON or YAML format as input, allowing you to specify requirements for various environment variables, file paths, and even execution callbacks…. It also can be shipped as part of the actual container or be used as a pipeline stage, to validate the environment before deploying…&lt;/p&gt;

&lt;h3&gt;
  
  
  Environment Descriptions
&lt;/h3&gt;

&lt;p&gt;Imagine you have a flask microservice that relies on a database and cache, and you want to ensure that certain environment variables meet specific criteria each time before the app starts, Here's an example YAML description:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;DB_USER&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8&lt;/span&gt;
  &lt;span class="na"&gt;regex&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;^[a-zA-Z0-9]+$"&lt;/span&gt;
&lt;span class="na"&gt;DB_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;12&lt;/span&gt;
  &lt;span class="na"&gt;regex&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s"&gt;$%&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s"&gt;^&amp;amp;&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s"&gt;*])(?=.{8,})"&lt;/span&gt;
&lt;span class="na"&gt;DB_HOST&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;option&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;localhost&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;127.0.0.1&lt;/span&gt;
&lt;span class="na"&gt;DB_PORT&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt;
  &lt;span class="na"&gt;regex&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;^[0-9]+$"&lt;/span&gt;
  &lt;span class="na"&gt;is_int&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;True&lt;/span&gt;
  &lt;span class="na"&gt;is_float&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;False&lt;/span&gt;
&lt;span class="na"&gt;CACHE&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="c1"&gt;# sure that it has the same value across whatever env?&lt;/span&gt;
  &lt;span class="na"&gt;constant&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;redis://container_name:6379/1"&lt;/span&gt;
&lt;span class="na"&gt;APP_ENV&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;option&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;dev&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;prod&lt;/span&gt;
  &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="no"&gt;false&lt;/span&gt; &lt;span class="c1"&gt;# only get's validated if it is set (not None)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;then a compose file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3'&lt;/span&gt;
&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;context&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.&lt;/span&gt;
    &lt;span class="na"&gt;expose&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="m"&gt;5000&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="s"&gt;sh -c '&lt;/span&gt;
        &lt;span class="s"&gt;env_should_be -d "/app/descriptions/app.json" &amp;amp;&amp;amp; \&lt;/span&gt;
        &lt;span class="s"&gt;flask run --host=0.0.0.0 --port 5000'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;env_should_be will check these conditions before allowing the container to run. If any condition is not met, it can either block the container from running or using the &lt;strong&gt;-fs&lt;/strong&gt; argument, let it start and log the errors, depending on your preference…&lt;/p&gt;

&lt;h3&gt;
  
  
  Callback Scripts
&lt;/h3&gt;

&lt;p&gt;But that's not all—env_should_be also provides the ability to execute callback scripts whenever a container attempts to start with an environment that doesn't match the defined description. This feature is incredibly powerful because it enables you to take immediate corrective actions or trigger notifications when something is amiss.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why env_should_be Matters
&lt;/h2&gt;

&lt;p&gt;env_should_be offers a multifaceted solution to the challenges of microservices and multi-environment deployments:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Consistency and Compatibility
&lt;/h3&gt;

&lt;p&gt;By specifying environmental requirements, it ensures that containers only run in environments that can support them. This eliminates compatibility issues, reducing the likelihood of runtime errors and downtime.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Security and Compliance
&lt;/h3&gt;

&lt;p&gt;It empowers you to enforce security standards by defining strict criteria for environment variables. You can rest assured that your microservices are operating in a secure environment, mitigating potential security vulnerabilities.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Developer-Operations Collaboration
&lt;/h3&gt;

&lt;p&gt;With it, developers can define deployment requirements independently, reducing the need for constant coordination with operations teams. This fosters a more efficient and autonomous development workflow.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Error Handling and Notifications
&lt;/h3&gt;

&lt;p&gt;Error-handling options allow you to choose whether to block containers or let them start with errors logged. Additionally, the ability to trigger callback scripts ensures swift responses to deployment issues.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;To get started, you can easily install it via PyPI and integrate it into your Docker containers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# I believe you are using a venv, right?  &lt;/span&gt;
python &lt;span class="nt"&gt;-m&lt;/span&gt; pip &lt;span class="nb"&gt;install &lt;/span&gt;env_should_be
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  full list of possible descriptions:
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(
  "boolean",
  "length",
  "min_length",
  "max_length",
  "regex",
  "option",
  "constant",
  "is_int",
  "is_str",
  "is_float",
  "is_number",
  "is_greater_than_eq",
  "is_lower_than_eq",
  "is_http",
  "is_https",
  "is_ipv4",
  "is_ipv6",
  "is_email",
  "is_uuid",
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Feel free, to try it/ break it, and open PR.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/wassef911/env_should_be"&gt;source code&lt;br&gt;
&lt;/a&gt;&lt;br&gt;
&lt;a href="https://pypi.org/project/env-should-be/"&gt;latest version&lt;br&gt;
&lt;/a&gt;&lt;/p&gt;

</description>
      <category>microservices</category>
      <category>docker</category>
      <category>devops</category>
      <category>infrastructureascode</category>
    </item>
    <item>
      <title>The Concept Of Virtualization (hypervisor)</title>
      <dc:creator>wassef ben ahmed </dc:creator>
      <pubDate>Thu, 13 May 2021 20:06:04 +0000</pubDate>
      <link>https://dev.to/wassef911/the-concept-of-virtualization-hypervisor-3bmo</link>
      <guid>https://dev.to/wassef911/the-concept-of-virtualization-hypervisor-3bmo</guid>
      <description>&lt;p&gt;There are 7 primary types of virtualization, &lt;strong&gt;Hypervisor&lt;/strong&gt; being the topic of this article. &lt;/p&gt;




&lt;p&gt;We'll start by taking a look at what a server looks like without Virtualization.&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%2F1zfba89s3ulascn7ul4m.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%2F1zfba89s3ulascn7ul4m.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
We'll start by taking a look at what a server looks like without virtualization. In this example, our server is working with the physical hardware that it has, it's running a Windows OS that is serving a website over HTTP. As simple as this configuration might be we can run to some limitations along the way:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;our OS is tied to hardware, which means it is not portable and we can't easily move that OS and the application that is installed on it to another piece of hardware if we have some sort of issue or if wanted to upgrade the specs due to more/less traffic.&lt;/li&gt;
&lt;li&gt;the hardware might be underutilized because of the wrong estimation of what we need and in the context of cloud computing, this will cause a higher bill.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's now look at virtualization how it can help us solve some of these issues. &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%2Ftrlncedfksqck5nbv5d0.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%2Ftrlncedfksqck5nbv5d0.png" alt="image"&gt;&lt;/a&gt;&lt;br&gt;
So with a virtualization stack, we have a server with an extra layer of abstraction.&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%2Ff13bykkk4ha9ef51pae8.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%2Ff13bykkk4ha9ef51pae8.png" alt="image"&gt;&lt;/a&gt;&lt;br&gt;
this layer is able to present virtualized hardware to the operating system, in that case, we call it a virtual machine or VM for short. The VM has an allocation of resources, maybe the server has 32GB of RAM but we just give 8GB the VM, also a certain amount of CPU power, disk space, and an allocation of shared networking... There is no physical hardware here it's virtualized and presented by the hypervisor but the OS doesn't know that, it just sees hardware.&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%2Fepranu8y33xlutylqyz5.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%2Fepranu8y33xlutylqyz5.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;the cool part about this is being able to run multiple VMs on the same physical hardware, another benefit is that any instance of these VMs can easily be moved to another server if it failed, went down, or if you wanted to perform some upgrades on hardware.&lt;/p&gt;

&lt;h2&gt;
  
  
  useful resources:
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://aws.amazon.com/fr/blogs/compute/running-hyper-v-on-amazon-ec2-bare-metal-instances/" rel="noopener noreferrer"&gt;running Hyper-V in EC2&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cloudacademy.com/blog/aws-ami-hvm-vs-pv-paravirtual-amazon/" rel="noopener noreferrer"&gt;Amazon Machine Images (AWS AMI)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.quora.com/What-virtualization-software-does-EC2-use" rel="noopener noreferrer"&gt;What virtualization software does EC2 use?&lt;/a&gt;&lt;/p&gt;

</description>
      <category>cloud</category>
      <category>aws</category>
    </item>
    <item>
      <title>Open Source Software Licensing.</title>
      <dc:creator>wassef ben ahmed </dc:creator>
      <pubDate>Sat, 17 Oct 2020 17:53:03 +0000</pubDate>
      <link>https://dev.to/wassef911/open-source-software-licensing-1jl5</link>
      <guid>https://dev.to/wassef911/open-source-software-licensing-1jl5</guid>
      <description>&lt;h3&gt;
  
  
  The use of open-sourced code is inevitable. Whatever you may be working on, you will likely make use of code snippets from the web or some library that implements a sub-dependency relying on other people’s code.
&lt;/h3&gt;




&lt;p&gt;&lt;strong&gt;Is it risky to use open source software:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Some open-source licenses generally allow the use of their components as long as you maintain any copyright notices. But if you use a code with a restrictive license in your proprietary software, you might be legally obligated to release your software under the same license.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;What are the different types of open-source licenses:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Public domain: It means that anyone can modify and use the software without any restrictions&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Permissive:&lt;/em&gt;&lt;/strong&gt; contains minimal requirements about how the software can be modified or redistributed. Also known as “Apache-style” or “BSD style” another common variant is the MIT License.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;LGPL:&lt;/em&gt;&lt;/strong&gt; The GNU Lesser General Public License allows you to link to open source libraries in your software. If you simply compile or link an LGPL-licensed library with your own code, you can release your application under any license you want, even a proprietary license.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Copyleft:&lt;/em&gt;&lt;/strong&gt; also known as reciprocal licenses or restrictive licenses, allow you to modify the code and distribute new works based on it, as long as you meet the requirements for redistribution under the same license. &lt;/p&gt;




&lt;p&gt;&lt;strong&gt;What kind of risks are there using open-source licenses:&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Low-risk:&lt;/em&gt; Permissive licenses are considered low risk because it’s easy to meet their reuse requirements: Usually, you just have to retain the copyright notice, but you don’t have to expose your source code. Examples are the Apache and MIT Licenses.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Medium-risk:&lt;/em&gt; Semi-permissive licenses sometimes referred to as limited licenses, weak copyleft licenses, or simple copyleft licenses, are considered a medium risk because if you modify the code, you have to release the modifications, but not your whole application, under the same license. Different licenses define “modification” differently. Examples are the Mozilla and the Eclipse Public Licenses.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;High-risk:&lt;/em&gt; Restrictive licenses carry a great deal of legal risk. If you use a component with one of these licenses, you might be legally obligated to release your entire application code. Examples are the GNU GPL and GNU LGPL.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>should you learn THE CLOUD?</title>
      <dc:creator>wassef ben ahmed </dc:creator>
      <pubDate>Sun, 11 Oct 2020 20:07:25 +0000</pubDate>
      <link>https://dev.to/wassef911/should-you-learn-the-cloud-3gnc</link>
      <guid>https://dev.to/wassef911/should-you-learn-the-cloud-3gnc</guid>
      <description>&lt;h2&gt;
  
  
  keeping-up with technologies is very hectic, but bear with me, and let’s see if you should invest your time in it? or maybe not?  
&lt;/h2&gt;

&lt;p&gt;What is the cloud, I hear you ask! It’s 2020 everyone has heard of the term, but it seems like people don’t really know what it means, and they have weird expectations about what it can do. Let’s start with a simple definition.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;cloud computing:&lt;/strong&gt; the delivery of on-demand computing services, from applications to storage and processing power over the internet, and on a pay-as-you-go basis.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;do we really need it?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes, we DO! Whoever you may be, running your own startup, software developer, or just a user of a cloud application ( Gmail, Google Drive, Google Docs). Everyone will benefit time and money. Though I can nerd-out and keep ranting about the endless possibilities of cloud computing, I’m keeping it short so you don't spend the day on an article.   &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Are people really switching to the cloud?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt; Cloud-based apps are expanding by the day. Their number has nearly tripled between 2013 and 2016, from 545 to 1427 different services and revenue from the sector is expected to grow in adoption to 56% by 2020, jumping to $331 billion by 2022 (from $175.8 billion in 2018). &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;should you learn it?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt; Maybe, It all comes back to what you are interested to build. As it has not fully dominated the field yet, it’s not a must, but it will be replacing a lot of jobs and creating new ones in the near future, so I think that early adopters we’ll have great leverage. If you have the time, I strongly recommend that you take the jump. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Top cloud providers (2020):&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt; 1. Amazon Web Services.&lt;/p&gt;

&lt;p&gt; 2. Microsoft Azure.&lt;/p&gt;

&lt;p&gt; 3. Google Cloud Platform.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>aws</category>
      <category>firebase</category>
      <category>azure</category>
    </item>
    <item>
      <title>Git terms for dummies!</title>
      <dc:creator>wassef ben ahmed </dc:creator>
      <pubDate>Wed, 05 Aug 2020 02:55:51 +0000</pubDate>
      <link>https://dev.to/wassef911/git-terms-for-dummies-319g</link>
      <guid>https://dev.to/wassef911/git-terms-for-dummies-319g</guid>
      <description>&lt;p&gt;Mid journey toward learning to code you came across the term GIT whether it is mentioned in a tutorial, or you've seen it on every job posting out there. This is the article for you, I'll try to explain the most common terms used and give you a glimpse of what this tool has to offer. &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;&lt;em&gt;GIT :&lt;/em&gt;&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Git is a version control system, it’s simply a tool for programmers to coordinate their work, providing a better workflow for teams. &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;&lt;em&gt;Repository :&lt;/em&gt;&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Repository is a treasury for your code. &lt;br&gt;
A repository consists of a folder containing files of code / images / text …&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;&lt;em&gt;Remote :&lt;/em&gt;&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Remote repository is a version of your project on the internet that is hosted on a web-based version control like GitHub.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;&lt;em&gt;Branching :&lt;/em&gt;&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Branching out or creating a new branch is having another copy of your code on the same repository and is used to give developers the freedom of experimenting and working on new features without the fear of altering the main project.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;&lt;em&gt;Merging :&lt;/em&gt;&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Merging is combining multiple branches of the project on the main branch that is commonly referred to as master.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;&lt;em&gt;Merge conflicts :&lt;/em&gt;&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Merge conflicts happens after trying to merge two branches caused by having concurrent changes in the same file that git doesn't know how to deal with.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;&lt;em&gt;The 3 git states :&lt;/em&gt;&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Modified:&lt;/strong&gt; A tracked file has been altered.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Staging:&lt;/strong&gt; Files that are ready to be committed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Committed:&lt;/strong&gt; A file the has been added to the last commit, committing is creating an image of the repository. Every commit has a hash to identify it, the author’s name, date, and a commit message.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>git</category>
      <category>beginners</category>
      <category>github</category>
    </item>
    <item>
      <title>What is POSIX?</title>
      <dc:creator>wassef ben ahmed </dc:creator>
      <pubDate>Tue, 21 Jul 2020 23:27:43 +0000</pubDate>
      <link>https://dev.to/wassef911/what-is-posix-2p0d</link>
      <guid>https://dev.to/wassef911/what-is-posix-2p0d</guid>
      <description>&lt;p&gt;It sure sounds like a cool name!&lt;br&gt;
POSIX stands for Portable Operating System Interface and is a family of standards, specified by the &lt;a href="https://en.wikipedia.org/wiki/Institute_of_Electrical_and_Electronics_Engineers"&gt;IEEE&lt;/a&gt; designed to facilitate application portability across &lt;strong&gt;UNIX&lt;/strong&gt; based systems.&lt;/p&gt;

&lt;p&gt;If you wrote your programs to rely on POSIX standards, you'll be able to port them easily among a large family of Unix derivatives.&lt;/p&gt;

&lt;p&gt;Honorable mentions of &lt;strong&gt;UNIX SYSTEMS&lt;/strong&gt; : &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QtNvTJEu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.howtogeek.com/wp-content/uploads/2014/02/history-of-unix.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QtNvTJEu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.howtogeek.com/wp-content/uploads/2014/02/history-of-unix.png" alt="alt text"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;em&gt;Some of the standards POSIX defines :&lt;/em&gt;
&lt;/h2&gt;



&lt;p&gt;1.&lt;strong&gt;C API&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Greatly extends &lt;a href="https://en.wikipedia.org/wiki/ANSI_C"&gt;STANDARD C&lt;/a&gt; with things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;file operations: mkdir, dirname, symlink, readlink, link.&lt;/li&gt;
&lt;li&gt;networking: socket().&lt;/li&gt;
&lt;li&gt;memory management: mmap, mlock, mprotect, advise.
Those APIs also determine the underlying system concepts on which they depend, forcing you to conform.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;2.&lt;strong&gt;CLI utilities&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;E.g: cd, ls, echo ...&lt;br&gt;
  Many utilities are direct shell front ends for a corresponding C API functions and some are implemented by Bash as built-ins.&lt;/p&gt;

&lt;p&gt;3.&lt;strong&gt;Shell language&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Support for the shell language.&lt;br&gt;
E.g :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;a &lt;span class="o"&gt;=&lt;/span&gt; 5&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$a&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;#to print the variable a.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4.&lt;strong&gt;Program exit status&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;ANSI C says 0 or EXIT_SUCCESS for success, EXIT_FAILURE for failure.&lt;br&gt;
what POSIX adds:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;126: command found but not executable.&lt;/li&gt;
&lt;li&gt;127: command not found.&lt;/li&gt;
&lt;li&gt;&amp;gt;128: terminated by a signal.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;5.&lt;strong&gt;Regular expression&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Support for the two types of regex (BRE/ERE).&lt;br&gt;
E.g :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'a.1'&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s1"&gt;'a.[[:digit:]]'&lt;/span&gt; 
&lt;span class="c"&gt;#search for a regex from the piped input &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;6.&lt;strong&gt;Filenames&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;/ is the path separator.&lt;/li&gt;
&lt;li&gt;NUL cannot be used. &lt;/li&gt;
&lt;li&gt;. is cwd, .. is parent.&lt;/li&gt;
&lt;li&gt;can only contain a-zA-Z0-9._-&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>linux</category>
      <category>unix</category>
      <category>computerscience</category>
      <category>c</category>
    </item>
    <item>
      <title>What is a Load Balancer?</title>
      <dc:creator>wassef ben ahmed </dc:creator>
      <pubDate>Thu, 09 Jul 2020 21:18:14 +0000</pubDate>
      <link>https://dev.to/wassef911/what-is-a-load-balancer-a7e</link>
      <guid>https://dev.to/wassef911/what-is-a-load-balancer-a7e</guid>
      <description>&lt;h1&gt;
  
  
  Why?
&lt;/h1&gt;




&lt;p&gt;imagine that you've worked on a startup website or a web app for a client and it started to get 100 visits per month. one year in, and the number of visits drastically increased to the point that the client called you complaining about the app's performance, so being the great engineer you are, you decided to upgrade the server's specs hoping it will solve the response time problem and it worked! &lt;/p&gt;

&lt;p&gt;But what if the server hits 3000 visits per minute and costumers started getting a  "502 bad gateway" and upgrading the server specs isn't an option being too expensive or that you are already using the maxed out specs the hosting service could offer.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hosting services list :

&lt;ol&gt;
&lt;li&gt;Bluehost.&lt;/li&gt;
&lt;li&gt;HostGator.&lt;/li&gt;
&lt;li&gt;InMotion.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Upgrading the specs or what is called &lt;strong&gt;vertical scaling&lt;/strong&gt; is sometimes accepted if used on a database server being that you need more storage or a better CPU to process data ...&lt;/p&gt;

&lt;p&gt;But what if, we still run into errors even after the upgrade?&lt;br&gt;
many factors may come into play even with a maxed-out server, the CPU handling the threads of different requests simultaneously will cause it to prioritize some of them in favor of others causing unwanted/unexpected behaviors...&lt;/p&gt;

&lt;p&gt;Imagine being in a restaurant that has 10 clients and a waiter that can't handle all incoming requests, so we replaced him with a four-armed waiter but that also didn't solve the problem being that, he takes a lot of trips to the kitchen and a client may order 4 plates that will occupy all 4 hands.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Clearly&lt;/strong&gt; the solution isn't surgically adding more hand to the waiter but in hiring another!&lt;br&gt;
He'll take some load off the first and we'll be distributing the pressure on both.&lt;br&gt;
That's what we're calling :&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;horizontal scaling :&lt;/strong&gt;&lt;br&gt;
adding more servers instead of maxing out the main server, which will consume a bit of the resources in each server making it easy to just add more, in a rush hour, and costing less than a &lt;strong&gt;gigantic&lt;/strong&gt; server.&lt;/p&gt;

&lt;p&gt;To apply horizontal scaling we need to deploy the code like we'ed normally do but on multiple servers &lt;em&gt;(let's say 10)&lt;/em&gt;&lt;br&gt;
Having the code duplicated on multiple places with &lt;strong&gt;NGINX&lt;/strong&gt; as a load balancer, it will distribute the incoming requests on our 10 servers&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://www.nginx.com/faq/what-are-the-load-balancing-algorithms-supported/"&gt;leveraging 6 algorithms to decide which one to use :&lt;/a&gt;
&lt;/h2&gt;

&lt;h6&gt;
  
  
  Weighted/Dynamic Round Robin.
&lt;/h6&gt;

&lt;h6&gt;
  
  
  Least Connections.
&lt;/h6&gt;

&lt;h6&gt;
  
  
  IP Hash.
&lt;/h6&gt;

&lt;h6&gt;
  
  
  Generic Hash.
&lt;/h6&gt;

&lt;h6&gt;
  
  
  Least Time.
&lt;/h6&gt;

&lt;h6&gt;
  
  
  Random.
&lt;/h6&gt;

</description>
      <category>beginners</category>
      <category>nginx</category>
      <category>backend</category>
      <category>loadbalancer</category>
    </item>
  </channel>
</rss>
