Skip to content

Commit 9e15e9e

Browse files
ryanmatsJon Wayne Parrott
authored and
Jon Wayne Parrott
committed
Updated Django Container Engine sample to use CloudSQL v2, sidecar co… (GoogleCloudPlatform#758)
* Updated Django Container Engine sample to use CloudSQL v2, sidecar container pod pattern, Django 1.10, and Deployment rather than ReplicationController * Added secrets for database user/password
1 parent ef86b6f commit 9e15e9e

File tree

3 files changed

+58
-192
lines changed

3 files changed

+58
-192
lines changed

container_engine/django_tutorial/README.md

Lines changed: 2 additions & 179 deletions
Original file line numberDiff line numberDiff line change
@@ -5,187 +5,10 @@ app on Google Container Engine. It uses the [Writing your first Django app](http
55
.9/intro/tutorial01/) Polls application as the example app to deploy. From here on out, we refer to this app as
66
the 'polls' application.
77

8-
## Pre-requisites
98

10-
1. Create a project in the [Google Cloud Platform Console](https://console.cloud.google.com).
9+
# Tutorial
10+
See our [Django on Container Engine](https://cloud.google.com/python/django/container-engine) tutorial for instructions for setting up and deploying this sample application.
1111

12-
2. [Enable billing](https://console.cloud.google.com/project/_/settings) for your project.
13-
14-
3. [Enable APIs](https://console.cloud.google.com/flows/enableapi?apiid=datastore,pubsub,storage_api,logging,plus) for your project. The provided link will enable all necessary APIs, but if you wish to do so manually you will need Datastore, Pub/Sub, Storage, and Logging.
15-
16-
4. Install the [Google Cloud SDK](https://cloud.google.com/sdk)
17-
18-
$ curl https://sdk.cloud.google.com | bash
19-
$ gcloud init
20-
21-
5. Install [Docker](https://www.docker.com/).
22-
23-
## Makefile
24-
25-
Several commands listed below are provided in simpler form via the Makefile. Many of them use the GCLOUD_PROJECT
26-
environment variable, which will be picked up from your gcloud config. Make sure you set this to the correct project,
27-
28-
gcloud config set project <your-project-id>
29-
30-
### Create a cluster
31-
32-
Create a cluster for the bookshelf application:
33-
34-
gcloud container clusters create bookshelf \
35-
--scope "https://www.googleapis.com/auth/userinfo.email","cloud-platform" \
36-
--num-nodes 2
37-
gcloud container clusters get-credentials bookshelf
38-
39-
The scopes specified in the `--scope` argument allows nodes in the cluster to access Google Cloud Platform APIs, such as the Cloud Datastore API.
40-
41-
### Create a Cloud Storage bucket
42-
43-
The bookshelf application uses [Google Cloud Storage](https://cloud.google.com/storage) to store image files. Create a bucket for your project:
44-
45-
gsutil mb gs://<your-project-id>
46-
gsutil defacl set public-read gs://<your-project-id>
47-
48-
49-
## Setup the database
50-
51-
This tutorial assumes you are setting up Django using a SQL database, which is the easiest way to run Django. If you have an existing SQL database running, you can use that, but if not, these are the instructions for creating a managed MySQL instance using CloudSQL.
52-
53-
54-
* Create a [CloudSQL instance](https://console.cloud.google.com/project/_/sql/create)
55-
56-
* In the instances list, click your Cloud SQL instance.
57-
58-
* Click Access Control.
59-
60-
* In the IP address subsection, click Request an IPv4 address to enable access to the Cloud SQL instance through an
61-
IPv4 address. It will take a moment to initialize the new IP address.
62-
63-
* Also under Access Control, in the Authorization subsection, under Allowed Networks, click the add (+) button .
64-
65-
* In the Networks field, enter 0.0.0.0/0. This value allows access by all IP addresses.
66-
67-
* Click Save.
68-
69-
Note: setting allowed networks to 0.0.0.0/0 opens your SQL instance to traffic from any computer. For production databases, it's highly recommended to limit the authorized networks to only IP ranges that need access.
70-
71-
* Alternatively, the instance can be created with the gcloud command line tool as follows, substituting `your-root-pw
72-
with a strong, unique password.
73-
74-
`gcloud sql instances create <instance_name> --assign-ip --authorized-networks=0.0.0.0/0 set-root-password=your-root-pw`
75-
76-
* Create a Database And User
77-
78-
* Using the root password created in the last step to create a new database, user, and password using your preferred MySQL client. Alternatively, follow these instructions to create the database and user from the console.
79-
* From the CloudSQL instance in the console, click New user.
80-
* Enter a username and password for the application. For example, name the user "pythonapp" and give it a randomly
81-
generated password.
82-
* Click Add.
83-
* Click Databases and then click New database.
84-
* For Name, enter the name of your database (for example, "polls"), and click Add.
85-
86-
Once you have a SQL host, configuring mysite/settings.py to point to your database. Change `your-database-name`,
87-
`your-database-user`, `your-database-host` , and `your-database-password` to match the settings created above. Note the
88-
instance name is not used in this configuration, and the host name is the IP address you created.
89-
90-
91-
## Running locally
92-
93-
First make sure you have Django installed. It's recommended you do so in a
94-
[virtualenv](https://virtualenv.pypa.io/en/latest/). The requirements.txt
95-
contains just the Django dependency.
96-
97-
pip install -r requirements.txt
98-
99-
Once the database is setup, run the migrations.
100-
101-
python manage.py migrate
102-
103-
If you'd like to use the admin console, create a superuser.
104-
105-
python manage.py createsuperuser
106-
107-
The app can be run locally the same way as any other Django app.
108-
109-
python manage.py runserver
110-
111-
Now you can view the admin panel of your local site at
112-
113-
http://localhost:8080/admin
114-
115-
# Deploying To Google Container Engine (Kubernetes)
116-
117-
## Build the polls container
118-
119-
Before the application can be deployed to Container Engine, you will need build and push the image to [Google Container Registry](https://cloud.google.com/container-registry/).
120-
121-
docker build -t gcr.io/your-project-id/polls .
122-
gcloud docker push gcr.io/your-project-id/polls
123-
124-
Alternatively, this can be done using
125-
126-
make push
127-
128-
129-
## Deploy to the application
130-
131-
### Serve the static content
132-
133-
Collect all the static assets into the static/ folder.
134-
135-
python manage.py collectstatic
136-
137-
When DEBUG is enabled, Django can serve the files directly from that folder. For production purposes, you should
138-
serve static assets from a CDN. Here are instructions for how to do this using Google Cloud Storage.
139-
140-
Upload it to CloudStorage using the `gsutil rsync` command
141-
142-
gsutil rsync -R static/ gs://<your-gcs-bucket>/static
143-
144-
Now your static content can be served from the following URL:
145-
146-
http://storage.googleapis.com/<your-gcs-bucket/static/
147-
148-
Change the `STATIC_URL` in mysite/settings.py to reflect this new URL by uncommenting
149-
the appropriate line and replacing `<your-cloud-bucket>`
150-
151-
### Create the Kubernetes resources
152-
153-
This application is represented in a single Kubernetes config, called `polls`. First, replace the
154-
GCLOUD_PROJECT in `polls.yaml` with your project ID. Alternatively, run `make template` with your
155-
GCLOUD_PROJECT environment variable set.
156-
157-
kubectl create -f polls.yaml
158-
159-
Alternatively this create set can be done using the Makefile
160-
161-
make deploy
162-
163-
Once the resources are created, there should be 3 `polls` pods on the cluster. To see the pods and ensure that
164-
they are running:
165-
166-
kubectl get pods
167-
168-
If the pods are not ready or if you see restarts, you can get the logs for a particular pod to figure out the issue:
169-
170-
kubectl logs pod-id
171-
172-
Once the pods are ready, you can get the public IP address of the load balancer:
173-
174-
kubectl get services polls
175-
176-
You can then browse to the public IP address in your browser to see the bookshelf application.
177-
178-
When you are ready to update the replication controller with a new image you built, the following command will do a
179-
rolling update
180-
181-
kubectl rolling-update polls --image=gcr.io/${GCLOUD_PROJECT}/polls
182-
183-
which can also be done with the `make update` command.
184-
185-
186-
## Issues
187-
188-
Please use the Issue Tracker for any issues or questions.
18912

19013
## Contributing changes
19114

container_engine/django_tutorial/mysite/settings.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,10 @@
2626
# SECURITY WARNING: don't run with debug turned on in production!
2727
DEBUG = True
2828

29-
ALLOWED_HOSTS = []
29+
# SECURITY WARNING: If you deploy a Django app to production, make sure to set
30+
# an appropriate host here.
31+
# See https://docs.djangoproject.com/en/1.10/ref/settings/
32+
ALLOWED_HOSTS = ['*']
3033

3134
# Application definition
3235

@@ -78,10 +81,10 @@
7881
DATABASES = {
7982
'default': {
8083
'ENGINE': 'django.db.backends.mysql',
81-
'NAME': '<your-database-name>',
82-
'USER': '<your-database-user>',
83-
'PASSWORD': '<your-database-password>',
84-
'HOST': '<your-cloudsql-host>',
84+
'NAME': 'polls',
85+
'USER': os.getenv('DATABASE_USER'),
86+
'PASSWORD': os.getenv('DATABASE_PASSWORD'),
87+
'HOST': '127.0.0.1',
8588
'PORT': '3306',
8689
}
8790
}
@@ -105,7 +108,7 @@
105108

106109
# [START staticurl]
107110
STATIC_URL = '/static/'
108-
# STATIC_URL = 'https://storage.googleapis.com/<your-bucket-id>/static/'
111+
# STATIC_URL = 'https://storage.googleapis.com/<your-gcs-bucket>/static/'
109112
# [END staticurl]
110113

111114
STATIC_ROOT = 'static/'

container_engine/django_tutorial/polls.yaml

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@
1919
# instances of the bookshelf app are running on the cluster.
2020
# For more info about Pods see:
2121
# https://cloud.google.com/container-engine/docs/pods/
22-
# For more info about Replication Controllers:
23-
# https://cloud.google.com/container-engine/docs/replicationcontrollers/
22+
# For more info about Deployments:
23+
# https://kubernetes.io/docs/user-guide/deployments/
2424

25-
# [START replication_controller]
26-
apiVersion: v1
27-
kind: ReplicationController
25+
# [START kubernetes_deployment]
26+
apiVersion: extensions/v1beta1
27+
kind: Deployment
2828
metadata:
2929
name: polls
3030
labels:
@@ -39,14 +39,54 @@ spec:
3939
containers:
4040
- name: polls-app
4141
# Replace with your project ID or use `make template`
42-
image: gcr.io/$GCLOUD_PROJECT/polls
42+
image: gcr.io/<your-project-id>/polls
4343
# This setting makes nodes pull the docker image every time before
4444
# starting the pod. This is useful when debugging, but should be turned
4545
# off in production.
4646
imagePullPolicy: Always
47+
env:
48+
# [START cloudsql_secrets]
49+
- name: DATABASE_USER
50+
valueFrom:
51+
secretKeyRef:
52+
name: cloudsql
53+
key: username
54+
- name: DATABASE_PASSWORD
55+
valueFrom:
56+
secretKeyRef:
57+
name: cloudsql
58+
key: password
59+
# [END cloudsql_secrets]
4760
ports:
4861
- containerPort: 8080
49-
# [END replication_controller]
62+
63+
# [START proxy_container]
64+
- image: b.gcr.io/cloudsql-docker/gce-proxy:1.05
65+
name: cloudsql-proxy
66+
command: ["/cloud_sql_proxy", "--dir=/cloudsql",
67+
"-instances=<your-cloudsql-connection-string>=tcp:3306",
68+
"-credential_file=/secrets/cloudsql/credentials.json"]
69+
volumeMounts:
70+
- name: cloudsql-oauth-credentials
71+
mountPath: /secrets/cloudsql
72+
readOnly: true
73+
- name: ssl-certs
74+
mountPath: /etc/ssl/certs
75+
- name: cloudsql
76+
mountPath: /cloudsql
77+
# [END proxy_container]
78+
# [START volumes]
79+
volumes:
80+
- name: cloudsql-oauth-credentials
81+
secret:
82+
secretName: cloudsql-oauth-credentials
83+
- name: ssl-certs
84+
hostPath:
85+
path: /etc/ssl/certs
86+
- name: cloudsql
87+
emptyDir:
88+
# [END volumes]
89+
# [END kubernetes_deployment]
5090

5191
---
5292

0 commit comments

Comments
 (0)