# these two lines ensure that WebSocket, and HTTP2 connection are forwarded correctly
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_redirect off;
proxy_buffering off;
# this forwards all traffic to the local server on port 8000
proxy_pass http://localhost:8000;
}
# This forwards all static requests to Django's STATIC_ROOT set in settings.py; it is generated using the collectstatic command.
location /static {
autoindex on;
alias /home/lame/lamegames.io/static_generated;
}
}
</pre>
### Setup
After all that, I was able to do the following:
<preclass="terminal">
# systemctl enable lamegames
</pre>
This enabled my `gunicorn` server to run once the server started.
NGINX is that way be default.
And tada! You now have a working Django project on a production server!
#### Notes
* If using ws:// websockets, change them to wss:// for secure web sockets.
* Make sure to use channels.routing.get_default_application() instead of django.get_asgi_application() if your're wanting to use channels/redis WebSockets.
<h1>How to Solve The Django Deployment Puzzle</h1>
<h4class="post-date line-under">Sunday, August 16 2020</h4>
<divclass="article">
<p>A few days ago I had a Django project I wanted to put on a real server.
This project is still in its infancy, but I thought it would be nice to put it on my resume and show my friends.
Little did I know the headache coming my way.
Here are some tips to help you not make the same mistakes as me.</p>
<h3id="asgi-servers">ASGI Servers</h3>
<p>Because my project used the ASGI (Asynchronous webServer Gateway Interface),
I needed to find a good production ASGI server to handle all the incoming requests.
The best thing I found was <ahref="http://www.uvicorn.org/">uvicorn</a>.
It focuses on speed, which is a priority, especially when using the ASGI protocol.</p>
<p>To run uvicorn on the command line for testing purposes, use something like the following:</p>
<preclass="terminal">
$ uvicorn --reload myapp.asgi:application
</pre>
<p>The <codeclass="highlighter-rouge">--reload</code> option says to reload the server if any of the files get updated.
This is not recommended in production.
Sadly, I thought this meant I would need to do a hard shutdown of the server process every time I wanted to update.
This turned out to not be the case.</p>
<h3id="workload-managers">Workload Managers</h3>
<p>There is another equine-named program called <ahref="https://gunicorn.org/">gunicorn</a>
which can hold a number of processes under its control.
An interesting feature of <codeclass="highlighter-rouge">gunicorn</code> is that it will gracefully switch from an old to a new deployment,
replacing the subprocesses one-by-one and eventually having only the new deployment active on all subprocesses.
The greatest part? Zero down time.
The server keeps any old processes open if there is communication with them,
then shift and new connections to the new deployment.
This was a very cool feature I wanted to take advantage of.</p>
<p>“Now hold on!” you might protest.
“gunicorn is a WSGI server!” … oh you got me there!
Yes, that’s right, <codeclass="highlighter-rouge">gunicorn</code> is paired with <codeclass="highlighter-rouge">uvicorn</code> to serve my files.</p>
<h3id="systemd">systemd</h3>
<p>Love it or hate it, the majority of Linux distributions use the <codeclass="highlighter-rouge">systemd</code> init system.
I decided it would be very convenient to have a .service file for my Django application to run automatically at boot.
<codeclass="highlighter-rouge">Systemd</code> allows me to do this with a file like the following one I stored in <codeclass="highlighter-rouge">/lib/systemd/system/lamegames.service</code>.</p>
<p>NGINX (pronounced engine-X) is a performance web server designed for speed and simplicity.
For the front facing side of the site, I do need a production web server like nginx.
Gunicorn simply doesn’t need all the features that nginx provides, but I do.
To configure my nginx installation, I used the following few directives to:</p>
<ol>
<li>Redirect most traffic towards the gunicorn server.</li>
<li>Redirect statically served files (CSS, JS, images) to the directory specified in the STATIC_ROOT variable of my <codeclass="highlighter-rouge">settings.py</code> file.</li>
<li>Use TLS to enable https://</li>
</ol>
<p>Serving the static files from nginx as opposed to the <codeclass="highlighter-rouge">gunicorn</code> server is necessary.
Gunicorn and other production A/WSGI web server will not set the proper MIME type over TLS.
This will cause your browser to not load the Javascript/CSS.</p>
<p>This is the important part of my nginx config.</p>
# these two lines ensure that WebSocket, and HTTP2 connection are forwarded correctly
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_redirect off;
proxy_buffering off;
# this forwards all traffic to the local server on port 8000
proxy_pass http://localhost:8000;
}
# This forwards all static requests to Django's STATIC_ROOT set in settings.py; it is generated using the collectstatic command.
location /static {
autoindex on;
alias /home/lame/lamegames.io/static_generated;
}
}
</pre>
<h3id="setup">Setup</h3>
<p>After all that, I was able to do the following:</p>
<preclass="terminal">
# systemctl enable lamegames
</pre>
<p>This enabled my <codeclass="highlighter-rouge">gunicorn</code> server to run once the server started.
NGINX is that way be default.</p>
<p>And tada! You now have a working Django project on a production server!</p>
<h4id="notes">Notes</h4>
<ul>
<li>If using ws:// websockets, change them to wss:// for secure web sockets.</li>
<li>Make sure to use channels.routing.get_default_application() instead of django.get_asgi_application() if your’re wanting to use channels/redis WebSockets.</li>
</ul>
</div>
<footer>
This page is mirrored on <ahref="https://beta.tait.tech/2020/08/16/django-deployment.html">beta.tait.tech</a>.
<?xml version="1.0" encoding="utf-8"?><feedxmlns="http://www.w3.org/2005/Atom"><generatoruri="https://jekyllrb.com/"version="4.0.0">Jekyll</generator><linkhref="http://localhost:4000/feed.xml"rel="self"type="application/atom+xml"/><linkhref="http://localhost:4000/"rel="alternate"type="text/html"/><updated>2020-08-15T15:40:55+00:00</updated><id>http://localhost:4000/feed.xml</id><entry><titletype="html">BSD Journey, Part 1</title><linkhref="http://localhost:4000/2020/08/15/openbsd1.html"rel="alternate"type="text/html"title="BSD Journey, Part 1"/><published>2020-08-15T00:00:00+00:00</published><updated>2020-08-15T00:00:00+00:00</updated><id>http://localhost:4000/2020/08/15/openbsd1</id><contenttype="html"xml:base="http://localhost:4000/2020/08/15/openbsd1.html"><p>As Linux becomes controlled by corporate sponsors and becomes more full of proprietary blobs, drivers, and even closed-source software like Steam,
<?xml version="1.0" encoding="utf-8"?><feedxmlns="http://www.w3.org/2005/Atom"><generatoruri="https://jekyllrb.com/"version="4.0.0">Jekyll</generator><linkhref="http://localhost:4000/feed.xml"rel="self"type="application/atom+xml"/><linkhref="http://localhost:4000/"rel="alternate"type="text/html"/><updated>2020-08-18T23:00:11+00:00</updated><id>http://localhost:4000/feed.xml</id><entry><titletype="html">How to Solve The Django Deployment Puzzle</title><linkhref="http://localhost:4000/2020/08/16/django-deployment.html"rel="alternate"type="text/html"title="How to Solve The Django Deployment Puzzle"/><published>2020-08-16T00:00:00+00:00</published><updated>2020-08-16T00:00:00+00:00</updated><id>http://localhost:4000/2020/08/16/django-deployment</id><contenttype="html"xml:base="http://localhost:4000/2020/08/16/django-deployment.html"><p>A few days ago I had a Django project I wanted to put on a real server.
This project is still in its infancy, but I thought it would be nice to put it on my resume and show my friends.
Little did I know the headache coming my way.
Here are some tips to help you not make the same mistakes as me.</p>
<p>There is another equine-named program called <a href="https://gunicorn.org/">gunicorn</a>
which can hold a number of processes under its control.
An interesting feature of <code class="highlighter-rouge">gunicorn</code> is that it will gracefully switch from an old to a new deployment,
replacing the subprocesses one-by-one and eventually having only the new deployment active on all subprocesses.
The greatest part? Zero down time.
The server keeps any old processes open if there is communication with them,
then shift and new connections to the new deployment.
This was a very cool feature I wanted to take advantage of.</p>
<p>“Now hold on!” you might protest.
“gunicorn is a WSGI server!” … oh you got me there!
Yes, that’s right, <code class="highlighter-rouge">gunicorn</code> is paired with <code class="highlighter-rouge">uvicorn</code> to serve my files.</p>
<p>Love it or hate it, the majority of Linux distributions use the <code class="highlighter-rouge">systemd</code> init system.
I decided it would be very convenient to have a .service file for my Django application to run automatically at boot.
<code class="highlighter-rouge">Systemd</code> allows me to do this with a file like the following one I stored in <code class="highlighter-rouge">/lib/systemd/system/lamegames.service</code>.</p>
<p>NGINX (pronounced engine-X) is a performance web server designed for speed and simplicity.
For the front facing side of the site, I do need a production web server like nginx.
Gunicorn simply doesn’t need all the features that nginx provides, but I do.
To configure my nginx installation, I used the following few directives to:</p>
<ol>
<li>Redirect most traffic towards the gunicorn server.</li>
<li>Redirect statically served files (CSS, JS, images) to the directory specified in the STATIC_ROOT variable of my <code class="highlighter-rouge">settings.py</code> file.</li>
<li>Use TLS to enable https://</li>
</ol>
<p>Serving the static files from nginx as opposed to the <code class="highlighter-rouge">gunicorn</code> server is necessary.
Gunicorn and other production A/WSGI web server will not set the proper MIME type over TLS.
This will cause your browser to not load the Javascript/CSS.</p>
<p>This is the important part of my nginx config.</p>
# these two lines ensure that WebSocket, and HTTP2 connection are forwarded correctly
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_redirect off;
proxy_buffering off;
# this forwards all traffic to the local server on port 8000
proxy_pass http://localhost:8000;
}
# This forwards all static requests to Django's STATIC_ROOT set in settings.py; it is generated using the collectstatic command.
location /static {
autoindex on;
alias /home/lame/lamegames.io/static_generated;
}
}
</pre>
<h3 id="setup">Setup</h3>
<p>After all that, I was able to do the following:</p>
<pre class="terminal">
# systemctl enable lamegames
</pre>
<p>This enabled my <code class="highlighter-rouge">gunicorn</code> server to run once the server started.
NGINX is that way be default.</p>
<p>And tada! You now have a working Django project on a production server!</p>
<h4 id="notes">Notes</h4>
<ul>
<li>If using ws:// websockets, change them to wss:// for secure web sockets.</li>
<li>Make sure to use channels.routing.get_default_application() instead of django.get_asgi_application() if your’re wanting to use channels/redis WebSockets.</li>
</ul></content><author><name></name></author><summarytype="html">A few days ago I had a Django project I wanted to put on a real server. This project is still in its infancy, but I thought it would be nice to put it on my resume and show my friends. Little did I know the headache coming my way. Here are some tips to help you not make the same mistakes as me.</summary></entry><entry><titletype="html">BSD Journey, Part 1</title><linkhref="http://localhost:4000/2020/08/15/openbsd1.html"rel="alternate"type="text/html"title="BSD Journey, Part 1"/><published>2020-08-15T00:00:00+00:00</published><updated>2020-08-15T00:00:00+00:00</updated><id>http://localhost:4000/2020/08/15/openbsd1</id><contenttype="html"xml:base="http://localhost:4000/2020/08/15/openbsd1.html"><p>As Linux becomes controlled by corporate sponsors and becomes more full of proprietary blobs, drivers, and even closed-source software like Steam,
One may wonder if there are other options out there.
For me, somebody that is intensely interested in security, there is one option: OpenBSD.</p>
@ -503,20 +623,4 @@ Although this may annoy your victim it is not dangerous security wise.</p>
<p>Those last two will ask for permission from the user (if their browser isn’t insanely insecure).</p>
<p>In my next article I’ll talk about a website I found which is vulnerable to this attack.
And, show you how you can run your own XSS attack.</p></content><author><name></name></author><summarytype="html">I found a cross-site scripting (XSS) attack in a well-known quiz hosting website. I disclosed the vulnerability to them years ago, so I thought now might be a good time to write about it.</summary></entry><entry><titletype="html">rfi: A Simple Linux utility to get a random file from a directory</title><linkhref="http://localhost:4000/2020/04/21/rfi.html"rel="alternate"type="text/html"title="rfi: A Simple Linux utility to get a random file from a directory"/><published>2020-04-21T00:00:00+00:00</published><updated>2020-04-21T00:00:00+00:00</updated><id>http://localhost:4000/2020/04/21/rfi</id><contenttype="html"xml:base="http://localhost:4000/2020/04/21/rfi.html"><p>I made a <a href="https://lbry.tv/@tait:7/rfi:5">little video</a> about this script I wrote:</p>
<pre class="terminal">
$ rfi
</pre>
<p>This program gets a random file from your current directory
if you do not specify one;
it gets a random file from the specified directory if you give it one like so:</p>
<pre class="terminal">
# rfi /etc/wireguard
</pre>
<p>Which is very useful if you want to start a random VPN configuration :)</p>
<p>The code, comments, etc. are on the <a href="https://github.com/TTWNO/scripts">Github</a>.</p></content><author><name></name></author><summarytype="html">I made a little video about this script I wrote:</summary></entry></feed>
And, show you how you can run your own XSS attack.</p></content><author><name></name></author><summarytype="html">I found a cross-site scripting (XSS) attack in a well-known quiz hosting website. I disclosed the vulnerability to them years ago, so I thought now might be a good time to write about it.</summary></entry></feed>
<imgid="main-img"src="/assets/img/banff.jpg"alt="A photot I took of the valley Banff, Alberta sits in">
<labelfor="main-img">Alberta, Canada</label>
</div>
### About
I am a student at the <ahref="https://sait.ca/">Southern Alberta Insitute of Technology (SAIT)</a>.
My fascination lies primarily with operating system internals and systems-level tools.
My goal is to bring the everyday computing environment of Linux/BSD nerds to visually impaired users, and to ensure the saftey, privacy and security of the internet.
Some of my projects reflect this.
I have all of my code projects hosted on [my Github](https://github.com/TTWNO).