Skip to content

Commit a5d8f31

Browse files
authored
Merge pull request #111404 from cephalin/python-tutorial
study in-sync edits
2 parents 5d6091b + 8f11ab0 commit a5d8f31

File tree

1 file changed

+31
-52
lines changed

1 file changed

+31
-52
lines changed

articles/app-service/containers/tutorial-python-postgresql-app.md

Lines changed: 31 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ ms.custom: [mvc, seodec18, seo-python-october2019, cli-validate]
88
---
99
# Tutorial: Deploy a Python (Django) web app with PostgreSQL in Azure App Service
1010

11-
This tutorial shows how to deploy a data-driven Python (Django) web app to [Azure App Service](app-service-linux-intro.md) and connect it to an Azure Database for PostgreSQL database. App Service provides a highly scalable, self-patching web hosting service.
11+
This tutorial shows how to deploy a data-driven Python (Django) web app to [Azure App Service](app-service-linux-intro.md) and connect it to an Azure Database for PostgreSQL database. App Service provides a highly scalable, self-patching web hosting service.
1212

1313
![Deploy Python Django web app to Azure App Service](./media/tutorial-python-postgresql-app/deploy-python-django-app-in-azure.png)
1414

@@ -23,7 +23,7 @@ In this tutorial, you learn how to:
2323
2424
You can follow the steps in this article on macOS, Linux, or Windows.
2525

26-
## Prerequisites
26+
## Install dependencies
2727

2828
Before you start this tutorial:
2929

@@ -34,33 +34,34 @@ Before you start this tutorial:
3434

3535
## Clone the sample app
3636

37-
In a terminal window, run the following commands to clone the sample app repository, and change to the new working directory:
37+
In a terminal window, run the following commands to clone the sample app repository, and change to the repository root:
3838

3939
```
4040
git clone https://github.com/Azure-Samples/djangoapp
4141
cd djangoapp
4242
```
4343

44-
The djangoapp sample repository contains the data-driven [Django](https://www.djangoproject.com/) polls app you get by following [Writing your first Django app](https://docs.djangoproject.com/en/2.1/intro/tutorial01/) in the Django documentation.
44+
The djangoapp sample repository contains the data-driven [Django](https://www.djangoproject.com/) polls app you get by following [Writing your first Django app](https://docs.djangoproject.com/en/2.1/intro/tutorial01/) in the Django documentation. It's provided here for your convenience.
4545

4646
## Prepare app for App Service
4747

4848
Like many Python web frameworks, Django [requires certain changes before they can be run in a production server](https://docs.djangoproject.com/en/2.1/howto/deployment/checklist/), and it's no different with App Service. You need to change and add some settings in the default *azuresite/settings.py* file so that the app works after it's deployed to App Service.
4949

50-
Take a look at *azuresite/production.py*, which makes the necessary configuration for App Service. It's added for convenience but not yet used by the app. Briefly, it does the following:
50+
Take a look at *azuresite/production.py*, which makes the necessary configuration for App Service. Briefly, it does the following:
5151

5252
- Inherit all settings from *azuresite/settings.py*.
5353
- Add the fully qualified domain name of the App Service app to the allowed hosts.
5454
- Use [WhiteNoise](https://whitenoise.evans.io/en/stable/) to enable serving static files in production, because Django by default doesn't serve static files in production. The WhiteNoise package is already included in *requirements.txt*.
5555
- Add configuration for PostgreSQL database. By default, Django uses Sqlite3 as the database, but it's not suitable for production apps. The [psycopg2-binary](https://pypi.org/project/psycopg2-binary/) package is already included in *requirements.txt*.
56+
- The Postgres configuration uses environment variables. Later, you'll find out how to set environment variables in App Service.
5657

57-
Make the following changes to your app so that it uses *azuresite/production.py* when in App Service.
58+
*azuresite/production.py* is included in the repository for convenience, but it's not yet used by the app. To make sure that its settings are used in App Service, you need to configure two files, *manage.py* and *azuresite/wsgi.py*, to access it.
5859

59-
1. In *manage.py*, change the following line:
60+
- In *manage.py*, change the following line:
6061

61-
```python
62+
<pre>
6263
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'azuresite.settings')
63-
```
64+
</pre>
6465

6566
To the following code:
6667

@@ -73,7 +74,7 @@ Make the following changes to your app so that it uses *azuresite/production.py*
7374

7475
You'll set the environment variable `DJANGO_ENV` later when you configure your App Service app.
7576

76-
1. In *azuresite/wsgi.py*, make the same change as above.
77+
- In *azuresite/wsgi.py*, make the same change as above.
7778

7879
In App Service, you use *manage.py* to run database migrations, and App Service uses *azuresite/wsgi.py* to run your Django app in production. This change in both files ensures that the production settings are used in both cases.
7980

@@ -87,27 +88,7 @@ To sign in to Azure, run the [`az login`](/cli/azure/reference-index#az-login) c
8788
az login
8889
```
8990

90-
Follow the instructions in the terminal to sign into your Azure account. When you're finished, your subscriptions are listed:
91-
92-
```
93-
[
94-
{
95-
"cloudName": "AzureCloud",
96-
"homeTenantId": "00000000-0000-0000-0000-000000000000",
97-
"id": "00000000-0000-0000-0000-000000000000",
98-
"isDefault": false,
99-
"managedByTenants": [],
100-
"name": "<subscription-name>",
101-
"state": "Enabled",
102-
"tenantId": "00000000-0000-0000-0000-000000000000",
103-
"user": {
104-
"name": "<azure-account-name>",
105-
"type": "user"
106-
}
107-
},
108-
...
109-
]
110-
```
91+
Follow the instructions in the terminal to sign into your Azure account. When you're finished, your subscriptions are shown in JSON format in the terminal output.
11192

11293
## Create Postgres database in Azure
11394

@@ -120,35 +101,29 @@ In this section, you create an Azure Database for PostgreSQL server and database
120101
az extension add --name db-up
121102
```
122103

123-
Create the Postgres database in Azure with the [`az postgres up`](/cli/azure/ext/db-up/postgres?view=azure-cli-latest#ext-db-up-az-postgres-up) command, as shown in the following example. Replace *\<postgresql-name>* with a *unique* name (the server endpoint is *https://\<postgresql-name>.postgres.database.azure.com*). For *\<admin-username>* and *\<admin-password>*, specify credentials for a database administrator account.
104+
Create the Postgres database in Azure with the [`az postgres up`](/cli/azure/ext/db-up/postgres#ext-db-up-az-postgres-up) command, as shown in the following example. Replace *\<postgresql-name>* with a *unique* name (the server endpoint is *https://\<postgresql-name>.postgres.database.azure.com*). For *\<admin-username>* and *\<admin-password>*, specify credentials to create an administrator user for this Postgres server.
124105

125106
<!-- Issue: without --location -->
126107
```azurecli
127-
az postgres up --resource-group myResourceGroup --location westus --server-name <postgresql-name> --database-name pollsdb --admin-user <admin-username> --admin-password <admin-password> --ssl-enforcement Enabled
108+
az postgres up --resource-group myResourceGroup --location westus2 --server-name <postgresql-name> --database-name pollsdb --admin-user <admin-username> --admin-password <admin-password> --ssl-enforcement Enabled
128109
```
129110

130111
This command may take a while because it's doing the following:
131112

132-
- Creates a resource group called `myResourceGroup`, if it doesn't exist. `--resource-group` is optional.
113+
- Creates a [resource group](../../azure-resource-manager/management/overview.md#terminology) called `myResourceGroup`, if it doesn't exist. Every Azure resource needs to be in one of these. `--resource-group` is optional.
133114
- Creates a Postgres server with the administrative user.
134115
- Creates a `pollsdb` database.
135116
- Allows access from your local IP address.
136117
- Allows access from Azure services.
137-
- Create a user with access to the `pollsdb` database.
118+
- Create a database user with access to the `pollsdb` database.
138119

139120
You can do all the steps separately with other `az postgres` commands and `psql`, but `az postgres up` does all of them in one step for you.
140121

141-
When the command finishes, find the script that created the database user, with the username `root` and password `Pollsdb1`, which you'll use later to connect to the database:
142-
143-
```
144-
Successfully Connected to PostgreSQL.
145-
Ran Database Query: `CREATE USER root WITH ENCRYPTED PASSWORD 'Pollsdb1'`
146-
Ran Database Query: `GRANT ALL PRIVILEGES ON DATABASE pollsdb TO root`
147-
```
122+
When the command finishes, find the output lines that being with `Ran Database Query:`. They show the database user that's created for you, with the username `root` and password `Pollsdb1`. You'll use them later to connect your app to the database.
148123

149124
<!-- not all locations support az postgres up -->
150125
> [!TIP]
151-
> To specify the location for your Postgres server, include the argument `--location <location-name>`, where `<location_name>` is one of the [Azure regions](https://azure.microsoft.com/global-infrastructure/regions/). You can get the regions available to your subscription with the [`az account list-locations`](/cli/azure/appservice?view=azure-cli-latest.md#az-appservice-list-locations) command.
126+
> To specify the location for your Postgres server, include the argument `--location <location-name>`, where `<location_name>` is one of the [Azure regions](https://azure.microsoft.com/global-infrastructure/regions/). You can get the regions available to your subscription with the [`az account list-locations`](/cli/azure/account#az-account-list-locations) command.
152127

153128
## Deploy the App Service app
154129

@@ -159,6 +134,10 @@ In this section, you create the App Service app. You will connect this app to th
159134
<!-- validation error: Parameter 'ResourceGroup.location' can not be None. -->
160135
<!-- --resource-group is not respected at all -->
161136

137+
Make sure you're back in the repository root (`djangoapp`), because the app will be deployed from this directory.
138+
139+
Create an App Service app with the [`az webapp up`](/cli/azure/webapp#az-webapp-up) command, as shown in the following example. Replace *\<app-name>* with a *unique* name (the server endpoint is *https://\<app-name>.azurewebsites.net*). Allowed characters for *\<app-name>* are `A`-`Z`, `0`-`9`, and `-`.
140+
162141
```azurecli
163142
az webapp up --plan myAppServicePlan --sku B1 --name <app-name>
164143
```
@@ -168,15 +147,15 @@ This command may take a while because it's doing the following:
168147

169148
<!-- - Create the resource group if it doesn't exist. `--resource-group` is optional. -->
170149
<!-- No it doesn't. az webapp up doesn't respect --resource-group -->
171-
- Generates a resource group automatically.
172-
- Creates the App Service plan *myAppServicePlan* in basic (B1) tier, if it doesn't exist. `--plan` and `--sku` are optional.
150+
- Generates a [resource group](../../azure-resource-manager/management/overview.md#terminology) automatically.
151+
- Creates the [App Service plan](../overview-hosting-plans.md) *myAppServicePlan* in the Basic pricing tier (B1), if it doesn't exist. `--plan` and `--sku` are optional.
173152
- Creates the App Service app if it doesn't exist.
174153
- Enables default logging for the app, if not already enabled.
175154
- Uploads the repository using ZIP deployment with build automation enabled.
176155

177156
Once the deployment finishes, you see a JSON output like the following:
178157

179-
```json
158+
<pre>
180159
{
181160
"URL": "http://<app-name>.azurewebsites.net",
182161
"appserviceplan": "myAppServicePlan",
@@ -189,7 +168,7 @@ Once the deployment finishes, you see a JSON output like the following:
189168
"sku": "BASIC",
190169
"src_path": "//var//lib//postgresql//djangoapp"
191170
}
192-
```
171+
</pre>
193172

194173
Copy the value of *\<app-resource-group>*. You need it to configure the app later.
195174

@@ -204,7 +183,7 @@ The sample code is now deployed, but the app doesn't connect to the Postgres dat
204183

205184
### Configure environment variables
206185

207-
When you run your app locally, you can set the environment variables in the terminal session. In Azure App Service, you do it with *app settings*, by using the [az webapp config appsettings set](/cli/azure/webapp/config/appsettings?view=azure-cli-latest#az-webapp-config-appsettings-set) command.
186+
When you run your app locally, you can set the environment variables in the terminal session. In App Service, you do it with *app settings*, by using the [az webapp config appsettings set](/cli/azure/webapp/config/appsettings#az-webapp-config-appsettings-set) command.
208187

209188
Run the following command to specify the database connection details as app settings. Replace *\<app-name>*, *\<app-resource-group>*, and *\<postgresql-name>* with your own values. Remember that the user credentials `root` and `Pollsdb1` were created for you by `az postgres up`.
210189

@@ -318,15 +297,15 @@ python manage.py runserver
318297

319298
When the Django web app is fully loaded, it returns something like the following message:
320299

321-
```
300+
<pre>
322301
Performing system checks...
323302

324303
System check identified no issues (0 silenced).
325304
December 13, 2019 - 10:54:59
326305
Django version 2.1.2, using settings 'azuresite.settings'
327306
Starting development server at http://127.0.0.1:8000/
328307
Quit the server with CONTROL-C.
329-
```
308+
</pre>
330309

331310
Go to *http:\//localhost:8000* in a browser. You should see the message **No polls are available**.
332311

@@ -342,9 +321,9 @@ To stop the Django server, type Ctrl+C.
342321

343322
Just to see how making app updates works, make a small change in `polls/models.py`. Find the line:
344323

345-
```python
324+
<pre>
346325
choice_text = models.CharField(max_length=200)
347-
```
326+
</pre>
348327

349328
And change it to:
350329

0 commit comments

Comments
 (0)