Last active
July 19, 2024 17:19
-
-
Save jjorissen52/bde86dfffc22c75a1a17c1eb056fbde7 to your computer and use it in GitHub Desktop.
Revisions
-
jjorissen52 revised this gist
Apr 16, 2021 . 1 changed file with 29 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -259,5 +259,34 @@ subsets: ``` # Migrations A good way to handle migrations is to run a `Job`: ```yaml kind: Job apiVersion: batch/v1 metadata: name: migrate spec: backoffLimit: 10 template: spec: volumes: - name: service-config secret: secretName: django-app-env containers: - name: migrate-app-db image: django-app command: [python, manage.py, migrate, --database, default] env: - name: ENV_FILE_PATH value: "/etc/env/.env" volumeMounts: - name: service-config mountPath: "/etc/env" readOnly: true ``` # Apply Build your containers and run `kubectl -f apply` on each of the kubernetes files you made. -
jjorissen52 revised this gist
Apr 14, 2021 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -160,7 +160,7 @@ events { } http { upstream django_app { server localhost:8000; } -
jjorissen52 revised this gist
Apr 14, 2021 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -233,7 +233,7 @@ http { ``` # Database You have the option to use an external database or a [StatefulSet](https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/), but here we just assume you are using an external database. You will need to create a `Service` and `Endpoint` for your Django app to connect to your database. Let's say your database server is bound to `172.20.20.5`: ```yaml kind: "Service" -
jjorissen52 revised this gist
Apr 14, 2021 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -26,7 +26,7 @@ CMD exec gunicorn --bind :$PORT --workers 1 --threads 4 my_app.wsgi You will also want to configure your app to pull from the environment or a file. I like to use `python-dotenv` for the best of both worlds. # Config You will need to make a kubernetes `Secret`, (the `DATABASE_HOST` setting shown below is assumed in the section on databases). This file will ultimately be mounted to `/etc/env/.env`, so in `settings.py` you will want to load the values from there. ```yaml apiVersion: v1 -
jjorissen52 revised this gist
Apr 14, 2021 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -49,7 +49,7 @@ stringData: ``` # Serving Static Files Gunicorn and other suitable WSGI servers for Django do not serve static files, so we will want to setup a reverse proxy server such as NGINX to take care of static files. In `settings.py`: ```python STATIC_ROOT = os.environ.get('STATIC_ROOT_PATH', BASE_DIR / 'static') -
jjorissen52 revised this gist
Apr 14, 2021 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -231,7 +231,7 @@ http { } } ``` # Database You have the option to use an external database or a [StatefulSet](https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/), but here we will talk about using an external database. You will need to create a `Service` and `Endpoint` for your Django app to connect to your database. Let's say your database server is bound to `172.20.20.5`: -
jjorissen52 revised this gist
Apr 14, 2021 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -26,7 +26,7 @@ CMD exec gunicorn --bind :$PORT --workers 1 --threads 4 my_app.wsgi You will also want to configure your app to pull from the environment or a file. I like to use `python-dotenv` for the best of both worlds. # Config You will need to make a kubernetes `Secret`, (the `DATABASE_HOST` setting shown below is assumed in the on databases). This file will ultimately be mounted to `/etc/env/.env`, so in `settings.py` you will want to load the values from there. ```yaml apiVersion: v1 -
jjorissen52 revised this gist
Apr 14, 2021 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,6 +1,6 @@ If you are hosting a Django app with Kubernetes, there are a few things that you need to take care of. # Containerizing Here is a sample Dockerfile for a containerized app: ```Dockerfile -
jjorissen52 revised this gist
Apr 14, 2021 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -233,7 +233,7 @@ http { ``` #Database You have the option to use an external database or a [StatefulSet](https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/), but here we will talk about using an external database. You will need to create a `Service` and `Endpoint` for your Django app to connect to your database. Let's say your database server is bound to `172.20.20.5`: ```yaml kind: "Service" -
jjorissen52 revised this gist
Apr 14, 2021 . 1 changed file with 5 additions and 5 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,6 +1,6 @@ If you are hosting a Django app with Kubernetes, there are a few things that you need to take care of. # Containterizing Here is a sample Dockerfile for a containerized app: ```Dockerfile @@ -25,7 +25,7 @@ CMD exec gunicorn --bind :$PORT --workers 1 --threads 4 my_app.wsgi You will also want to configure your app to pull from the environment or a file. I like to use `python-dotenv` for the best of both worlds. # Config You will need to make a kubernetes `Secret`, e.g. (the `DATABASE_HOST` setting is assumed in section on databases). This file will ultimately be mounted to `/etc/env/.env` so in `settings.py` you will want to load the values from there. ```yaml @@ -48,7 +48,7 @@ stringData: API_VERSION= ``` # Serving Static Files Gunicorn and other suitable WSGI servers for Django do not server static files, so we will want to setup a reverse proxy server such as NGINX to take care of static files. In `settings.py`: ```python @@ -231,7 +231,7 @@ http { } } ``` #Database You have the option to use an external database or a [[StatefulSet|https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/]], but here we will talk about using an external database. You will need to create a `Service` and `Endpoint` for your Django app to connect to your database. Let's say your database server is bound to `172.20.20.5`: @@ -259,5 +259,5 @@ subsets: ``` # Apply Build your containers and run `kubectl -f apply` on each of the kubernetes files you made. -
jjorissen52 revised this gist
Apr 14, 2021 . 2 changed files with 263 additions and 215 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,215 +0,0 @@ This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,263 @@ If you are hosting a Django app with Kubernetes, there are a few things that you need to take care of. ! Containterizing Here is a sample Dockerfile for a containerized app: ```Dockerfile FROM python:3.9-buster RUN apt-get update \ --fix-missing \ && rm -rf /var/lib/apt/lists/* ENV APP_HOME /app WORKDIR $APP_HOME ADD requirements.txt requirements.txt RUN pip install -r requirements.txt --no-cache-dir \ && rm requirements.txt COPY . . ENV PORT 8000 CMD exec gunicorn --bind :$PORT --workers 1 --threads 4 my_app.wsgi ``` You will also want to configure your app to pull from the environment or a file. I like to use `python-dotenv` for the best of both worlds. ! Config You will need to make a kubernetes `Secret`, e.g. (the `DATABASE_HOST` setting is assumed in section on databases). This file will ultimately be mounted to `/etc/env/.env` so in `settings.py` you will want to load the values from there. ```yaml apiVersion: v1 kind: Secret metadata: name: django-app-env type: Opaque stringData: .env: | DEBUG=True USE_SQLITE=0 ALLOWED_HOSTS=*, INITIAL_ADMIN_EMAIL= INITIAL_ADMIN_PASSWORD= DATABASE_NAME= DATABASE_USER= DATABASE_PASSWORD= DATABASE_HOST=app-db # API_VERSION= ``` ! Serving Static Files Gunicorn and other suitable WSGI servers for Django do not server static files, so we will want to setup a reverse proxy server such as NGINX to take care of static files. In `settings.py`: ```python STATIC_ROOT = os.environ.get('STATIC_ROOT_PATH', BASE_DIR / 'static') ``` Then we make a `Deployment` and `Service` where a volume mount is shared between the Django app container and the NGINX container so that the app's staticfiles can be collected into a location that the NGINX container can read on initialization (`initContainers`) : ```yaml apiVersion: v1 kind: Service metadata: name: django-app spec: ports: - port: 8000 targetPort: 8080 type: LoadBalancer selector: app: django-app --- apiVersion: apps/v1 kind: Deployment metadata: name: django-app labels: app: django-app spec: replicas: 2 selector: matchLabels: app: django-app template: metadata: labels: app: django-app spec: volumes: - name: service-config secret: secretName: django-app-env - name: static emptyDir: { } # on container startup, move the collected staticfiles initContainers: - name: move-static image: django-app env: - name: STATIC_ROOT_PATH value: "/usr/share/nginx/static" volumeMounts: - name: static mountPath: /usr/share/nginx/static command: [ python, manage.py, collectstatic, --noinput ] containers: - name: app-nginx image: app-nginx ports: - containerPort: 8080 volumeMounts: - name: static mountPath: /usr/share/nginx/static - name: django-app image: django-app env: - name: ENV_FILE_PATH value: "/etc/env/.env" volumeMounts: - name: service-config mountPath: "/etc/env" readOnly: true livenessProbe: httpGet: path: / port: 8000 initialDelaySeconds: 3 ports: - containerPort: 8000 resources: requests: cpu: "1" memory: "1024Mi" limits: cpu: "2" memory: "2048Mi" ``` Here is a sample NGINX Dockerfile and conf: ```Dockerfile # Dockerfile FROM nginx:1.19 COPY nginx.conf /etc/nginx/nginx.conf ``` ``` # nginx.conf user nobody nogroup; # 'user nobody nobody;' for systems with 'nobody' as a group instead error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; # increase if you have lots of clients accept_mutex off; # set to 'on' if nginx worker_processes > 1 # 'use epoll;' to enable for Linux 2.6+ # 'use kqueue;' to enable for FreeBSD, OSX } http { upstream store { server localhost:8000; } server { listen 8080; root /usr/share/nginx; location / { # checks for static file, if not found proxy to app try_files $uri @proxy_to_app; } location @proxy_to_app { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; proxy_redirect off; proxy_pass http://django_app; } } types { text/html html htm shtml; text/css css; text/xml xml rss; image/gif gif; image/jpeg jpeg jpg; application/x-javascript js; text/plain txt; text/x-component htc; text/mathml mml; image/png png; image/x-icon ico; image/x-jng jng; image/vnd.wap.wbmp wbmp; application/java-archive jar war ear; application/mac-binhex40 hqx; application/pdf pdf; application/x-cocoa cco; application/x-java-archive-diff jardiff; application/x-java-jnlp-file jnlp; application/x-makeself run; application/x-perl pl pm; application/x-pilot prc pdb; application/x-rar-compressed rar; application/x-redhat-package-manager rpm; application/x-sea sea; application/x-shockwave-flash swf; application/x-stuffit sit; application/x-tcl tcl tk; application/x-x509-ca-cert der pem crt; application/x-xpinstall xpi; application/zip zip; application/octet-stream deb; application/octet-stream bin exe dll; application/octet-stream dmg; application/octet-stream eot; application/octet-stream iso img; application/octet-stream msi msp msm; audio/mpeg mp3; audio/x-realaudio ra; video/mpeg mpeg mpg; video/quicktime mov; video/x-flv flv; video/x-msvideo avi; video/x-ms-wmv wmv; video/x-ms-asf asx asf; video/x-mng mng; } } ``` !Database You have the option to use an external database or a [[StatefulSet|https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/]], but here we will talk about using an external database. You will need to create a `Service` and `Endpoint` for your Django app to connect to your database. Let's say your database server is bound to `172.20.20.5`: ```yaml kind: "Service" apiVersion: "v1" metadata: name: app-db spec: clusterIP: None ports: - port: 5432 --- kind: "Endpoints" apiVersion: "v1" metadata: name: app-db subsets: - addresses: - ip: "172.20.20.5" ports: - port: 5432 name: app-db ``` ! Apply Build your containers and run `kubectl -f apply` on each of the kubernetes files you made. -
jjorissen52 renamed this gist
Apr 14, 2021 . 1 changed file with 0 additions and 0 deletions.There are no files selected for viewing
File renamed without changes. -
jjorissen52 created this gist
Apr 14, 2021 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,215 @@ <div class="tc-tiddler-body tc-reveal"><p>If you are hosting a Django app with Kubernetes, there are a few things that you need to take care of.</p><h1 class="">Containterizing</h1><p>Here is a sample Dockerfile for a containerized app:</p><pre class="dockerfile hljs"><code><span class="hljs-keyword">FROM</span> python:<span class="hljs-number">3.9</span>-buster <span class="hljs-keyword">RUN</span><span class="bash"> apt-get update \ --fix-missing \ && rm -rf /var/lib/apt/lists/*</span> <span class="hljs-keyword">ENV</span> APP_HOME /app <span class="hljs-keyword">WORKDIR</span><span class="bash"> <span class="hljs-variable">$APP_HOME</span></span> <span class="hljs-keyword">ADD</span><span class="bash"> requirements.txt requirements.txt</span> <span class="hljs-keyword">RUN</span><span class="bash"> pip install -r requirements.txt --no-cache-dir \ && rm requirements.txt</span> <span class="hljs-keyword">COPY</span><span class="bash"> . .</span> <span class="hljs-keyword">ENV</span> PORT <span class="hljs-number">8000</span> <span class="hljs-keyword">CMD</span><span class="bash"> <span class="hljs-built_in">exec</span> gunicorn --<span class="hljs-built_in">bind</span> :<span class="hljs-variable">$PORT</span> --workers 1 --threads 4 my_app.wsgi</span></code></pre><p>You will also want to configure your app to pull from the environment or a file. I like to use <code>python-dotenv</code> for the best of both worlds.</p><h1 class="">Config</h1><p>You will need to make a kubernetes <code>Secret</code>, e.g. (the <code>DATABASE_HOST</code> setting is assumed in section on databases). This file will ultimately be mounted to <code>/etc/env/.env</code> so in <code>settings.py</code> you will want to load the values from there.</p><pre class="yaml hljs"><code><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">v1</span> <span class="hljs-attr">kind:</span> <span class="hljs-string">Secret</span> <span class="hljs-attr">metadata:</span> <span class="hljs-attr">name:</span> <span class="hljs-string">django-app-env</span> <span class="hljs-attr">type:</span> <span class="hljs-string">Opaque</span> <span class="hljs-attr">stringData:</span> <span class="hljs-string">.env:</span> <span class="hljs-string">| DEBUG=True USE_SQLITE=0 ALLOWED_HOSTS=*, INITIAL_ADMIN_EMAIL= INITIAL_ADMIN_PASSWORD= DATABASE_NAME= DATABASE_USER= DATABASE_PASSWORD= DATABASE_HOST=app-db # API_VERSION=</span></code></pre><h1 class="">Serving Static Files</h1><p>Gunicorn and other suitable WSGI servers for Django do not server static files, so we will want to setup a reverse proxy server such as NGINX to take care of static files. In <code>settings.py</code>:</p><pre class="python hljs"><code>STATIC_ROOT = os.environ.get(<span class="hljs-string">'STATIC_ROOT_PATH'</span>, BASE_DIR / <span class="hljs-string">'static'</span>)</code></pre><p>Then we make a <code>Deployment</code> and <code>Service</code> where a volume mount is shared between the Django app container and the NGINX container so that the app's staticfiles can be collected into a location that the NGINX container can read on initialization (<code>initContainers</code>) :</p><pre class="yaml hljs"><code><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">v1</span> <span class="hljs-attr">kind:</span> <span class="hljs-string">Service</span> <span class="hljs-attr">metadata:</span> <span class="hljs-attr">name:</span> <span class="hljs-string">django-app</span> <span class="hljs-attr">spec:</span> <span class="hljs-attr">ports:</span> <span class="hljs-bullet">-</span> <span class="hljs-attr">port:</span> <span class="hljs-number">8000</span> <span class="hljs-attr">targetPort:</span> <span class="hljs-number">8080</span> <span class="hljs-attr">type:</span> <span class="hljs-string">LoadBalancer</span> <span class="hljs-attr">selector:</span> <span class="hljs-attr">app:</span> <span class="hljs-string">django-app</span> <span class="hljs-meta">---</span> <span class="hljs-attr">apiVersion:</span> <span class="hljs-string">apps/v1</span> <span class="hljs-attr">kind:</span> <span class="hljs-string">Deployment</span> <span class="hljs-attr">metadata:</span> <span class="hljs-attr">name:</span> <span class="hljs-string">django-app</span> <span class="hljs-attr">labels:</span> <span class="hljs-attr">app:</span> <span class="hljs-string">django-app</span> <span class="hljs-attr">spec:</span> <span class="hljs-attr">replicas:</span> <span class="hljs-number">2</span> <span class="hljs-attr">selector:</span> <span class="hljs-attr">matchLabels:</span> <span class="hljs-attr">app:</span> <span class="hljs-string">django-app</span> <span class="hljs-attr">template:</span> <span class="hljs-attr">metadata:</span> <span class="hljs-attr">labels:</span> <span class="hljs-attr">app:</span> <span class="hljs-string">django-app</span> <span class="hljs-attr">spec:</span> <span class="hljs-attr">volumes:</span> <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">service-config</span> <span class="hljs-attr">secret:</span> <span class="hljs-attr">secretName:</span> <span class="hljs-string">django-app-env</span> <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">static</span> <span class="hljs-attr">emptyDir:</span> <span class="hljs-string">{</span> <span class="hljs-string">}</span> <span class="hljs-comment"># on container startup, move the collected staticfiles</span> <span class="hljs-attr">initContainers:</span> <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">move-static</span> <span class="hljs-attr">image:</span> <span class="hljs-string">django-app</span> <span class="hljs-attr">env:</span> <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">STATIC_ROOT_PATH</span> <span class="hljs-attr">value:</span> <span class="hljs-string">"/usr/share/nginx/static"</span> <span class="hljs-attr">volumeMounts:</span> <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">static</span> <span class="hljs-attr">mountPath:</span> <span class="hljs-string">/usr/share/nginx/static</span> <span class="hljs-attr">command:</span> <span class="hljs-string">[</span> <span class="hljs-string">python,</span> <span class="hljs-string">manage.py,</span> <span class="hljs-string">collectstatic,</span> <span class="hljs-string">--noinput</span> <span class="hljs-string">]</span> <span class="hljs-attr">containers:</span> <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">app-nginx</span> <span class="hljs-attr">image:</span> <span class="hljs-string">app-nginx</span> <span class="hljs-attr">ports:</span> <span class="hljs-bullet">-</span> <span class="hljs-attr">containerPort:</span> <span class="hljs-number">8080</span> <span class="hljs-attr">volumeMounts:</span> <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">static</span> <span class="hljs-attr">mountPath:</span> <span class="hljs-string">/usr/share/nginx/static</span> <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">django-app</span> <span class="hljs-attr">image:</span> <span class="hljs-string">django-app</span> <span class="hljs-attr">env:</span> <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">ENV_FILE_PATH</span> <span class="hljs-attr">value:</span> <span class="hljs-string">"/etc/env/.env"</span> <span class="hljs-attr">volumeMounts:</span> <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">service-config</span> <span class="hljs-attr">mountPath:</span> <span class="hljs-string">"/etc/env"</span> <span class="hljs-attr">readOnly:</span> <span class="hljs-literal">true</span> <span class="hljs-attr">livenessProbe:</span> <span class="hljs-attr">httpGet:</span> <span class="hljs-attr">path:</span> <span class="hljs-string">/</span> <span class="hljs-attr">port:</span> <span class="hljs-number">8000</span> <span class="hljs-attr">initialDelaySeconds:</span> <span class="hljs-number">3</span> <span class="hljs-attr">ports:</span> <span class="hljs-bullet">-</span> <span class="hljs-attr">containerPort:</span> <span class="hljs-number">8000</span> <span class="hljs-attr">resources:</span> <span class="hljs-attr">requests:</span> <span class="hljs-attr">cpu:</span> <span class="hljs-string">"1"</span> <span class="hljs-attr">memory:</span> <span class="hljs-string">"1024Mi"</span> <span class="hljs-attr">limits:</span> <span class="hljs-attr">cpu:</span> <span class="hljs-string">"2"</span> <span class="hljs-attr">memory:</span> <span class="hljs-string">"2048Mi"</span> </code></pre><p>Here is a sample NGINX Dockerfile and conf:</p><pre class="dockerfile hljs"><code><span class="hljs-comment"># Dockerfile</span> <span class="hljs-keyword">FROM</span> nginx:<span class="hljs-number">1.19</span> <span class="hljs-keyword">COPY</span><span class="bash"> nginx.conf /etc/nginx/nginx.conf</span></code></pre><pre><code># nginx.conf user nobody nogroup; # 'user nobody nobody;' for systems with 'nobody' as a group instead error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; # increase if you have lots of clients accept_mutex off; # set to 'on' if nginx worker_processes > 1 # 'use epoll;' to enable for Linux 2.6+ # 'use kqueue;' to enable for FreeBSD, OSX } http { upstream store { server localhost:8000; } server { listen 8080; root /usr/share/nginx; location / { # checks for static file, if not found proxy to app try_files $uri @proxy_to_app; } location @proxy_to_app { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; proxy_redirect off; proxy_pass http://django_app; } } types { text/html html htm shtml; text/css css; text/xml xml rss; image/gif gif; image/jpeg jpeg jpg; application/x-javascript js; text/plain txt; text/x-component htc; text/mathml mml; image/png png; image/x-icon ico; image/x-jng jng; image/vnd.wap.wbmp wbmp; application/java-archive jar war ear; application/mac-binhex40 hqx; application/pdf pdf; application/x-cocoa cco; application/x-java-archive-diff jardiff; application/x-java-jnlp-file jnlp; application/x-makeself run; application/x-perl pl pm; application/x-pilot prc pdb; application/x-rar-compressed rar; application/x-redhat-package-manager rpm; application/x-sea sea; application/x-shockwave-flash swf; application/x-stuffit sit; application/x-tcl tcl tk; application/x-x509-ca-cert der pem crt; application/x-xpinstall xpi; application/zip zip; application/octet-stream deb; application/octet-stream bin exe dll; application/octet-stream dmg; application/octet-stream eot; application/octet-stream iso img; application/octet-stream msi msp msm; audio/mpeg mp3; audio/x-realaudio ra; video/mpeg mpeg mpg; video/quicktime mov; video/x-flv flv; video/x-msvideo avi; video/x-ms-wmv wmv; video/x-ms-asf asx asf; video/x-mng mng; } }</code></pre><h1 class="">Database</h1><p>You have the option to use an external database or a <a href="https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/" class="tc-tiddlylink-external" target="_blank" rel="noopener noreferrer">StatefulSet</a>, but here we will talk about using an external database. You will need to create a <code>Service</code> and <code>Endpoint</code> for your Django app to connect to your database. Let's say your database server is bound to <code>172.20.20.5</code>:</p><pre class="yaml hljs"><code><span class="hljs-attr">kind:</span> <span class="hljs-string">"Service"</span> <span class="hljs-attr">apiVersion:</span> <span class="hljs-string">"v1"</span> <span class="hljs-attr">metadata:</span> <span class="hljs-attr">name:</span> <span class="hljs-string">app-db</span> <span class="hljs-attr">spec:</span> <span class="hljs-attr">clusterIP:</span> <span class="hljs-string">None</span> <span class="hljs-attr">ports:</span> <span class="hljs-bullet">-</span> <span class="hljs-attr">port:</span> <span class="hljs-number">5432</span> <span class="hljs-meta">---</span> <span class="hljs-attr">kind:</span> <span class="hljs-string">"Endpoints"</span> <span class="hljs-attr">apiVersion:</span> <span class="hljs-string">"v1"</span> <span class="hljs-attr">metadata:</span> <span class="hljs-attr">name:</span> <span class="hljs-string">app-db</span> <span class="hljs-attr">subsets:</span> <span class="hljs-bullet">-</span> <span class="hljs-attr">addresses:</span> <span class="hljs-bullet">-</span> <span class="hljs-attr">ip:</span> <span class="hljs-string">"172.20.20.5"</span> <span class="hljs-attr">ports:</span> <span class="hljs-bullet">-</span> <span class="hljs-attr">port:</span> <span class="hljs-number">5432</span> <span class="hljs-attr">name:</span> <span class="hljs-string">app-db</span> </code></pre><h1 class="">Apply</h1><p>Build your containers and run <code>kubectl -f apply</code> on each of the kubernetes files you made.</p></div>