<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Muhammad Haseeb - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Muhammad Haseeb - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Tue, 26 May 2026 10:36:20 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/author/haseebwrites/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Deploy Your Django Project on an EC2 Machine using GitHub Actions ]]>
                </title>
                <description>
                    <![CDATA[ Deploying a Django application can be streamlined and automated using GitHub Actions. This article provides a comprehensive guide on how to set up a continuous deployment pipeline for a Django project hosted on an AWS EC2 instance. By leveraging GitH... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-deploy-django-project-on-ec2/</link>
                <guid isPermaLink="false">66bb8fd2fce17a7d998852e2</guid>
                
                    <category>
                        <![CDATA[ Django ]]>
                    </category>
                
                    <category>
                        <![CDATA[ ec2 ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GitHub Actions ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Muhammad Haseeb ]]>
                </dc:creator>
                <pubDate>Tue, 30 Jan 2024 15:40:16 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/01/Deploying-Django-Project-on-EC2-Machine-using-GitHub-Actions.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Deploying a Django application can be streamlined and automated using GitHub Actions.</p>
<p>This article provides a comprehensive guide on how to set up a continuous deployment pipeline for a Django project hosted on an AWS EC2 instance.</p>
<p>By leveraging GitHub Actions, developers can automate their deployment process, making it more efficient and error-free.</p>
<h2 id="heading-prerequisites">Prerequisites</h2>
<ul>
<li>A Django project hosted in a GitHub repository.</li>
<li>An AWS EC2 instance set up for hosting a Django application.</li>
<li>Basic familiarity with YAML and GitHub workflows.</li>
</ul>
<h2 id="heading-how-to-set-up-the-ec2-instance">How to Set up the EC2 Instance</h2>
<p>Before diving into GitHub Actions, ensure your EC2 instance is ready to host your Django application. </p>
<p>Use the command below to connect to your EC2 instance:</p>
<pre><code>ssh -i /path/to/your-key.pem ec2-user@your-ec2-instance-public-dns
</code></pre><p>You can update your system packages using these:</p>
<pre><code>sudo apt-get update
sudo apt-get upgrade
</code></pre><p>Next, if you haven't already, install Python and Pip:</p>
<pre><code>sudo apt-get install python3
sudo apt-get install python3-pip
</code></pre><p>Then install Django using this command:</p>
<pre><code>pip3 install django
</code></pre><h2 id="heading-how-to-configure-a-web-server">How to Configure a Web Server</h2>
<p>In this section, you'll see how to configure your web server.</p>
<p>First, install Nginx:</p>
<pre><code>sudo apt-get install nginx
</code></pre><p>Then configure Nginx for Django. Start by creating a new configuration file for your Django project.</p>
<pre><code>sudo nano /etc/nginx/sites-available/mydjangoapp
</code></pre><p>Then add the following server block:</p>
<pre><code>server {
    listen <span class="hljs-number">80</span>;
    server_name your-domain.com;

    location = /favicon.ico { access_log off; log_not_found off; }
    location /<span class="hljs-keyword">static</span>/ {
        root /path/to/your/django/project;
    }

    location / {
        include proxy_params;
        proxy_pass http:<span class="hljs-comment">//unix:/path/to/your/gunicorn.sock;</span>
    }
}
</code></pre><p>Lastly, enable the Nginx configuration:</p>
<pre><code>sudo ln -s /etc/nginx/sites-available/mydjangoapp /etc/nginx/sites-enabled
sudo nginx -t
sudo systemctl restart nginx
</code></pre><h2 id="heading-how-to-setup-a-database">How to Setup a Database</h2>
<p>You can install PostgreSQL using this:</p>
<pre><code>sudo apt-get install postgresql postgresql-contrib
</code></pre><p>After the installation, create a database and user using this command:</p>
<pre><code>sudo -u postgres psql
</code></pre><p>Run this SQL query to create a new database and add a new user:</p>
<pre><code class="lang-sql"><span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">DATABASE</span> mydjangodb;
<span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">USER</span> mydjangouser <span class="hljs-keyword">WITH</span> <span class="hljs-keyword">PASSWORD</span> <span class="hljs-string">'password'</span>;
<span class="hljs-keyword">ALTER</span> <span class="hljs-keyword">ROLE</span> mydjangouser <span class="hljs-keyword">SET</span> client_encoding <span class="hljs-keyword">TO</span> <span class="hljs-string">'utf8'</span>;
<span class="hljs-keyword">ALTER</span> <span class="hljs-keyword">ROLE</span> mydjangouser <span class="hljs-keyword">SET</span> default_transaction_isolation <span class="hljs-keyword">TO</span> <span class="hljs-string">'read committed'</span>;
<span class="hljs-keyword">ALTER</span> <span class="hljs-keyword">ROLE</span> mydjangouser <span class="hljs-keyword">SET</span> timezone <span class="hljs-keyword">TO</span> <span class="hljs-string">'UTC'</span>;
<span class="hljs-keyword">GRANT</span> <span class="hljs-keyword">ALL</span> <span class="hljs-keyword">PRIVILEGES</span> <span class="hljs-keyword">ON</span> <span class="hljs-keyword">DATABASE</span> mydjangodb <span class="hljs-keyword">TO</span> mydjangouser;
\q
</code></pre>
<p>Then configure Django to use PostgreSQL. In your Django <code>settings.py</code> file, update the <code>DATABASES</code> setting:</p>
<pre><code class="lang-python">DATABASES = {
    <span class="hljs-string">'default'</span>: {
        <span class="hljs-string">'ENGINE'</span>: <span class="hljs-string">'django.db.backends.postgresql'</span>,
        <span class="hljs-string">'NAME'</span>: <span class="hljs-string">'mydjangodb'</span>,
        <span class="hljs-string">'USER'</span>: <span class="hljs-string">'mydjangouser'</span>,
        <span class="hljs-string">'PASSWORD'</span>: <span class="hljs-string">'password'</span>,
        <span class="hljs-string">'HOST'</span>: <span class="hljs-string">'localhost'</span>,
        <span class="hljs-string">'PORT'</span>: <span class="hljs-string">''</span>,
    }
}
</code></pre>
<p>The GitHub Actions workflow for deploying a Django project involves several key steps:</p>
<h3 id="heading-step-1-checkout-and-preparation">Step #1 - Checkout and Preparation</h3>
<p>The first step in your workflow is to check out the latest code from your GitHub repository and set up the environment for the deployment.</p>
<pre><code class="lang-yaml"><span class="hljs-attr">name:</span> <span class="hljs-string">Deploy</span> <span class="hljs-string">Django</span> <span class="hljs-string">to</span> <span class="hljs-string">EC2</span>

<span class="hljs-attr">on:</span>
  <span class="hljs-attr">push:</span>
    <span class="hljs-attr">branches:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">main</span>

<span class="hljs-attr">jobs:</span>
  <span class="hljs-attr">deploy:</span>
    <span class="hljs-attr">runs-on:</span> <span class="hljs-string">ubuntu-latest</span>
    <span class="hljs-attr">steps:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Checkout</span> <span class="hljs-string">repository</span>
      <span class="hljs-attr">uses:</span> <span class="hljs-string">actions/checkout@v2</span>
</code></pre>
<h3 id="heading-step-2-deployment-script">Step #2 - Deployment Script</h3>
<p>The deployment script involves pulling the latest code, installing dependencies, running migrations, and restarting the web and WSGI servers. </p>
<p>Create a new file <code>deploy_script.sh</code> on your EC2 machine and add the code below:</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>

DRY_RUN=<span class="hljs-variable">$1</span>

<span class="hljs-built_in">echo</span> <span class="hljs-string">"Pulling latest code from repository..."</span>
<span class="hljs-comment"># Skip actual git pull in dry run</span>
[ <span class="hljs-string">"<span class="hljs-variable">$DRY_RUN</span>"</span> != <span class="hljs-string">"true"</span> ] &amp;&amp; git pull origin main

<span class="hljs-built_in">echo</span> <span class="hljs-string">"Installing dependencies..."</span>
<span class="hljs-comment"># Skip actual installation in dry run</span>
[ <span class="hljs-string">"<span class="hljs-variable">$DRY_RUN</span>"</span> != <span class="hljs-string">"true"</span> ] &amp;&amp; pip install -r requirements.txt

<span class="hljs-built_in">echo</span> <span class="hljs-string">"Running migrations..."</span>
<span class="hljs-comment"># Skip actual migrations in dry run</span>
[ <span class="hljs-string">"<span class="hljs-variable">$DRY_RUN</span>"</span> != <span class="hljs-string">"true"</span> ] &amp;&amp; python manage.py migrate

<span class="hljs-built_in">echo</span> <span class="hljs-string">"Restarting the server..."</span>
<span class="hljs-comment"># Skip actual restart in dry run</span>
[ <span class="hljs-string">"<span class="hljs-variable">$DRY_RUN</span>"</span> != <span class="hljs-string">"true"</span> ] &amp;&amp; sudo systemctl restart myapp

<span class="hljs-built_in">echo</span> <span class="hljs-string">"Deployment complete."</span>
</code></pre>
<h3 id="heading-step-3-create-a-step-to-run-the-deployment-script">Step #3 - Create a Step to Run the Deployment Script</h3>
<p>Use GitHub Actions to SSH into your EC2 instance. You'll need to store your EC2 instance's SSH key as a GitHub secret.</p>
<pre><code class="lang-yaml"><span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Run</span> <span class="hljs-string">Deployment</span>
  <span class="hljs-attr">run:</span> <span class="hljs-string">|
    ssh -i ${{ secrets.EC2_SSH_KEY }} ec2-user@your-ec2-instance 'bash -s' &lt; deploy_script.sh
</span>  <span class="hljs-attr">env:</span>
    <span class="hljs-attr">ACTIONS_RUNNER_DEBUG:</span> <span class="hljs-literal">false</span>
</code></pre>
<h2 id="heading-security-considerations">Security Considerations</h2>
<p>Here are some security considerations to keep in mind:</p>
<ul>
<li><strong>SSH Keys</strong>: Store your SSH private keys securely in GitHub Secrets.</li>
<li><strong>Minimal Permissions</strong>: Ensure the EC2 instance's IAM role has minimal permissions necessary for deployment.</li>
</ul>
<h2 id="heading-testing-and-validation">Testing and Validation</h2>
<p>Before fully implementing this workflow, test it with a development or staging environment to ensure that the deployment process works as expected.</p>
<p><strong>Dry Run Deployment</strong>: Implement a step in your GitHub Actions workflow that does a 'dry run' of the deployment process. This can help validate the deployment scripts without affecting the live EC2 instance. Add the step below to pass <code>dry_run = true</code> in deployment script.</p>
<pre><code class="lang-yaml"><span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Dry</span> <span class="hljs-string">Run</span> <span class="hljs-string">Deployment</span>
  <span class="hljs-attr">run:</span> <span class="hljs-string">|
    ssh -i ${{ secrets.EC2_SSH_KEY }} ec2-user@your-ec2-instance 'bash -s' &lt; deploy_script.sh true
</span>  <span class="hljs-attr">env:</span>
    <span class="hljs-attr">ACTIONS_RUNNER_DEBUG:</span> <span class="hljs-literal">true</span>
</code></pre>
<p><strong>Logging and Monitoring</strong>: You can see current action capture logs of the deployment process from <code>deploy_script.sh</code>, which can be reviewed if any issues arise.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Automating Django deployments using GitHub Actions offers a streamlined and reliable way to manage application delivery. </p>
<p>By following the steps outlined above, developers can set up a robust deployment pipeline that pushes their latest Django code to an EC2 instance seamlessly upon every push to the main branch.</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
