Skip to content
This repository was archived by the owner on Mar 27, 2023. It is now read-only.

Commit de06734

Browse files
committed
Merge branch 'fix-ui' into 'develop'
Fix ui Closes #7 See merge request verbose-equals-true/django-postgres-vue-gitlab-ecs!9
2 parents dbe5b28 + c7d8011 commit de06734

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+1343
-315
lines changed

.dockerignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
documentation/
2+
cloudformation/
3+
.vscode
4+
cypress/videos/
5+
gitlab-runner
6+
kubernetes
7+
node_modules
8+
**/node_modules
9+
notes

backend/backend/settings/development.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
11
from .base import * # noqa
22

3+
SECRET_KEY = "my-secret-key"
4+
5+
DATABASES = {
6+
'default': {
7+
'ENGINE': 'django.db.backends.postgresql_psycopg2',
8+
'NAME': os.environ.get('RDS_DB_NAME', 'postgres'),
9+
'USER': os.environ.get('RDS_USERNAME', 'postgres'),
10+
'PASSWORD': os.environ.get('RDS_PASSWORD', 'postgres'),
11+
'HOST': os.environ.get('RDS_HOSTNAME', 'postgres'),
12+
'PORT': os.environ.get('RDS_PORT', 5432),
13+
}
14+
}
15+
16+
17+
318
DEBUG_APPS = [
419
'django_extensions',
520
'debug_toolbar'
@@ -54,3 +69,4 @@ def show_toolbar(request):
5469
STATIC_URL = '/static/'
5570

5671
STATIC_ROOT = '/static/'
72+
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from .development import * # noqa
2+
3+
print("loading minikube settings...")
4+
5+
DATABASES = {
6+
'default': {
7+
'ENGINE': 'django.db.backends.postgresql_psycopg2',
8+
'NAME': os.environ.get('POSTGRES_NAME', 'kubernetes_django'),
9+
'USER': os.environ.get('POSTGRES_USER', 'postgres'),
10+
'PASSWORD': os.environ.get('POSTGRES_PASSWORD', 'postgres'),
11+
'HOST': os.environ.get('POSTGRES_HOST', 'postgres'),
12+
'PORT': os.environ.get('POSTGRES_PORT', 5432),
13+
}
14+
}

docker-compose.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ version: '3.7'
22

33
services:
44

5-
db:
6-
container_name: db
5+
postgres:
6+
container_name: postgres
77
image: postgres
88
networks:
99
- main
@@ -66,7 +66,7 @@ services:
6666
- ./quasar:/app/:rw
6767
depends_on:
6868
- backend
69-
- db
69+
- postgres
7070
environment:
7171
- CHOKIDAR_USEPOLLING=true
7272
- GITHUB_KEY=${GITHUB_KEY}
@@ -107,7 +107,7 @@ services:
107107
- GOOGLE_OAUTH2_KEY=${GOOGLE_OAUTH2_KEY}
108108
- GOOGLE_OAUTH2_SECRET=${GOOGLE_OAUTH2_SECRET}
109109
depends_on:
110-
- db
110+
- postgres
111111

112112
asgiserver:
113113
<<: *backend

documentation/docs/.vuepress/config.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ module.exports = {
5555
{ text: "Vue Authentication", link: "/guide/vue-authentication/" }
5656
]
5757
},
58+
{
59+
text: "Topics",
60+
items: [{ text: "Minikube", link: "/topics/minikube/" }]
61+
},
5862
{
5963
text: "Source Code",
6064
link:
121 KB
Loading
Lines changed: 301 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,301 @@
1+
# Minikube
2+
3+
Minikube is a tool for running a single-node kubernetes cluster inside of a virtual machine. It is a popular tool for developing Kubernetes applications locally.
4+
5+
This topic will cover using `minikube` to set up the project Kubernetes locally.
6+
7+
I'll be following [this guide](https://medium.com/@markgituma/kubernetes-local-to-production-with-django-1-introduction-d73adc9ce4b4) to get started.
8+
9+
## Getting started
10+
11+
### Start minikube
12+
13+
To get started, bring up `minikube` with
14+
15+
```bash
16+
minikube start
17+
```
18+
19+
Optionally, run `minikube delete`, and then `minikube start` to start with a clean cluster.
20+
21+
I'll be using the following alias to use `kubectl`:
22+
23+
```bash
24+
alias k='kubectl'
25+
```
26+
27+
## Build the Django server Deployment
28+
29+
We need to build our `backend` image. In order for minikube to be able to use the image, we can set our docker client to point to the minikube docker host. To do this, run the following command:
30+
31+
```
32+
eval $(minikube docker-env)
33+
```
34+
35+
`$(minikube docker-env)` results in the following output:
36+
37+
```bash
38+
export DOCKER_TLS_VERIFY="1"
39+
export DOCKER_HOST="tcp://192.168.99.100:2376"
40+
export DOCKER_CERT_PATH="/home/brian/.minikube/certs"
41+
# Run this command to configure your shell:
42+
# eval $(minikube docker-env)
43+
```
44+
45+
Notice that the `DOCKER_HOST` is pointing to the minikube VM on docker's default port `2376`.
46+
47+
With these environment variables set, let's build the Django container image with the following command:
48+
49+
```bash
50+
docker build -t backend:<TAG> -f backend/scripts/dev/Dockerfile backend/
51+
```
52+
53+
**`deployment.yml`**
54+
55+
```yml
56+
apiVersion: apps/v1
57+
kind: Deployment
58+
metadata:
59+
name: django-backend
60+
labels:
61+
app: django-backend
62+
spec:
63+
replicas: 1
64+
selector:
65+
matchLabels:
66+
app: django-backend
67+
template:
68+
metadata:
69+
labels:
70+
app: django-backend
71+
spec:
72+
containers:
73+
- name: django-backend-container
74+
image: localhost:5000/backend
75+
command: ["./manage.py", "runserver"]
76+
ports:
77+
- containerPort: 8000
78+
```
79+
80+
Let's send this file to Kubernete API server with the following command:
81+
82+
```
83+
kubectl apply -f kubernetes/django/deployment.yml
84+
```
85+
86+
Your pod for the deployment should be starting. Inspect the pods with `k get pods`. If there is an error with container startup, you might see something like this:
87+
88+
```
89+
k get pods
90+
NAME READY STATUS RESTARTS AGE
91+
django-backend-dd798db99-hkv2p 0/1 Error 0 3s
92+
```
93+
94+
If this is the case, inspect the logs of the container with the following command:
95+
96+
I have intentionally cause the container to fail by not providing a `SECRET_KEY` environment variable (this is something that Django needs in order to start).
97+
98+
Let's inspect the container logs to confirm this:
99+
100+
```bash
101+
k logs django-backend-dd798db99-hkv2p
102+
Traceback (most recent call last):
103+
File "./manage.py", line 16, in <module>
104+
execute_from_command_line(sys.argv)
105+
File "/usr/local/lib/python3.7/site-packages/django/core/management/__init__.py", line 381, in execute_from_command_line
106+
utility.execute()
107+
File "/usr/local/lib/python3.7/site-packages/django/core/management/__init__.py", line 375, in execute
108+
self.fetch_command(subcommand).run_from_argv(self.argv)
109+
File "/usr/local/lib/python3.7/site-packages/django/core/management/base.py", line 323, in run_from_argv
110+
self.execute(*args, **cmd_options)
111+
File "/usr/local/lib/python3.7/site-packages/django/core/management/commands/runserver.py", line 60, in execute
112+
super().execute(*args, **options)
113+
File "/usr/local/lib/python3.7/site-packages/django/core/management/base.py", line 364, in execute
114+
output = self.handle(*args, **options)
115+
File "/usr/local/lib/python3.7/site-packages/django/core/management/commands/runserver.py", line 67, in handle
116+
if not settings.DEBUG and not settings.ALLOWED_HOSTS:
117+
File "/usr/local/lib/python3.7/site-packages/django/conf/__init__.py", line 79, in __getattr__
118+
self._setup(name)
119+
File "/usr/local/lib/python3.7/site-packages/django/conf/__init__.py", line 66, in _setup
120+
self._wrapped = Settings(settings_module)
121+
File "/usr/local/lib/python3.7/site-packages/django/conf/__init__.py", line 176, in __init__
122+
raise ImproperlyConfigured("The SECRET_KEY setting must not be empty.")
123+
django.core.exceptions.ImproperlyConfigured: The SECRET_KEY setting must not be empty.
124+
```
125+
126+
We could either provide a fallback value in the Django settings (which would require rebuilding the image), or we could add an environment variable to the container definition in the Pod `spec` in `deployment.yml`:
127+
128+
```yml
129+
spec:
130+
containers:
131+
- name: backend
132+
imagePullPolicy: IfNotPresent
133+
image: backend:latest
134+
command: ["./manage.py", "runserver"]
135+
ports:
136+
- containerPort: 8000
137+
env:
138+
- name: SECRET_KEY
139+
value: "my-secret-key"
140+
```
141+
142+
This should work, but we will still see errors in logs because we Django will attempt to establish a connection with the Postgres database which we will be setting up next.
143+
144+
We can hit our public facing `hello-world` endpoint which should serve as a nice health check for the Django container.
145+
146+
Let's test this endpoint with `curl`. We haven't set up a Kubernetes `Service` yet, so we will have to curl the Django application from within the cluster. We can do this with:
147+
148+
```
149+
k exec django-backend-757b5944d8-htssm -- curl -s http://172.17.0.5/api/hello-world/
150+
```
151+
152+
This gives us:
153+
154+
```
155+
command terminated with exit code 7
156+
```
157+
158+
Our container has started, but the database connection has prevented the Django process from starting. In our Pod logs, we can see that no request have been received and the Django application is not listening on `0.0.0.0:8000`.
159+
160+
Let's come back to this once we have set up our Postgres database.
161+
162+
## Postgres
163+
164+
First, we create a `PersistentVolume` resource:
165+
166+
**`kubernetes/postgres/volume.yml`**
167+
168+
```yml
169+
kind: PersistentVolume
170+
apiVersion: v1
171+
metadata:
172+
name: postgres-pv
173+
labels:
174+
type: local
175+
spec:
176+
storageClassName: manual
177+
capacity:
178+
storage: 2Gi
179+
accessModes:
180+
- ReadWriteOnce
181+
hostPath:
182+
path: /data/postgres-pv
183+
```
184+
185+
::: warning storageClassName
186+
Clicking on the `storageClassName` gave a 404 error
187+
:::
188+
189+
::: warning Authentication failure
190+
Message with postgres authentication failure
191+
:::
192+
193+
After changing the `postgres` user password, the migrations are able to run successfully:
194+
195+
```bash
196+
k exec django-784d668c8b-9gbf7 -it -- ./manage.py migrat
197+
e
198+
loading minikube settings...
199+
Operations to perform:
200+
Apply all migrations: accounts, admin, auth, contenttypes, sessions, social_django
201+
Running migrations:
202+
Applying contenttypes.0001_initial... OK
203+
Applying contenttypes.0002_remove_content_type_name... OK
204+
Applying auth.0001_initial... OK
205+
Applying auth.0002_alter_permission_name_max_length... OK
206+
Applying auth.0003_alter_user_email_max_length... OK
207+
Applying auth.0004_alter_user_username_opts... OK
208+
Applying auth.0005_alter_user_last_login_null... OK
209+
Applying auth.0006_require_contenttypes_0002... OK
210+
Applying auth.0007_alter_validators_add_error_messages... OK
211+
Applying auth.0008_alter_user_username_max_length... OK
212+
Applying auth.0009_alter_user_last_name_max_length... OK
213+
Applying auth.0010_alter_group_name_max_length... OK
214+
Applying auth.0011_update_proxy_permissions... OK
215+
Applying accounts.0001_initial... OK
216+
Applying admin.0001_initial... OK
217+
Applying admin.0002_logentry_remove_auto_add... OK
218+
Applying admin.0003_logentry_add_action_flag_choices... OK
219+
Applying sessions.0001_initial... OK
220+
Applying social_django.0001_initial... OK
221+
Applying social_django.0002_add_related_name... OK
222+
Applying social_django.0003_alter_email_max_length... OK
223+
Applying social_django.0004_auto_20160423_0400... OK
224+
Applying social_django.0005_auto_20160727_2333... OK
225+
Applying social_django.0006_partial... OK
226+
Applying social_django.0007_code_timestamp... OK
227+
Applying social_django.0008_partial_timestamp... OK
228+
```
229+
230+
::: warning Try this again
231+
Try this again with a clean version of minikube and using the Secrets resource.
232+
:::
233+
234+
I initially started the postgres container with a password set by environment variable. This may have set data in the
235+
236+
::: tip kubectl cheatsheet from kubernetes documentation
237+
[https://kubernetes.io/docs/reference/kubectl/cheatsheet/#viewing-finding-resources](https://kubernetes.io/docs/reference/kubectl/cheatsheet/#viewing-finding-resources)
238+
:::
239+
240+
241+
Show the service in kubernetes:
242+
243+
```
244+
minikube service kubernetes-django-service
245+
```
246+
247+
We have two options for how to run the frontend application in Kubernetes.
248+
249+
1) Servce the static content from Django
250+
2) Serve the static content from nginx and use another service.
251+
252+
Serving the static content from Django was not working, so I'm building another deployment/service for frontend. For this to work, we need to tell Quasar about the address for the Django service. There are two ways to do this:
253+
254+
1) DNS
255+
2) Environment variables
256+
257+
258+
## Use environment variables to get service IP/Host
259+
260+
This won't be possible with out static front end site.
261+
262+
## Use DNS for services
263+
264+
DNS will be easier since we are building static assets outside of the context of Kubernetes and the environment variables that it injects at runtime.
265+
266+
```
267+
/ # curl http://kubernetes-django-service:8000/api/
268+
{"message": "Root"}
269+
```
270+
271+
This works from inside of a pod, but we can't use this for our static site since `localhost` won't know how to resolve `kubernetes-django-service`. One solution for this is to get the `port:ip` of the backend service from minikube, and then use this value for the `baseUrl` in our frontend application:
272+
273+
**minikube/Dockerfile**
274+
275+
```Dockerfile
276+
# build stage
277+
FROM node:10-alpine as build-stage
278+
WORKDIR /app/
279+
ENV DOMAIN_NAME 192.168.99.101:30958 <-- this is the nodePort for the backend service
280+
ENV HTTP_PROTOCOL http
281+
COPY quasar/package.json /app/
282+
RUN npm cache verify
283+
RUN npm install -g @quasar/cli
284+
RUN npm install --progress=false
285+
COPY quasar /app/
286+
RUN quasar build -m pwa
287+
288+
# minikube stage
289+
FROM nginx:1.13.12-alpine as minikube
290+
COPY nginx/minikube/minikube.conf /etc/nginx/nginx.conf
291+
COPY --from=build-stage /app/dist/pwa /dist/
292+
EXPOSE 80
293+
CMD ["nginx", "-g", "daemon off;"]
294+
```
295+
296+
We need to set the `DOMAIN_NAME` environment variable to `kubernetes-django-service`, and also set the port, and we should be able to access the backend from frontend AJAX calls.
297+
298+
## Troubleshooting and Misc
299+
300+
https://stackoverflow.com/questions/55573426/virtualbox-is-configured-with-multiple-host-only-adapters-with-the-same-ip-whe
301+

0 commit comments

Comments
 (0)