<?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: Chris</title>
    <description>The latest articles on DEV Community by Chris (@facepalm).</description>
    <link>https://dev.to/facepalm</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%2F1170908%2Ffc1891f7-5a16-4e93-a168-f03f29dbdb5d.png</url>
      <title>DEV Community: Chris</title>
      <link>https://dev.to/facepalm</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/facepalm"/>
    <language>en</language>
    <item>
      <title>How to Setup Autocompletion using Hinterland in Jupyter Notebook</title>
      <dc:creator>Chris</dc:creator>
      <pubDate>Sat, 04 Nov 2023 15:38:08 +0000</pubDate>
      <link>https://dev.to/facepalm/how-to-setup-autocompletion-using-hinterland-in-jupyter-notebook-40c8</link>
      <guid>https://dev.to/facepalm/how-to-setup-autocompletion-using-hinterland-in-jupyter-notebook-40c8</guid>
      <description>&lt;p&gt;In this tutorial, I will show you how to setup extensions and enable Hinterland in Jupyter Notebook. There is probably a way to set it up using &lt;code&gt;conda&lt;/code&gt; but I will use &lt;code&gt;pip&lt;/code&gt; in this tutorial to set it up.&lt;/p&gt;

&lt;p&gt;For this tutorial, I will assume following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;using Python 3.9 or higher&lt;/li&gt;
&lt;li&gt;running macOS or linux (may require different command for Windows)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Jupyter Notebook&lt;/strong&gt; is an open-source web application that allows you to create and share documents that contain live code, equations, visualizations, and narrative text. It is commonly used for data analysis, data visualization, machine learning, and scientific computing, but it can be employed for various other tasks as well. Jupyter Notebook provides an interactive and user-friendly environment for writing and running code, making it popular among data scientists, researchers, and educators.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hinterland&lt;/strong&gt; is an extension for Jupyter Notebook that provides code autocompletion suggestions in code cells as you type. It aims to enhance your coding experience by suggesting completions for variable names, functions, methods, and other code elements, which can save you time and reduce potential coding errors. It provides suggestions without you having to press tab key.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create Virtual Environment
&lt;/h2&gt;

&lt;p&gt;I like to use &lt;code&gt;venv&lt;/code&gt; to set up my virtual environment. It goes like this:&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;python3 &lt;span class="nt"&gt;-m&lt;/span&gt; venv &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;name&lt;/span&gt;&lt;span class="sh"&gt; of virtual environment&amp;gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&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;python3 &lt;span class="nt"&gt;-m&lt;/span&gt; venv venv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can activate it by typing this into the terminal&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;&lt;span class="nb"&gt;source &lt;/span&gt;venv/bin/activate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Install Jupyter Notebook
&lt;/h2&gt;

&lt;p&gt;There are different ways to install Jupyter Notebook on your computer. I personally use &lt;a href="https://docs.anaconda.com/free/navigator/index.html" rel="noopener noreferrer"&gt;Anaconda Navigator&lt;/a&gt;, but you can install it using &lt;code&gt;pip&lt;/code&gt;:&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="o"&gt;(&lt;/span&gt;venv&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;notebook
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can start notebook by:&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="o"&gt;(&lt;/span&gt;venv&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;jupyter notebook
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Use Virtual Environment as Kernel
&lt;/h2&gt;

&lt;p&gt;In Jupyter Notebook, a "kernel" is used as a computational engine that executes the code contained within the notebook. Each notebook can be associated with a specific kernel. I will show you how to use our virtual environment as kernel.&lt;/p&gt;

&lt;p&gt;First, make sure you have activated &lt;code&gt;venv&lt;/code&gt; by &lt;code&gt;source venv/bin/activate&lt;/code&gt;. Then we need to install &lt;code&gt;ipykernel&lt;/code&gt;.&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="o"&gt;(&lt;/span&gt;venv&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;ipykernel
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can install a kernel 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="o"&gt;(&lt;/span&gt;venv&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; ipykernel &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--user&lt;/span&gt; &lt;span class="nt"&gt;--name&lt;/span&gt; venv 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should replace &lt;code&gt;venv&lt;/code&gt; with your python environment.&lt;/p&gt;

&lt;p&gt;Now, you should be able to see your kernel when you start up Jupyter Notebook:&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%2F2p3ahi7jp0b9ltonkkn6.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%2F2p3ahi7jp0b9ltonkkn6.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Install Nbextensions
&lt;/h2&gt;

&lt;p&gt;When you start up the Jupyter Notebook, you may see an environment like below:&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%2Fddpu7juh91lfrgrf5tg1.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%2Fddpu7juh91lfrgrf5tg1.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Right now, you may not have the &lt;code&gt;Nbextensions&lt;/code&gt; tab. We need that tab to enable extensions, so let's install it now.&lt;/p&gt;

&lt;p&gt;(Make sure you are not running Jupyter Notebook.)&lt;/p&gt;

&lt;p&gt;You need to install few more Python packages:&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="o"&gt;(&lt;/span&gt;venv&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;jupyter_contrib_nbextensions
&lt;span class="o"&gt;(&lt;/span&gt;venv&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;jupyter_nbextensions_configurator
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once those packages are installed, run following commands:&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="o"&gt;(&lt;/span&gt;venv&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;jupyter contrib nbextension &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--user&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;venv&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;jupyter nbextensions_configurator &lt;span class="nb"&gt;enable&lt;/span&gt; &lt;span class="nt"&gt;--user&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first command copies the nbextensions’ javascript and css files into the jupyter server’s search directory, and edits some jupyter config files.&lt;/p&gt;

&lt;p&gt;The second command enables the nbextension.&lt;/p&gt;

&lt;p&gt;(You can find more information about these steps &lt;a href="https://jupyter-contrib-nbextensions.readthedocs.io/en/latest/install.html" rel="noopener noreferrer"&gt;here&lt;/a&gt;.)&lt;/p&gt;

&lt;p&gt;Now, when you start up the Notebook, you should be able to see the &lt;code&gt;Nbextensions&lt;/code&gt; tab.&lt;/p&gt;

&lt;p&gt;We are almost done. We just need to enable Hinterland now.&lt;/p&gt;

&lt;h1&gt;
  
  
  Enable Hinterland
&lt;/h1&gt;

&lt;p&gt;Go to Nbextensions tab.&lt;/p&gt;

&lt;p&gt;Make sure checkbox beside "disable configuration for nbextensions without ..." is unchecked.&lt;/p&gt;

&lt;p&gt;In the filter, type 'hinterland'. Make sure checkbox beside the Hinterland is checked to enable it:&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%2F6g6z8rl2jby4ta46p0sx.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%2F6g6z8rl2jby4ta46p0sx.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And that is it!&lt;/p&gt;

&lt;p&gt;If you create a notebook (make sure to use your virtual environment as a kernel), and start typing things, you will see code suggestion showing up automatically without pressing tab key all the time! :) &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%2Fvap71jg24wsq7inr9fq7.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%2Fvap71jg24wsq7inr9fq7.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>python</category>
      <category>machinelearning</category>
      <category>productivity</category>
    </item>
    <item>
      <title>How to Set Formatting and Linting on VSCode for Python using Black Formatter and Flake8 Extensions</title>
      <dc:creator>Chris</dc:creator>
      <pubDate>Thu, 12 Oct 2023 23:47:38 +0000</pubDate>
      <link>https://dev.to/facepalm/how-to-set-formatting-and-linting-on-vscode-for-python-using-black-formatter-and-flake8-extensions-322o</link>
      <guid>https://dev.to/facepalm/how-to-set-formatting-and-linting-on-vscode-for-python-using-black-formatter-and-flake8-extensions-322o</guid>
      <description>&lt;p&gt;In this tutorial, I will demonstrate how you might configure VSCode to use code formatter and linter for Python 3.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;code formatter&lt;/strong&gt; is a tool or software that automatically and consistently formats source code in a programming language according to a predefined set of style rules or coding conventions.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;code linter&lt;/strong&gt; (or simply "linter") is a tool that analyzes source code for potential errors, coding style violations, and other issues.&lt;/p&gt;

&lt;p&gt;These two tools are optional, but can be an essential part of maintaining code quality and consistency in software development projects, especially in large or collaborative teams where adherence to a common coding style is crucial.&lt;/p&gt;

&lt;p&gt;We will use &lt;a href="https://pypi.org/project/black/" rel="noopener noreferrer"&gt;Black&lt;/a&gt; as a Python code formatter, and &lt;a href="https://flake8.pycqa.org/en/latest/" rel="noopener noreferrer"&gt;Flake8&lt;/a&gt; as a Python linter.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install Extensions
&lt;/h2&gt;

&lt;p&gt;Black and Flake8 can be installed using pip, and configured that way. But it seems the built-in support is going to be deprecated soon. They are now migrating to individual Python tool extension. (Check &lt;a href="https://github.com/microsoft/vscode-python/wiki/Migration-to-Python-Tools-Extensions" rel="noopener noreferrer"&gt;here&lt;/a&gt; for more information.)&lt;/p&gt;

&lt;p&gt;On Visual Studio Code, go to View &amp;gt; Extensions to see list of extensions. Type "Black Formatter" to download extension from Microsoft. Do the same with "Flake8", also from Microsoft.&lt;/p&gt;

&lt;p&gt;(You might want to install "isort" as well - also from Microsoft - if you want your import statements to sort when you save file.)&lt;/p&gt;

&lt;p&gt;(If you want to disable these extensions, you can &lt;a href="https://code.visualstudio.com/docs/editor/extension-marketplace#_disable-an-extension" rel="noopener noreferrer"&gt;disable the extension&lt;/a&gt; per workspace in Visual Studio Code.)&lt;/p&gt;

&lt;p&gt;Now we are ready to use these tools.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create Settings File
&lt;/h2&gt;

&lt;p&gt;Create a new folder in the project root folder, and name it &lt;code&gt;.vscode&lt;/code&gt;. Inside newly created folder, create a json file and name it &lt;code&gt;settings.json&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3cns7dvkbnww9ua6kfql.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%2F3cns7dvkbnww9ua6kfql.png" alt="Project Folder" width="518" height="378"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Configure Black Formatter in Settings File
&lt;/h2&gt;

&lt;p&gt;The settings file is in json format, so you need to enclose everything in a curly bracket (&lt;code&gt;{ }&lt;/code&gt;). Let's first set the default formatter to use Black; you can do that by typing this into the &lt;code&gt;settings.json&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;editor.defaultFormatter&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ms-python.black-formatter&lt;/span&gt;&lt;span class="dl"&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;/div&gt;

&lt;p&gt;If you want VSCode to format on save, you need to write this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;editor.defaultFormatter&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ms-python.black-formatter&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;editor.formatOnSave&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// new&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;You can enforce a line length by passing an argument to Black Formatter:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="c1"&gt;// ...&lt;/span&gt;
   &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;black-formatter.args&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;--line-length&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;88&lt;/span&gt;&lt;span class="dl"&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;/div&gt;

&lt;p&gt;(The line length is 88 by default, which seems to be the recommended length.)&lt;/p&gt;

&lt;p&gt;If you want the settings to apply to specific language such as "Python", you can do that like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="c1"&gt;// ...&lt;/span&gt;
   &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;[python]&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;editor.codeActionsOnSave&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;source.organizeImports&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&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;/div&gt;

&lt;p&gt;The above code organize import statements when you save Python files. You can add previous settings here instead so it only applies to Python file (don't forget the commas):&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="c1"&gt;// ...&lt;/span&gt;
   &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;[python]&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;editor.codeActionsOnSave&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;source.organizeImports&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;editor.formatOnSave&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// new&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;h2&gt;
  
  
  Configure Flake8
&lt;/h2&gt;

&lt;p&gt;When you install Flake8 and enable the extension, it is automatically used without any additional settings applied. &lt;/p&gt;

&lt;p&gt;If you have a bug in the program or a typo, and you save a file, you can see that flake8 warns you with a message, such as:&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%2Fh4a2wc3gmzdhd0z0s210.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%2Fh4a2wc3gmzdhd0z0s210.png" alt="Flake8 Warning Message" width="790" height="346"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Just like Black Formatter, you can pass Flake8 with an argument. For example:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="c1"&gt;// ...&lt;/span&gt;
   &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flake8.args&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;--max-line-length&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;88&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;--extend-ignore&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;E203&lt;/span&gt;&lt;span class="dl"&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;/div&gt;

&lt;p&gt;You can set max length by using &lt;code&gt;--max-line-length&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;--extend-ignore&lt;/code&gt; can be used to ignore certain errors depending on their codes.&lt;/p&gt;

&lt;p&gt;Check these links for more information on the various codes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://black.readthedocs.io/en/stable/the_black_code_style/current_style.html#flake8" rel="noopener noreferrer"&gt;Flake8 Options&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://flake8.pycqa.org/en/6.1.0/user/error-codes.html" rel="noopener noreferrer"&gt;Flake8 Error/Violation Codes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pycodestyle.pycqa.org/en/latest/intro.html#error-codes" rel="noopener noreferrer"&gt;pycodestyle’s list of error codes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And that is basically it! There are more to the settings, and read Black and Flake8 documentation to learn more, but I hope this tutorial gives you an idea how it can be done.&lt;/p&gt;

&lt;p&gt;The finished settings might look like this:&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%2Fea5hdfbl3klrae42qtgk.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%2Fea5hdfbl3klrae42qtgk.png" alt="Final Settings" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hopefully this tutorial was helpful. Leave me comments if you have any questions :)&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>python</category>
      <category>tutorial</category>
      <category>vscode</category>
    </item>
    <item>
      <title>How to Deploy Production Django 4 using Google Cloud Run, Cloud SQL, and Cloud Storage</title>
      <dc:creator>Chris</dc:creator>
      <pubDate>Sun, 08 Oct 2023 16:35:54 +0000</pubDate>
      <link>https://dev.to/facepalm/how-to-deploy-production-django-4-using-google-cloud-run-cloud-sql-and-cloud-storage-2i7d</link>
      <guid>https://dev.to/facepalm/how-to-deploy-production-django-4-using-google-cloud-run-cloud-sql-and-cloud-storage-2i7d</guid>
      <description>&lt;p&gt;In this tutorial, I will show you how to deploy Django 4 application on Google Cloud using Cloud Run.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;We will cover the following&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create and connect to Cloud SQL database.&lt;/li&gt;
&lt;li&gt;Build Dockerfile image and push to Artifact Registry.&lt;/li&gt;
&lt;li&gt;Deploy app on Cloud Run using image from Artifact Registry.&lt;/li&gt;
&lt;li&gt;Use Secret Manager to handle Environment Variables securely.&lt;/li&gt;
&lt;li&gt;Serve static files from Cloud Storage.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;

&lt;p&gt;For this tutorial I will be using &lt;strong&gt;Django 4.2&lt;/strong&gt; and &lt;strong&gt;Python 3.10&lt;/strong&gt;. If you are using different versions, things may be slightly different. Also, I will be using Polls app from &lt;a href="https://docs.djangoproject.com/en/4.2/intro/tutorial01/" rel="noopener noreferrer"&gt;official Django 4.2 tutorials&lt;/a&gt; for demonstration, but feel free to use your own.&lt;/p&gt;

&lt;p&gt;This is not a tutorial on Django, Docker, command line, or GCP. I will assume you know the basics, but I will show you how to put them together! :)&lt;/p&gt;

&lt;h2&gt;
  
  
  Create Cloud SQL Database (PostgreSQL)
&lt;/h2&gt;

&lt;p&gt;For the tutorial, we will use PostgreSQL database. Go to Cloud SQL, and create an instance.&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%2Fzolky8hkxhqvwmb5tpoc.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%2Fzolky8hkxhqvwmb5tpoc.png" alt="Cloud SQL"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From the options, choose PostgreSQL. Give it an &lt;em&gt;instance ID&lt;/em&gt;, &lt;em&gt;Password&lt;/em&gt;, and set &lt;em&gt;Region&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Under "Customize your instance" &amp;gt; "Connections" make sure you select "Public IP" (we will use public ip for this tutorial)&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%2Frvf4itu4f8pyx7hizlqk.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%2Frvf4itu4f8pyx7hizlqk.png" alt="Instance IP assignment"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also Google your ip address, and add as an authorized network. (This is only needed for accessing database from local. You can use &lt;a href="https://cloud.google.com/sql/docs/postgres/sql-proxy" rel="noopener noreferrer"&gt;Cloud SQL Proxy&lt;/a&gt; as an alternative.)&lt;/p&gt;

&lt;p&gt;Leave the rest as defaults, and create instance. It will take a minute or so. Once it completes, you will be taken to an Overview page. Take notice of the "Public IP address", and "Connection name". We will need them to connect to database from locally and Cloud Run, respectively.&lt;/p&gt;

&lt;p&gt;Next, we need to create users. Go to "Users", and click "ADD USER ACCOUNT" and enter name and password:&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%2Fmdm9h96mosqyjkoi13y4.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%2Fmdm9h96mosqyjkoi13y4.png" alt="Users"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk6rpwtjxor2ibujhd8m5.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%2Fk6rpwtjxor2ibujhd8m5.png" alt="Create Users"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Write down this name and password somewhere, these will be &lt;strong&gt;DB_USER&lt;/strong&gt; and &lt;strong&gt;DB_PASSWORD&lt;/strong&gt;, respectively.&lt;/p&gt;

&lt;p&gt;Lastly, go to "Databases" and click "CREATE DATABASE". Give the database a name. (Will be our DB_NAME)&lt;/p&gt;

&lt;p&gt;And that is it! Now we are ready to connect to Cloud SQL database!&lt;/p&gt;

&lt;h2&gt;
  
  
  Connect to Cloud SQL Database (Local)
&lt;/h2&gt;

&lt;p&gt;In order to connect to PostgreSQL from Django, we need to install &lt;code&gt;psycopg2-binary&lt;/code&gt; library. Type following in the terminal:&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;pip &lt;span class="nb"&gt;install &lt;/span&gt;psycopg2-binary&lt;span class="o"&gt;==&lt;/span&gt;2.9.9


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

&lt;/div&gt;

&lt;p&gt;or &lt;br&gt;
&lt;code&gt;$ pip3 install psycopg2-binary==2.9.9&lt;/code&gt; if you are not using virtual environment.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;settings.py&lt;/code&gt; configure to use our Cloud SQL database instead of &lt;code&gt;sqlite3&lt;/code&gt; database:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="n"&gt;DATABASES&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;default&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&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;ENGINE&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;django.db.backends.postgresql_psycopg2&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;HOST&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;env&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DB_HOST&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;USER&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;env&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DB_USER&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;PASSWORD&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;env&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DB_PASSWORD&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;NAME&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;env&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DB_NAME&lt;/span&gt;&lt;span class="sh"&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;/div&gt;

&lt;p&gt;Make sure &lt;strong&gt;DB_HOST&lt;/strong&gt;, &lt;strong&gt;DB_USER&lt;/strong&gt;, &lt;strong&gt;DB_PASSWORD&lt;/strong&gt;, and &lt;strong&gt;DB_NAME&lt;/strong&gt; is set in the &lt;code&gt;.env&lt;/code&gt; file (You can just hard code it, but using environment variables are recommended for production).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DB_HOST&lt;/strong&gt;: use &lt;strong&gt;public ip&lt;/strong&gt; address&lt;br&gt;
&lt;strong&gt;DB_USER&lt;/strong&gt;: user created ('Admin' for me)&lt;br&gt;
&lt;strong&gt;DB_PASSWORD&lt;/strong&gt;: password created for the user (Admin)&lt;br&gt;
&lt;strong&gt;DB_NAME&lt;/strong&gt;: database name ('django-demo-db' for me)&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(I used &lt;a href="https://pypi.org/project/environs/" rel="noopener noreferrer"&gt;environs&lt;/a&gt;. Check it out if you want to set your project to use environment variables.)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Before we start our application, we need to &lt;code&gt;migrate&lt;/code&gt; and create our superuser. Type following in the terminal:&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;python manage.py migrate
&lt;span class="nv"&gt;$ &lt;/span&gt;python manage.py createsuperuser


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

&lt;/div&gt;

&lt;p&gt;&lt;em&gt;(If you are not connecting, check if you added your ip address to the trusted network in the previous section.)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Now when we run our app locally, we should be connected to Cloud SQL database!!&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;python manage.py runserver


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

&lt;/div&gt;

&lt;p&gt;Now let's deploy our app on Cloud Run.&lt;/p&gt;

&lt;h2&gt;
  
  
  Push Docker Image to Artifact Registry
&lt;/h2&gt;

&lt;p&gt;Before we go any farther, make sure you have Docker installed. And if you are using Docker Desktop, make sure you start it.&lt;/p&gt;

&lt;p&gt;Create &lt;code&gt;Dockerfile&lt;/code&gt; and &lt;code&gt;.dockerignore&lt;/code&gt; in your project root folder (right beside &lt;code&gt;manage.py&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;This is what I used, but you can create your own (&lt;strong&gt;For &lt;code&gt;CMD gunicorn&lt;/code&gt;, make sure you change &lt;code&gt;mysite&lt;/code&gt; and use yours instead&lt;/strong&gt;. For me &lt;code&gt;mysite&lt;/code&gt; is the folder that contains &lt;code&gt;settings.py&lt;/code&gt; and &lt;code&gt;wsgi.py&lt;/code&gt; files. Yours would probably be different.):&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;

&lt;span class="c"&gt;# Dockerfile&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; python:3.10.4-slim-bullseye&lt;/span&gt;

&lt;span class="c"&gt;# Set environment variables&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; PYTHONDONTWRITEBYTECODE 1&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; PYTHONUNBUFFERED 1&lt;/span&gt;

&lt;span class="c"&gt;# Set the working directory in the container&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;

&lt;span class="c"&gt;# Install system dependencies&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;apt-get update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    netcat postgresql-client mime-support &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; /var/lib/apt/lists/&lt;span class="k"&gt;*&lt;/span&gt;

&lt;span class="c"&gt;# Install Python dependencies&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; requirements.txt .&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--no-cache-dir&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt

&lt;span class="c"&gt;# Copy the Django project code into the container&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;

&lt;span class="c"&gt;# Expose the port (Cloud Run uses the PORT environment variable)&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; PORT 8080&lt;/span&gt;
&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 8080&lt;/span&gt;

&lt;span class="c"&gt;# Run the Django development server&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; exec gunicorn mysite.wsgi:application --bind :$PORT --workers 1 --threads 8&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;&lt;code&gt;.dockerignore&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;

.env
venv/
db.sqlite3


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

&lt;/div&gt;

&lt;p&gt;For production, we are using gunicorn, so let's install that:&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;pip &lt;span class="nb"&gt;install &lt;/span&gt;&lt;span class="nv"&gt;gunicorn&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;21.2.0


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

&lt;/div&gt;

&lt;p&gt;We also need to create &lt;code&gt;requirements.txt&lt;/code&gt; file:&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;pip freeze &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; requirements.txt


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

&lt;/div&gt;

&lt;p&gt;Make sure you update requirements.txt file every time you install a new pip library.&lt;/p&gt;

&lt;p&gt;Ok, now let's create our Docker repository on Artifact Registry on GCP.&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%2Fsn9cfx8nw7jnk66gqcc1.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%2Fsn9cfx8nw7jnk66gqcc1.png" alt="Artifact Registry"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Give it a name and region:&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%2Fdpdt5ebpxktmkc4u1f7m.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%2Fdpdt5ebpxktmkc4u1f7m.png" alt="name"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmipgfcprycy35ci5ecwe.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%2Fmipgfcprycy35ci5ecwe.png" alt="location"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you create your repo, click it from the list. You may need to &lt;a href="https://cloud.google.com/sdk/docs/?_ga=2.189184366.-451893564.1664934102" rel="noopener noreferrer"&gt;initialize gcloud&lt;/a&gt; and configure Docker. Take a look at &lt;code&gt;SETUP INSTRUCTIONS&lt;/code&gt; for more details.&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%2Fho0n6no63wlavxfx68cn.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%2Fho0n6no63wlavxfx68cn.png" alt="Setup Instructions"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Configuring Docker by typing following in terminal:&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;gcloud auth configure-docker &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;your&lt;/span&gt;&lt;span class="sh"&gt;-region&amp;gt;&amp;gt;-docker.pkg.dev


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

&lt;/div&gt;

&lt;p&gt;Now that we have set up our repo, let's build our Docker image. Make sure you are in the same directory as your &lt;code&gt;Dockerfile&lt;/code&gt;, and type following in terminal:&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 build &lt;span class="nt"&gt;-t&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;image&lt;/span&gt;&lt;span class="sh"&gt;-name&amp;gt;&amp;gt; .


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

&lt;/div&gt;

&lt;p&gt;We also need to tag it before we push:&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 tag &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;image&lt;/span&gt;&lt;span class="sh"&gt;-name&amp;gt;&amp;gt; &amp;lt;&amp;lt;region&amp;gt;&amp;gt;-docker.pkg.dev/&amp;lt;project-id&amp;gt;&amp;gt;/&amp;lt;&amp;lt;repo-name&amp;gt;&amp;gt;/&amp;lt;&amp;lt;image-name-you-want&amp;gt;&amp;gt;


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

&lt;/div&gt;

&lt;p&gt;Make sure you replace things with your own.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
If I used following:&lt;br&gt;
image-name: &lt;code&gt;django-demo&lt;/code&gt;&lt;br&gt;
region: &lt;code&gt;us-central1&lt;/code&gt;&lt;br&gt;
project-id: &lt;code&gt;ch-project&lt;/code&gt;&lt;br&gt;
repo-name: &lt;code&gt;django-test-repo&lt;/code&gt;&lt;br&gt;
image-name-yout-want: &lt;code&gt;django-demo&lt;/code&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 tag django-demo us-centra1-docker.pkg.dev/ch-project/django-test-repo/django-demo


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

&lt;/div&gt;

&lt;p&gt;Finally we can push our tagged image to repo on Artifact Registry:&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 push &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;region&lt;/span&gt;&lt;span class="sh"&gt;&amp;gt;&amp;gt;-docker.pkg.dev/&amp;lt;project-id&amp;gt;&amp;gt;/&amp;lt;&amp;lt;repo-name&amp;gt;&amp;gt;/&amp;lt;&amp;lt;image-name-you-want&amp;gt;&amp;gt;


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

&lt;/div&gt;

&lt;p&gt;In my case:&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 push us-centra1-docker.pkg.dev/ch-project/django-test-repo/django-demo


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

&lt;/div&gt;

&lt;p&gt;If you go to GCP Artifact Registry, you should see your image:&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%2Faeou9fbuui950yr3pl6y.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%2Faeou9fbuui950yr3pl6y.png" alt="Repositories"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Deploy using Cloud Run
&lt;/h2&gt;

&lt;p&gt;Finally, we are ready to deploy our application on Cloud Run.&lt;/p&gt;

&lt;p&gt;We are going to use the image that we pushed to Artifact Registry. We also need a service account to use with Cloud Run. This service account will need a following IAM role as a minimum:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cloud SQL Client&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now go to Cloud Run, and click &lt;code&gt;CREATE SERVICE&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Under "Deploy one revision from an existing container image", select image from Artifact Registry. Select the latest.&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%2Fzx9ruse71hqztkke0pki.jpeg" 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%2Fzx9ruse71hqztkke0pki.jpeg" alt="latest image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Under Authentication, select "Allow unauthenticate invocations".&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%2Fiu7ehjon5az99d7ywpcm.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%2Fiu7ehjon5az99d7ywpcm.png" alt="Authentication"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select the SQL instance you created from the drop down menu:&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%2Ftmgcv6fmmdk9e4my0gh4.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%2Ftmgcv6fmmdk9e4my0gh4.png" alt="Cloud SQL connections"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also make sure you include Environment Variables that are inside &lt;code&gt;.env&lt;/code&gt; file (Make sure the name matches the ones you use in the &lt;code&gt;settings.py&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;The exception is the DB_HOST. We used public IP address when we connected locally, but if we want to connect from Cloud Run, we have to use different value.&lt;/p&gt;

&lt;p&gt;DB_HOST: &lt;code&gt;/cloudsql/&amp;lt;&amp;lt;instance-connection-name&amp;gt;&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;code&gt;/cloudsql/ch-project:us-central1:django-demo-instance&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We can get the connection name from the Overview page of SQL instance we created. Don't forget &lt;code&gt;/cloudsql/&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjehlp4zk2650zuqessnn.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%2Fjehlp4zk2650zuqessnn.png" alt="Environment variables"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the later section I will show you a better way to manage Environment Variables using Secret Manager. For now, you can leave the rest as default, and create the Cloud Run service instance.&lt;/p&gt;

&lt;p&gt;It will take few seconds, but once it completes, you should see a url:&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%2F8r5eky19cjxor3h98qv2.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%2F8r5eky19cjxor3h98qv2.png" alt="Cloud Run URL"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you click it now, error message will show. That is because we have to include our url as Allowed Host in &lt;code&gt;settings.py&lt;/code&gt; (Make sure you use your own url instead):&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="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;127.0.0.1&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;localhost&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;django-demo-3parkuk6ra-uc.a.run.app&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Make sure you don't include "https://" or trailing "/" at the end of url.&lt;/p&gt;

&lt;p&gt;If you have forms, you will have to include this as well (you may have to uncomment it when you run locally):&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="n"&gt;CSRF_TRUSTED_ORIGINS&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;https://django-demo-3parkuk6ra-uc.a.run.app&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&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="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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now we need to build image, tag and push again (Make sure you save &lt;code&gt;settings.py&lt;/code&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 build &lt;span class="nt"&gt;-t&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;image&lt;/span&gt;&lt;span class="sh"&gt;-name&amp;gt;&amp;gt; .
&lt;/span&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="sh"&gt;docker tag &amp;lt;&amp;lt;image-name&amp;gt;&amp;gt; &amp;lt;&amp;lt;region&amp;gt;&amp;gt;-docker.pkg.dev/&amp;lt;project-id&amp;gt;&amp;gt;/&amp;lt;&amp;lt;repo-name&amp;gt;&amp;gt;/&amp;lt;&amp;lt;image-name-you-want&amp;gt;&amp;gt;
&lt;/span&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="sh"&gt;docker push &amp;lt;&amp;lt;region&amp;gt;&amp;gt;-docker.pkg.dev/&amp;lt;project-id&amp;gt;&amp;gt;/&amp;lt;&amp;lt;repo-name&amp;gt;&amp;gt;/&amp;lt;&amp;lt;image-name-you-want&amp;gt;&amp;gt;


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

&lt;/div&gt;

&lt;p&gt;Now go back to Cloud Run, and select &lt;code&gt;EDIT &amp;amp; DEPLOY NEW REVISION&lt;/code&gt;. Under &lt;code&gt;Container image URL&lt;/code&gt;, select new image you just pushed.&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%2Fy0eicgh1remitwzobf6v.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%2Fy0eicgh1remitwzobf6v.png" alt="New container image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Making sure "Serve this revision immediately" is selected, Deploy:&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%2Fr36vutenbeq7qzfm1jdl.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%2Fr36vutenbeq7qzfm1jdl.png" alt="Deploy Cloud Run instance"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Congrats! If you check the url, your app should be working now!&lt;/p&gt;

&lt;h2&gt;
  
  
  Use Secret Manager (Better Way to Manage Environment Variables)
&lt;/h2&gt;

&lt;p&gt;Alright, our app is up and running, but we can make it better by using Secret Manager to keep things more secure. You should create a new secret for each environment variable values that you want to keep secure, such as tokens and passwords. For this tutorial, I will create secrets for SECRET_KEY and DB_PASSWORD.&lt;/p&gt;

&lt;p&gt;Go to Cloud Run instance and click "EDIT &amp;amp; DEPLOY NEW REVISION".&lt;/p&gt;

&lt;p&gt;First, &lt;strong&gt;delete environment variables that you want to convert to secret&lt;/strong&gt; (can't have duplicates).&lt;/p&gt;

&lt;p&gt;Next, scroll down until you see "Secrets" and click "ADD A SECRET REFERENCE":&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%2Fyflmfzgyek0jedjk4eus.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%2Fyflmfzgyek0jedjk4eus.png" alt="New Secret reference"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click Secret drop down menu and select "CREATE NEW SECRET" to make "Create Secret" modal to appear.&lt;/p&gt;

&lt;p&gt;Fill in name (it could be anything as long as unique within project), and under "Secret value", enter just the value of the environment variables:&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%2Fj3whu7fmn7aa5jjtgm1c.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%2Fj3whu7fmn7aa5jjtgm1c.png" alt="Create Secret"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can leave the rest as default, and create secret. Then you need to change the "Reference method" to "Exposed as environment variable". Then you need to enter the environment variable name and choose the version. It should look like this:&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%2Futnsgtk6ruzzb901n7ta.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%2Futnsgtk6ruzzb901n7ta.png" alt="How new secret reference should look like"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can choose the latest as a version, but choosing specific version is recommended. Click "Done" to create it.&lt;/p&gt;

&lt;p&gt;Now we just need to repeat the same thing for the password. It should look something like this at the end:&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%2Firu24fhj7jlzq48qpciu.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%2Firu24fhj7jlzq48qpciu.png" alt="Final secrets list"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And that is it, now just Deploy the change. If you go to the URL, the app should work exactly the same! Yay!&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup Cloud Storage
&lt;/h2&gt;

&lt;p&gt;We are almost at the end. The application should be running fine on Cloud Run. However, our application is serving the static files. As more and more people use our app, more instance resources are used up. We will solve this issue by serving static files from Cloud Storage.&lt;/p&gt;

&lt;p&gt;First, let's start by creating Cloud Storage bucket. We will create a public bucket that is available for everyone.&lt;/p&gt;

&lt;p&gt;Go to Cloud Storage and Create a bucket. Give it a unique name, and choose same region as Cloud Run instance. Make sure "Enforce public access prevention on this bucket" is unchecked, and choose "Fine-grained" as our Access control:&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%2Fmr8rd8ptiiiixmgoasr6.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%2Fmr8rd8ptiiiixmgoasr6.png" alt="Create a Bucket"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Leave the rest as default, and create a bucket. Inside Bucket details, go to "PERMISSIONS" tab. We need to Grant Access to "allUsers", and give them &lt;strong&gt;Storage Object Viewer&lt;/strong&gt; role:&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%2Fmxzp16jcmrixtfu52wou.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%2Fmxzp16jcmrixtfu52wou.png" alt="Grant Access"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Save and press "ALLOW PUBLIC ACCESS" button. Now, we are ready to serve static files!&lt;/p&gt;

&lt;h2&gt;
  
  
  Serve Static Files on Cloud Storage
&lt;/h2&gt;

&lt;p&gt;We need to install &lt;code&gt;django-storages&lt;/code&gt; library, and update our &lt;code&gt;requirements.txt&lt;/code&gt; file:&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;pip &lt;span class="nb"&gt;install &lt;/span&gt;django-storages[google]&lt;span class="o"&gt;==&lt;/span&gt;1.14.1
&lt;span class="nv"&gt;$ &lt;/span&gt;pip freeze &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; requirements.txt


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

&lt;/div&gt;

&lt;p&gt;We also need to configure &lt;code&gt;settings.py&lt;/code&gt; to use our storage bucket:&lt;/p&gt;

&lt;p&gt;If you are using Django &amp;gt;=4.2, type:&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="n"&gt;STORAGES&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;default&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&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;BACKEND&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;storages.backends.gcloud.GoogleCloudStorage&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&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;staticfiles&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&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;BACKEND&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;storages.backends.gcloud.GoogleCloudStorage&lt;/span&gt;&lt;span class="sh"&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;/div&gt;

&lt;p&gt;If you are using Django &amp;lt; 4.2, type instead (&lt;em&gt;I am using 4.2, so I haven't tested this myself - it is from documentation&lt;/em&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="n"&gt;DEFAULT_FILE_STORAGE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;storages.backends.gcloud.GoogleCloudStorage&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;STATICFILES_STORAGE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;storages.backends.gcloud.GoogleCloudStorage&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Also for all Django version, type:&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
# Google Cloud Storage for Static File Serve
&lt;/span&gt;&lt;span class="n"&gt;GS_PROJECT_ID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;env&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GS_PROJECT_ID&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;GS_BUCKET_NAME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;env&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GS_BUCKET_NAME&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;GS_AUTO_CREATE_BUCKET&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
&lt;span class="n"&gt;GS_DEFAULT_ACL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;publicRead&lt;/span&gt;&lt;span class="sh"&gt;'&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;https://storage.googleapis.com/{}/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GS_BUCKET_NAME&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;&lt;em&gt;(You can check &lt;a href="https://django-storages.readthedocs.io/en/latest/backends/gcloud.html" rel="noopener noreferrer"&gt;cloud storage documentation&lt;/a&gt; to learn more.)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In your &lt;code&gt;.env&lt;/code&gt; file, make sure to include &lt;code&gt;GS_PROJECT_ID&lt;/code&gt; and &lt;code&gt;GS_BUCKET_NAME&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Don't forget to also set &lt;code&gt;STATICFILES_DIRS&lt;/code&gt; and &lt;code&gt;STATIC_ROOT&lt;/code&gt; properly in the settings file. Check &lt;a href="https://docs.djangoproject.com/en/4.2/ref/contrib/staticfiles/" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; for more details.&lt;/p&gt;

&lt;p&gt;Ok, now type following into terminal to collect static files:&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;python manage.py collectstatic


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

&lt;/div&gt;

&lt;p&gt;Type "yes" to overwrite existing files. It may take few minutes. When it completes, go to Cloud Storage bucket, and you will see your static files! (&lt;em&gt;Notice that there is no 'staticfiles' folder created in your project :)&lt;/em&gt;)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9v7z0t69mh00lptiayh3.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%2F9v7z0t69mh00lptiayh3.png" alt="storage bucket"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Congratulation! In the next section, we will make sure to update Cloud Run instance. (You should know how to do it, so go ahead and try!)&lt;/p&gt;

&lt;h2&gt;
  
  
  Update Cloud Run instance to use Storage Bucket
&lt;/h2&gt;

&lt;p&gt;First make sure everything is saved, and let's build our image again and push to repository (If you have 'staticfiles', you can delete it and add 'staticfiles' to &lt;code&gt;.dockerignore&lt;/code&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 build &lt;span class="nt"&gt;-t&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;image&lt;/span&gt;&lt;span class="sh"&gt;-name&amp;gt;&amp;gt; .
&lt;/span&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="sh"&gt;docker tag &amp;lt;&amp;lt;image-name&amp;gt;&amp;gt; &amp;lt;&amp;lt;region&amp;gt;&amp;gt;-docker.pkg.dev/&amp;lt;project-id&amp;gt;&amp;gt;/&amp;lt;&amp;lt;repo-name&amp;gt;&amp;gt;/&amp;lt;&amp;lt;image-name-you-want&amp;gt;&amp;gt;
&lt;/span&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="sh"&gt;docker push &amp;lt;&amp;lt;region&amp;gt;&amp;gt;-docker.pkg.dev/&amp;lt;project-id&amp;gt;&amp;gt;/&amp;lt;&amp;lt;repo-name&amp;gt;&amp;gt;/&amp;lt;&amp;lt;image-name-you-want&amp;gt;&amp;gt;


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

&lt;/div&gt;

&lt;p&gt;Now go to Cloud Run instance, and "EDIT &amp;amp; DEPLOY NEW REVISION" while making sure you use the new image.&lt;/p&gt;

&lt;p&gt;Also don't forget to include &lt;code&gt;GS_PROJECT_ID&lt;/code&gt; and &lt;code&gt;GS_BUCKET_NAME&lt;/code&gt; to Environment Variables.&lt;/p&gt;

&lt;p&gt;Now Deploy! Everything should work as intended now!&lt;/p&gt;

&lt;p&gt;And that is everything guys! It was a long article, but hopefully it was helpful. It was my first article, and writing isn't exactly my strength. I hope everything was clear, but if you have any questions, please leave comments. &lt;/p&gt;

</description>
      <category>django</category>
      <category>googlecloud</category>
      <category>tutorial</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
