<?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: rburkhardt</title>
    <description>The latest articles on DEV Community by rburkhardt (@rob32).</description>
    <link>https://dev.to/rob32</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%2F926366%2F17fd17a6-4193-481f-9bd9-fcdcd8b9b6c7.jpg</url>
      <title>DEV Community: rburkhardt</title>
      <link>https://dev.to/rob32</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rob32"/>
    <language>en</language>
    <item>
      <title>Self-Hosting Fonts - No more excuses</title>
      <dc:creator>rburkhardt</dc:creator>
      <pubDate>Thu, 29 Sep 2022 17:23:52 +0000</pubDate>
      <link>https://dev.to/rob32/self-hosting-fonts-no-more-excuses-3kk8</link>
      <guid>https://dev.to/rob32/self-hosting-fonts-no-more-excuses-3kk8</guid>
      <description>&lt;h3&gt;
  
  
  Google Fonts - Privacy &amp;amp; DSGVO
&lt;/h3&gt;

&lt;p&gt;For some time now it is &lt;em&gt;forbidden&lt;/em&gt; in germany to use the google-fonts-api for your website. The idea behind this is that the user has no chance to prevent google from loading the fonts when visiting the website. The whole thing has actually been known for a while, but I still see a lot of sites from the EU/GER using google-fonts. With this short blog post I try to draw some more attention to the problem and show you some tools that can solve the data-privacy dilemma quickly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Self-Hosting Fonts - Tools
&lt;/h3&gt;

&lt;p&gt;With the help of the &lt;code&gt;@font-face&lt;/code&gt; (&lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face" rel="noopener noreferrer"&gt;MDN&lt;/a&gt;) rule and a dedicated tool, the problem can be fixed in no time. Two of them I can recommend:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/majodev/google-webfonts-helper" rel="noopener noreferrer"&gt;google-webfonts-helper&lt;/a&gt; (wep-app &amp;amp; rest-api)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/rafaelmardojai/webfont-kit-generator" rel="noopener noreferrer"&gt;webfont-kit-generator&lt;/a&gt; (linux)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I came across the tool "Webfont-Kit-Generator" for linux only recently.&lt;/p&gt;

&lt;p&gt;With the helpful tool it is possible to generate woff/woff2 font formats from non-web fonts (otf &amp;amp; ttf). Additionally you get a css snippet which you can use for embedding.&lt;/p&gt;

&lt;p&gt;What I like the most is that you can also download google-fonts and convert them automatically. Webfont-Kit-Generator uses &lt;a href="https://github.com/fonttools/fonttools" rel="noopener noreferrer"&gt;fonttools&lt;/a&gt; (written in Python), that's pretty cool too.&lt;/p&gt;

&lt;p&gt;In the settings you can then adjust and optimize the fonts a little more (&lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/%40font-face/unicode-range" rel="noopener noreferrer"&gt;unicode-range&lt;/a&gt;, &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display" rel="noopener noreferrer"&gt;font-display&lt;/a&gt; etc.).&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%2Frob.fra1.cdn.digitaloceanspaces.com%2Fimages%2Fwebfont-kit-generator-screenshot.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%2Frob.fra1.cdn.digitaloceanspaces.com%2Fimages%2Fwebfont-kit-generator-screenshot.png" alt="webfont-kit-generator-screenshot"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The tool is also available via Flatpak and can be obtained from &lt;a href="https://flathub.org/apps/details/com.rafaelmardojai.WebfontKitGenerator" rel="noopener noreferrer"&gt;Flathub&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flatpak install flathub com.rafaelmardojai.WebfontKitGenerator
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As an alternative there is the &lt;a href="https://github.com/majodev/google-webfonts-helper" rel="noopener noreferrer"&gt;google-webfonts-helper&lt;/a&gt;. It can be used online and regardless of the operating system.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bottom line
&lt;/h3&gt;

&lt;p&gt;Actually, there is no reason to use google-fonts anymore (CDN). The average internet speed has become so fast that the performance hardly plays a role in self-hosting. The performance can even be improved when self hosting (adjustable charset, S3-CDN etc.). Also for privacy reasons I think it is important not to leave things like fonts to a data giant. Unfortunately, there are still a lot of sites that use google-fonts. Even medium-sized and large corporate sites from germany. I hope the trend goes here more in the direction of data privacy.&lt;/p&gt;

&lt;p&gt;Interesting links on the topic:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/google/fonts/issues/1495" rel="noopener noreferrer"&gt;GDPR compliance · Issue #1495 · google/fonts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developers.google.com/fonts/faq#what_does_using_the_google_fonts_api_mean_for_the_privacy_of_my_users" rel="noopener noreferrer"&gt;developers.google.com/fonts/faq&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.heise.de/news/DSGVO-Abmahnwelle-wegen-Google-Fonts-7206364.html" rel="noopener noreferrer"&gt;Angeblicher DSGVO-Verstoß: Abmahnwelle wegen Google Fonts | heise online&lt;/a&gt; (german)&lt;/li&gt;
&lt;/ul&gt;




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

&lt;p&gt;Originally published at &lt;a href="https://rburkhardt.com/" rel="noopener noreferrer"&gt;rburkhardt.com&lt;/a&gt;&lt;br&gt;
Feel free to subscribe to my &lt;a href="https://rburkhardt.com/feed/" rel="noopener noreferrer"&gt;RSS&lt;/a&gt; and connect on &lt;a href="https://twitter.com/rob_burkhardt" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; or &lt;a href="https://github.com/rob32" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>privacy</category>
      <category>tooling</category>
      <category>css</category>
    </item>
    <item>
      <title>Django Deployment - Postgres DBaaS</title>
      <dc:creator>rburkhardt</dc:creator>
      <pubDate>Mon, 26 Sep 2022 10:41:50 +0000</pubDate>
      <link>https://dev.to/rob32/django-deployment-postgres-dbaas-5ca7</link>
      <guid>https://dev.to/rob32/django-deployment-postgres-dbaas-5ca7</guid>
      <description>&lt;p&gt;During my last attempt to get a Postgres server up and running, I realized again how time consuming it actually is. In addition to the installation of the Postgres server, the whole server has to be secured. This can take a lot of time. With a small vps with many users there is also the limited perfomrnace.&lt;/p&gt;

&lt;p&gt;The alternative: &lt;strong&gt;DBaaS&lt;/strong&gt; (Database-as-a-Service).&lt;/p&gt;

&lt;p&gt;The advantages of a DBaaS are simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Time saving (server management and installation)&lt;/li&gt;
&lt;li&gt;Security ( reduced risk and best practice)&lt;/li&gt;
&lt;li&gt;Data-Security (automatic backups)&lt;/li&gt;
&lt;li&gt;Scalability (fast and easy to scale down and up)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Providers I can recommend are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.linode.com/de/products/postgresql/"&gt;Linode&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.digitalocean.com/products/managed-databases-postgresql"&gt;DigitalOcean&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://render.com/docs/databases"&gt;Render&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The service from &lt;em&gt;fly.io&lt;/em&gt; &lt;a href="https://fly.io/docs/reference/postgres/"&gt;Postgres on Fly&lt;/a&gt; also looks very promising.&lt;/p&gt;

&lt;h2&gt;
  
  
  Preparations
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Postgres
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;login: &lt;code&gt;psql -U doadmin -h host -p port -d database&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;database creation: &lt;code&gt;CREATE DATABASE djangodb;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;switch to the new db: &lt;code&gt;\c djangodb;&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After that we can create the new user with a secure password:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE USER djangouser WITH PASSWORD 'securepassword';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For everything to work smoothly django recommends the following paramenter (see &lt;a href="https://docs.djangoproject.com/en/4.1/ref/databases/#optimizing-postgresql-s-configuration"&gt;django-docs&lt;/a&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ALTER ROLE djangouser SET client_encoding TO 'utf8';

ALTER ROLE djangouser SET default_transaction_isolation TO 'read committed';

ALTER ROLE djangouser SET timezone TO 'UTC';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally we can change the privileges for our new user:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GRANT ALL PRIVILEGES ON DATABASE djangodb TO djangouser;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Django
&lt;/h3&gt;

&lt;p&gt;Here i decided to use &lt;a href="https://github.com/joke2k/django-environ"&gt;django-environ&lt;/a&gt;'s &lt;code&gt;env.db()&lt;/code&gt; for the &lt;code&gt;DATABASE_URL&lt;/code&gt;.&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="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;pathlib&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;environ&lt;/span&gt;

&lt;span class="n"&gt;BASE_DIR&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__file__&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parent&lt;/span&gt;

&lt;span class="n"&gt;env&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Env&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;env_file&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="n"&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="s"&gt;".env"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&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="n"&gt;isfile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env_file&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read_env&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env_file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;DATABASE_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"DATABASE_URL"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;DATABASE_URL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&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="s"&gt;"default"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&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="s"&gt;"default"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s"&gt;"ENGINE"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"django.db.backends.sqlite3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"NAME"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;BASE_DIR&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="s"&gt;"db.sqlite3"&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;&lt;strong&gt;Note about DigitalOcean's App Platform:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If we use DigitalOcean's App Platform, we can skip the dynamic variable &lt;code&gt;${dbname.DATABASE_URL}&lt;/code&gt; as &lt;code&gt;DATABASE_URL&lt;/code&gt;. This has always led to an empty database for me with a redeploy. Even if I created a database via DO's GUI before, and changed the variable accordingly.&lt;/p&gt;

&lt;p&gt;To ensure that our data is also available after a redeploy in the future, we can use the &lt;em&gt;Postgres-String&lt;/em&gt; as variable (with encryption on).&lt;/p&gt;

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

&lt;p&gt;(in connection with DO's Postgres DBaaS)&lt;/p&gt;

&lt;p&gt;I am very happy with the performance so far. If I need connection pooling (via PgBouncer) later, I can add it quickly and easily via DO's GUI. The price is a bit expensive for a single and smaller project, but quickly pays off when another project is added. With DigitalOcean the fun starts at 15€ and 3 databases (1GB Memory, 1 vCPU, 15GB Disk). &lt;/p&gt;




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

&lt;p&gt;Originally published at &lt;a href="https://rburkhardt.com/"&gt;rburkhardt.com&lt;/a&gt;&lt;br&gt;
Feel free to subscribe to my &lt;a href="https://rburkhardt.com/feed/"&gt;RSS&lt;/a&gt; and connect on &lt;a href="https://twitter.com/rob_burkhardt"&gt;Twitter&lt;/a&gt; or &lt;a href="https://github.com/rob32"&gt;Github&lt;/a&gt;&lt;/p&gt;

</description>
      <category>django</category>
      <category>tutorial</category>
      <category>cloud</category>
      <category>database</category>
    </item>
    <item>
      <title>Django deployment with App Platform &amp; S3 Space</title>
      <dc:creator>rburkhardt</dc:creator>
      <pubDate>Wed, 14 Sep 2022 18:27:48 +0000</pubDate>
      <link>https://dev.to/rob32/django-deployment-with-app-platform-s3-space-3ijf</link>
      <guid>https://dev.to/rob32/django-deployment-with-app-platform-s3-space-3ijf</guid>
      <description>&lt;h2&gt;
  
  
  Preface
&lt;/h2&gt;

&lt;p&gt;Recently i had to decide which hosting solution i want to use for my private blog. The blog was developed with the help of &lt;a href="https://rburkhardt.com/projects/devcase/"&gt;Dev-Case&lt;/a&gt; and is based on Django.&lt;/p&gt;

&lt;p&gt;Since i have read a lot of good things about &lt;strong&gt;PaaS&lt;/strong&gt; in connection with Django lately, the decision was made quickly.&lt;/p&gt;

&lt;p&gt;The providers to choose from were:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;DigitalOcean&lt;/li&gt;
&lt;li&gt;Railway&lt;/li&gt;
&lt;li&gt;Render&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the end, i decided to go with DigitalOcean because i have already had good experiences here (VPS, Space). Another plus for DO was that i didn't need another provider for the S3-Storage.&lt;/p&gt;

&lt;h2&gt;
  
  
  Preparation
&lt;/h2&gt;

&lt;p&gt;To be able to host my Django project with the App-Platform, i have made the following preparations:&lt;/p&gt;

&lt;h3&gt;
  
  
  Environment variables
&lt;/h3&gt;

&lt;p&gt;For this i use &lt;a href="https://github.com/joke2k/django-environ"&gt;django-environ&lt;/a&gt;.&lt;br&gt;
Here are a few basic settings:&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="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;pathlib&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.core.management.utils&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;get_random_secret_key&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;environ&lt;/span&gt;

&lt;span class="n"&gt;BASE_DIR&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__file__&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parent&lt;/span&gt;

&lt;span class="n"&gt;env&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Env&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;env_file&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="n"&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="s"&gt;".env"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&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="n"&gt;isfile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env_file&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read_env&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env_file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;SECRET_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SECRET_KEY"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;get_random_secret_key&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

&lt;span class="n"&gt;DEBUG&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"DEBUG"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;ALLOWED_HOSTS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"ALLOWED_HOSTS"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s"&gt;"127.0.0.1"&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;h3&gt;
  
  
  Database
&lt;/h3&gt;

&lt;p&gt;Here i decided to use Postgres.&lt;/p&gt;

&lt;p&gt;Thanks to &lt;strong&gt;django-environ&lt;/strong&gt; i can use a &lt;code&gt;DATABASE_URL&lt;/code&gt; here.&lt;br&gt;
A possibility to use SQLite should still exist but is a matter of personal taste.&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="n"&gt;DATABASE_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"DATABASE_URL"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;DATABASE_URL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&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="s"&gt;"default"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&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="s"&gt;"default"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s"&gt;"ENGINE"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"django.db.backends.sqlite3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"NAME"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;BASE_DIR&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="s"&gt;"db.sqlite3"&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;h3&gt;
  
  
  S3 Storage
&lt;/h3&gt;

&lt;p&gt;To be able to use the S3 compatible storage later on (DO Space):&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="n"&gt;USE_S3_STORAGE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"USE_S3_STORAGE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;AWS_ACCESS_KEY_ID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"AWS_ACCESS_KEY_ID"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;AWS_SECRET_ACCESS_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"AWS_SECRET_ACCESS_KEY"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;AWS_STORAGE_BUCKET_NAME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"AWS_STORAGE_BUCKET_NAME"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;AWS_S3_REGION_NAME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"AWS_S3_REGION_NAME"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;AWS_S3_ENDPOINT_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"AWS_S3_ENDPOINT_URL"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;AWS_S3_CUSTOM_DOMAIN&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"AWS_S3_CUSTOM_DOMAIN"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;AWS_LOCATION&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"AWS_LOCATION"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;AWS_IS_GZIPPED&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"AWS_IS_GZIPPED"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;AWS_S3_FILE_OVERWRITE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"AWS_S3_FILE_OVERWRITE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;AWS_DEFAULT_ACL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"AWS_DEFAULT_ACL"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"public-read"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;STATICFILES_DIRS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;str&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="n"&gt;joinpath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"static"&lt;/span&gt;&lt;span class="p"&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="nb"&gt;str&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="n"&gt;joinpath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"staticfiles"&lt;/span&gt;&lt;span class="p"&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="nb"&gt;str&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="n"&gt;joinpath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"media"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;USE_S3_STORAGE&lt;/span&gt;&lt;span class="p"&gt;:&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="s"&gt;"storages.backends.s3boto3.S3Boto3Storage"&lt;/span&gt;
    &lt;span class="n"&gt;STATICFILES_STORAGE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"storages.backends.s3boto3.S3Boto3Storage"&lt;/span&gt;

    &lt;span class="n"&gt;STATIC_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s"&gt;"https://&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;AWS_S3_ENDPOINT_URL&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;STATIC_ROOT&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/"&lt;/span&gt;
    &lt;span class="n"&gt;MEDIA_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s"&gt;"https://&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;AWS_S3_ENDPOINT_URL&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;MEDIA_ROOT&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/"&lt;/span&gt;

&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&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="s"&gt;"django.contrib.staticfiles.storage.StaticFilesStorage"&lt;/span&gt;
    &lt;span class="n"&gt;STATIC_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"static/"&lt;/span&gt;
    &lt;span class="n"&gt;MEDIA_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"/media/"&lt;/span&gt;

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  SSL
&lt;/h3&gt;

&lt;p&gt;A valid SSL certificate is supplied automatically:&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="n"&gt;SECURE_SSL_REDIRECT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SECURE_SSL_REDIRECT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&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="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SECURE_HSTS_SECONDS"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&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="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"SECURE_HSTS_INCLUDE_SUBDOMAINS"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;
&lt;span class="p"&gt;)&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="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SECURE_HSTS_PRELOAD"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&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="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SESSION_COOKIE_SECURE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&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="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"CSRF_COOKIE_SECURE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  PIP requirements
&lt;/h2&gt;

&lt;p&gt;The following packages are required:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;django
gunicorn
django-environ
psycopg2-binary
boto3
django-storages
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With the help of the &lt;em&gt;requirements.txt&lt;/em&gt; file, the buildtool later also recognizes that this is a python project.&lt;/p&gt;

&lt;h2&gt;
  
  
  App Platform
&lt;/h2&gt;

&lt;p&gt;Now that everything is ready, you can start creating the Django project on DO. A detailed instruction i save me at this point, because the docs and further post about it on the internet are very good.&lt;/p&gt;

&lt;p&gt;Important settings are (example Dev-Case):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;run_command: &lt;code&gt;gunicorn dev_case.wsgi:application --bind 0.0.0.0:8080 --worker-tmp-dir /dev/shm&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;http_port: &lt;code&gt;8080&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Depending on the project structure:&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;routes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/&lt;/span&gt;
&lt;span class="na"&gt;source_dir&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With a "dev" database a dynamic variable can be used as environment variable. Example: &lt;code&gt;${db.DATABASE_URL}&lt;/code&gt;. In this case the name of the database would be &lt;code&gt;db&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;When using a managed-databases from DO, you should create the database manually and not via the GUI. Otherwise, errors may occur with a redeploy. I will link a post about it here soon.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;edited (2022-09-26):&lt;/em&gt; &lt;a href="https://rburkhardt.com/blog/django-deployment-postgres-dbaas/"&gt;link&lt;/a&gt; to the post mentioned above.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;After the build process completes:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Access your app’s console through the console tab and run the following commands:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;python3 manage.py migrate&lt;/code&gt; for the initial database migrations&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;python3 manage.py createsuperuser&lt;/code&gt; to create an administrative user&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  S3 and CORS
&lt;/h2&gt;

&lt;p&gt;To prevent later errors with CORS, make the following adjustment in your Space setting:&lt;/p&gt;

&lt;p&gt;Your Space -&amp;gt; Settings -&amp;gt; CORS Configurations (Add):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add your domain (with wildcard) in "Origin", examples:

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;*ondigitalocean.app&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;*example.com&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Allow/Check:

&lt;ul&gt;
&lt;li&gt;GET, HEAD&lt;/li&gt;
&lt;/ul&gt;


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

&lt;p&gt;This should solve the problems with fonts, scripts etc. (missing header, Access-Control-Allow-Origin).&lt;/p&gt;

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

&lt;p&gt;I am very satisfied with DO's APP-Platform so far. The performance is good and i feel safe. Soon i will test the log forwarding. If there is something to write about it, i will link it here.&lt;/p&gt;




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

&lt;p&gt;Originally published at &lt;a href="https://rburkhardt.com/"&gt;rburkhardt.com&lt;/a&gt;&lt;br&gt;
Feel free to subscribe to my &lt;a href="https://rburkhardt.com/feed/"&gt;RSS&lt;/a&gt; and connect on &lt;a href="https://twitter.com/rob_burkhardt"&gt;Twitter&lt;/a&gt; or &lt;a href="https://github.com/rob32"&gt;Github&lt;/a&gt;&lt;/p&gt;

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