Skip to content

Commit 506c933

Browse files
glasntiennae
andauthored
fix(run/django): Update to Procfile, Artifact Registry, dedicated service account (#12718)
* Update to Procfile, Artifact Registry, dedicated service account * debug: do not create sa * remove excess permission * ensure unique cloudrunjob name * debug: ensure values use random suffix * lint * syntax * Turns out, this value is important. * ensure consistent substitutions * move to Cloud Run Job based superuser, update migrations * remove unused vars * Update sample code, region tags * fix region tag * lint [skip ci] * update cloudmigrate * update to support multiple cloud run URLs * confirm jobs complete * pass python version to pack * string * use CNB-distributed pack image * remove old build steps * replace other k8s-skaffold image reference --------- Co-authored-by: Jennifer Davis <[email protected]>
1 parent 8f39ccc commit 506c933

File tree

10 files changed

+213
-259
lines changed

10 files changed

+213
-259
lines changed

run/django/Dockerfile

Lines changed: 0 additions & 37 deletions
This file was deleted.

run/django/Procfile

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Default entrypoint: run Django
2+
web: gunicorn --bind 0.0.0.0:$PORT --workers 1 --threads 8 --timeout 0 mysite.wsgi:application
3+
4+
# [START cloudrun_django_procfile_migrate]
5+
# Apply database migrations
6+
migrate: python manage.py migrate && python manage.py collectstatic --verbosity 2 --no-input
7+
# [END cloudrun_django_procfile_migrate]
8+
9+
# [START cloudrun_django_procfile_superuser]
10+
# Create superuser (requires DJANGO_SUPERUSER_PASSWORD and DJANGO_SUPERUSER_EMAIL envvars)
11+
createsuperuser: python manage.py createsuperuser --username admin --noinput || echo "User already exists."
12+
# [END cloudrun_django_procfile_superuser]

run/django/cloudmigrate.yaml

Lines changed: 40 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -14,55 +14,58 @@
1414

1515
# [START cloudrun_django_cloudmigrate]
1616
steps:
17-
- id: "build image"
18-
name: "gcr.io/cloud-builders/docker"
19-
args: ["build", "-t", "gcr.io/${PROJECT_ID}/${_SERVICE_NAME}", "."]
17+
- id: "Build Container Image"
18+
name: buildpacksio/pack
19+
args: ["build", "${_IMAGE_NAME}", "--builder=gcr.io/buildpacks/builder"]
2020

21-
- id: "push image"
21+
- id: "Push Container Image"
2222
name: "gcr.io/cloud-builders/docker"
23-
args: ["push", "gcr.io/${PROJECT_ID}/${_SERVICE_NAME}"]
23+
args: ["push", "${_IMAGE_NAME}"]
2424

25-
- id: "apply migrations"
26-
name: "gcr.io/google-appengine/exec-wrapper"
25+
- id: "Migrate database"
26+
name: "gcr.io/google.com/cloudsdktool/cloud-sdk"
27+
entrypoint: /bin/bash
2728
args:
28-
[
29-
"-i",
30-
"gcr.io/$PROJECT_ID/${_SERVICE_NAME}",
31-
"-s",
32-
"${PROJECT_ID}:${_REGION}:${_INSTANCE_NAME}",
33-
"-e",
34-
"SETTINGS_NAME=${_SECRET_SETTINGS_NAME}",
35-
"--",
36-
"python",
37-
"manage.py",
38-
"migrate",
39-
]
29+
- "-c"
30+
- |
31+
gcloud run jobs create migrate-job \
32+
--region ${_REGION} \
33+
--image ${_IMAGE_NAME} \
34+
--set-cloudsql-instances ${_CLOUD_SQL_CONNECTION_NAME} \
35+
--set-env-vars SETTINGS_NAME=${_SECRET_SETTINGS_NAME} \
36+
--command migrate \
37+
--execute-now
4038
41-
- id: "collect static"
42-
name: "gcr.io/google-appengine/exec-wrapper"
39+
- id: "Create superuser"
40+
name: "gcr.io/google.com/cloudsdktool/cloud-sdk"
41+
entrypoint: /bin/bash
4342
args:
44-
[
45-
"-i",
46-
"gcr.io/$PROJECT_ID/${_SERVICE_NAME}",
47-
"-s",
48-
"${PROJECT_ID}:${_REGION}:${_INSTANCE_NAME}",
49-
"-e",
50-
"SETTINGS_NAME=${_SECRET_SETTINGS_NAME}",
51-
"--",
52-
"python",
53-
"manage.py",
54-
"collectstatic",
55-
"--verbosity",
56-
"2",
57-
"--no-input",
58-
]
43+
- "-c"
44+
- |
45+
gcloud run jobs create superuser-job \
46+
--region ${_REGION} \
47+
--image ${_IMAGE_NAME} \
48+
--set-cloudsql-instances ${_CLOUD_SQL_CONNECTION_NAME} \
49+
--set-env-vars SETTINGS_NAME=${_SECRET_SETTINGS_NAME} \
50+
--set-env-vars DJANGO_SUPERUSER_EMAIL=${_ADMIN_EMAIL} \
51+
--set-secrets DJANGO_SUPERUSER_PASSWORD=${_ADMIN_PASSWORD_NAME}:latest \
52+
--command createsuperuser \
53+
--execute-now
54+
55+
options:
56+
dynamicSubstitutions: true
5957

6058
substitutions:
6159
_INSTANCE_NAME: django-instance
60+
_CLOUD_SQL_CONNECTION_NAME: ${PROJECT_ID}:${_REGION}:${_INSTANCE_NAME}
6261
_REGION: us-central1
6362
_SERVICE_NAME: polls-service
6463
_SECRET_SETTINGS_NAME: django_settings
64+
_ARTIFACT_REGISTRY: cloud-run-source-deploy
65+
_IMAGE_NAME: ${_REGION}-docker.pkg.dev/${PROJECT_ID}/${_ARTIFACT_REGISTRY}/${_SERVICE_NAME}
66+
_ADMIN_EMAIL: [email protected]
67+
_ADMIN_PASSWORD_NAME: superuser_password
6568

6669
images:
67-
- "gcr.io/${PROJECT_ID}/${_SERVICE_NAME}"
70+
- "${_IMAGE_NAME}"
6871
# [END cloudrun_django_cloudmigrate]

run/django/e2e_test.py

Lines changed: 7 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
from collections.abc import Iterator
1919
import os
2020
import subprocess
21+
import sys
2122
import uuid
2223

2324
import backoff
@@ -27,10 +28,10 @@
2728
# Unique suffix to create distinct service names
2829
SUFFIX = uuid.uuid4().hex[:10]
2930

31+
PYTHON_VERSION = f"{sys.version_info.major}.{sys.version_info.minor}"
3032
SAMPLE_VERSION = os.environ.get("SAMPLE_VERSION", None)
3133
GOOGLE_CLOUD_PROJECT = os.environ["GOOGLE_CLOUD_PROJECT"]
3234
REGION = "us-central1"
33-
PLATFORM = "managed"
3435

3536
SERVICE = f"polls-{SUFFIX}"
3637

@@ -50,20 +51,11 @@
5051
POSTGRES_INSTANCE_FULL = f"{GOOGLE_CLOUD_PROJECT}:{REGION}:{POSTGRES_INSTANCE}"
5152
POSTGRES_INSTANCE_NAME = POSTGRES_INSTANCE
5253

53-
POSTGRES_DATABASE = f"django-database-{SUFFIX}"
54-
55-
CLOUD_STORAGE_BUCKET = f"{GOOGLE_CLOUD_PROJECT}-media-{SUFFIX}"
56-
57-
POSTGRES_DATABASE = f"polls-{SUFFIX}"
58-
POSTGRES_USER = f"django-{SUFFIX}"
5954
POSTGRES_PASSWORD = uuid.uuid4().hex[:26]
6055

6156
ADMIN_NAME = "admin"
6257
ADMIN_PASSWORD = uuid.uuid4().hex[:26]
6358

64-
SECRET_SETTINGS_NAME = f"django_settings-{SUFFIX}"
65-
SECRET_PASSWORD_NAME = f"superuser_password-{SUFFIX}"
66-
6759

6860
@backoff.on_exception(backoff.expo, Exception, max_tries=3)
6961
def run_shell_cmd(args: list) -> subprocess.CompletedProcess:
@@ -98,18 +90,14 @@ def run_shell_cmd(args: list) -> subprocess.CompletedProcess:
9890
@pytest.fixture
9991
def deployed_service() -> str:
10092
substitutions = [
93+
f"_VERSION={SUFFIX},"
94+
f"_PYTHON_VERSION={PYTHON_VERSION},"
10195
f"_SERVICE={SERVICE},"
102-
f"_PLATFORM={PLATFORM},"
10396
f"_REGION={REGION},"
104-
f"_STORAGE_BUCKET={CLOUD_STORAGE_BUCKET},"
105-
f"_DB_NAME={POSTGRES_DATABASE},"
106-
f"_DB_USER={POSTGRES_USER},"
10797
f"_DB_PASS={POSTGRES_PASSWORD},"
98+
f"_ADMIN_PASSWORD={ADMIN_PASSWORD},"
10899
f"_DB_INSTANCE={POSTGRES_INSTANCE_NAME},"
109-
f"_SECRET_SETTINGS_NAME={SECRET_SETTINGS_NAME},"
110-
f"_SECRET_PASSWORD_NAME={SECRET_PASSWORD_NAME},"
111-
f"_SECRET_PASSWORD_VALUE={ADMIN_PASSWORD},"
112-
f"_CLOUD_SQL_CONNECTION_NAME={POSTGRES_INSTANCE_FULL}"
100+
f"_CLOUD_SQL_CONNECTION_NAME={POSTGRES_INSTANCE_FULL},"
113101
]
114102
if SAMPLE_VERSION:
115103
substitutions.append(f",_VERSION={SAMPLE_VERSION}")
@@ -133,15 +121,10 @@ def deployed_service() -> str:
133121
# Cleanup
134122

135123
substitutions = [
124+
f"_VERSION={SUFFIX},"
136125
f"_SERVICE={SERVICE},"
137-
f"_PLATFORM={PLATFORM},"
138126
f"_REGION={REGION},"
139-
f"_DB_USER={POSTGRES_USER},"
140-
f"_DB_NAME={POSTGRES_DATABASE},"
141127
f"_DB_INSTANCE={POSTGRES_INSTANCE_NAME},"
142-
f"_SECRET_SETTINGS_NAME={SECRET_SETTINGS_NAME},"
143-
f"_SECRET_PASSWORD_NAME={SECRET_PASSWORD_NAME},"
144-
f"_STORAGE_BUCKET={CLOUD_STORAGE_BUCKET},"
145128
]
146129
if SAMPLE_VERSION:
147130
substitutions.append(f"_SAMPLE_VERSION={SAMPLE_VERSION}")
@@ -172,8 +155,6 @@ def service_url_auth_token(deployed_service: str) -> Iterator[tuple[str, str]]:
172155
"services",
173156
"describe",
174157
deployed_service,
175-
"--platform",
176-
"managed",
177158
"--region",
178159
REGION,
179160
"--format",

run/django/e2e_test_cleanup.yaml

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,32 +22,38 @@ steps:
2222
./retry.sh "gcloud secrets describe ${_SECRET_SETTINGS_NAME}" \
2323
"gcloud secrets delete ${_SECRET_SETTINGS_NAME} --quiet --project $PROJECT_ID"
2424
25-
./retry.sh "gcloud secrets describe ${_SECRET_PASSWORD_NAME}" \
26-
"gcloud secrets delete ${_SECRET_PASSWORD_NAME} --quiet --project $PROJECT_ID"
27-
2825
./retry.sh "gsutil ls gs://${_STORAGE_BUCKET}" \
2926
"gsutil -m rm -r gs://${_STORAGE_BUCKET}"
3027
31-
./retry.sh "gcloud container images describe gcr.io/${PROJECT_ID}/${_SERVICE}:${_VERSION}" \
32-
"gcloud container images delete gcr.io/${PROJECT_ID}/${_SERVICE}:${_VERSION} --quiet"
28+
./retry.sh "gcloud artifacts docker images describe ${_IMAGE_NAME}" \
29+
"gcloud artifacts docker images delete ${_IMAGE_NAME} --quiet"
30+
31+
./retry.sh "gcloud run jobs describe migrate-${_VERSION} --region ${_REGION}" \
32+
"gcloud run jobs delete migrate-${_VERSION} --region ${_REGION} --async --quiet"
3333
34-
./retry.sh "gcloud run services describe ${_SERVICE} --region ${_REGION} --platform ${_PLATFORM}" \
35-
"gcloud run services delete ${_SERVICE} --region ${_REGION} --platform ${_PLATFORM} --async --quiet"
34+
./retry.sh "gcloud run jobs describe superuser-${_VERSION} --region ${_REGION}" \
35+
"gcloud run jobs delete superuser-${_VERSION} --region ${_REGION} --async --quiet"
36+
37+
./retry.sh "gcloud run services describe ${_SERVICE} --region ${_REGION}" \
38+
"gcloud run services delete ${_SERVICE} --region ${_REGION} --async --quiet"
3639
3740
WAIT=30 ./retry.sh "gcloud sql databases describe ${_DB_NAME} --instance ${_DB_INSTANCE} --project $PROJECT_ID" \
3841
"gcloud sql databases delete ${_DB_NAME} --instance ${_DB_INSTANCE} --quiet --project $PROJECT_ID"
3942
4043
./retry.sh "gcloud sql users list --filter \"name=${_DB_USER}\" --instance ${_DB_INSTANCE}" \
4144
"gcloud sql users delete ${_DB_USER} --instance ${_DB_INSTANCE} --quiet --project $PROJECT_ID"
4245
46+
options:
47+
dynamicSubstitutions: true
48+
4349
substitutions:
4450
_SERVICE: django
4551
_VERSION: manual
4652
_REGION: us-central1
47-
_PLATFORM: managed
48-
_DB_USER: django
49-
_DB_NAME: django
53+
_ARTIFACT_REGISTRY: cloud-run-source-deploy
54+
_IMAGE_NAME: ${_REGION}-docker.pkg.dev/${PROJECT_ID}/${_ARTIFACT_REGISTRY}/django-${_VERSION}
55+
_STORAGE_BUCKET: ${PROJECT_ID}-bucket-${_VERSION}
56+
_DB_USER: django-${_VERSION}
57+
_DB_NAME: django-${_VERSION}
5058
_DB_INSTANCE: django-instance
51-
_SECRET_SETTINGS_NAME: django_settings
52-
_SECRET_PASSWORD_NAME: admin_password
53-
_STORAGE_BUCKET: ${PROJECT_ID}-bucket
59+
_SECRET_SETTINGS_NAME: django_settings-${_VERSION}

0 commit comments

Comments
 (0)