Skip to content
This repository was archived by the owner on Oct 1, 2025. It is now read-only.

Commit a384f28

Browse files
committed
replaced the 2.x Step 4 w/Step 2a, effectively merging 2a w/4; switched from CMD to ENTRYPOINT in Dockerfiles; updated .dockerignore files
Change-Id: Idd091b016183cc0c18dc47d4973d87b909204093
1 parent a148cad commit a384f28

File tree

26 files changed

+169
-261
lines changed

26 files changed

+169
-261
lines changed

step2a-flask-cloudndb-cloudrun-py2/README.md

Lines changed: 0 additions & 50 deletions
This file was deleted.
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
*.md
22
*.pyc
33
*.pyo
4-
*.pyd
5-
.git
4+
.git/
5+
.gitignore
66
__pycache__
File renamed without changes.

step2a-flask-cloudndb-cloudrun-py2/Dockerfile renamed to step4-cloudds-cloudrun-py3/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ FROM python:3-slim
22
WORKDIR /app
33
COPY . .
44
RUN pip install -r requirements.txt
5-
CMD ["python", "main.py"]
5+
ENTRYPOINT ["python", "main.py"]
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# Step 4 - Migrate from Python 3 App Engine with Cloud Datastore to Cloud Run (with Docker)
2+
3+
## Introduction
4+
5+
The next (but still optional) step of migrating from App Engine to an explicit container for [Cloud Run](https://cloud.google.com/run) offers several benefits:
6+
7+
- The ability to roll in functionality in any language, any library, any binary
8+
- Opens the door to more product improvements only available to Cloud Run users
9+
- Helps move even further away from vendor lock-in, dependency on Google Cloud
10+
- Gives users the ability to more easily migrate their apps to VMs or Kubernetes, or move out of the cloud and run on-premise.
11+
12+
This migration is slightly different from its Python 2 twin (the "other" Step 4) in that we're using Cloud Datastore for this 3.x version but Cloud NDB for the 2.x version. If you're ready for containerization, this tutorial show you how to migrate Python 3 App Engine apps using Cloud Datastore to Cloud Run.
13+
14+
The steps include replacing the configuration files and specifying how your app should start. Since you won't have App Engine's web server, you'll need to specify your own server or bundle one into your container. For testing and staging, it's easy to just run Flask's development server from Python, but developers can opt for something more powerful for production such as the [Cloud Run Quickstart sample](https://cloud.google.com/run/docs/quickstarts/build-and-deploy) which uses `gunicorn`.
15+
16+
---
17+
18+
## Background
19+
20+
App Engine existed before the concept of containers. Since Docker's launch, containers have become the de facto standard in packaging applications & dependencies into a single transportable & deployable unit. Users can imagine that App Engine apps were custom containers created by Google engineers, and the migration in this step help users move further away from vendor lock-in and continues the messaging of Google Cloud being an open platform to its customers and offering them more flexibility than ever before.
21+
22+
There are two options for users when migrating to a container, and it hinges upon what generation runtime your app is on as well as your [Docker](http://docker.com/) experience. Those on a newer runtime can use [Cloud Buildpacks](https://github.com/GoogleCloudPlatform/buildpacks) to containerize apps so they can be deployed to Cloud Run or other Google Cloud container platforms ([GCE](https://cloud.google.com/compute), [GKE](https://cloud.google.com/kubernetes-engine), [Anthos](http://cloud.google.com/anthos), etc.).
23+
24+
See Step 4a (see `step4a-flask-datastore-py3-cloudrun`) if interested in using Buildpacks over Docker. However, if you're on a first generation runtime or prefer to use Docker, you're in the right place.
25+
26+
---
27+
28+
## Migration
29+
30+
Learning how to use Cloud Run is not within the scope of this tutorial, so refer to the Quickstart above or the general [Cloud Run docs](https://cloud.google.com/run/docs). Containerizing your app for Cloud Run means no longer using App Engine. This means all App Engine configuration files will be replaced by Docker config files. You'll also have to tweak your code a bit to tell the container to launch the web server and start your app — these things were originally handled by App Engine automatically.
31+
32+
1. Delete `app.yaml` and `appengine_config.py` config files as they're not used with Cloud Run.
33+
1. Delete the `lib` folder for the same reason.
34+
1. Add a `Dockerfile` with the container specifications and optionally a `.dockerignore` file as well.
35+
1. The `requirements.txt` and `templates/index.html` are fine to leave as-is.
36+
1. Modify `main.py` to start up the Flask app.
37+
38+
### Configuration
39+
40+
The only configuration file needed is the [`Dockerfile`](https://docs.docker.com/develop/develop-images/dockerfile_best-practices) that outlines how to build & run the container. This simple app only needs a minimal `Dockerfile`; here's one that works:
41+
42+
```Dockerfile
43+
FROM python:3-slim
44+
WORKDIR /app
45+
COPY . .
46+
RUN pip install -r requirements.txt
47+
ENTRYPOINT ["python", "main.py"]
48+
```
49+
50+
App Engine automatically starts your application, but Cloud Run doesn't. This is what the `Dockerfile` `ENTRYPOINT` directive is for. An alternative is to put a similar directive in a [`Procfile`](https://devcenter.heroku.com/articles/procfile). Our `ENTRYPOINT` launches `python` to execute `main.py` to start the Flask development server. You may also use a production web server like `gunicorn` if desired, and if so, be sure to add it to `requirements.txt`. Learn more about `Dockerfile` as well as `.dockerignore` from [this Cloud Run docs page](https://cloud.google.com/run/docs/quickstarts/build-and-deploy#containerizing) as well as see an example `Dockerfile` that spawns `gunicorn`.
51+
52+
Optionally add a `.dockerignore`, or if you already have one, it should remain as-is. A `.dockerignore` file can trim the size of your container and not bundle irrelevant files. The one we used:
53+
54+
```ignore
55+
*.md
56+
*.pyc
57+
*.pyo
58+
.git/
59+
.gitignore
60+
__pycache__
61+
```
62+
63+
Add a pair of lines at the bottom of `main.py` to start the application. Cloud Run automatically "injects" 8080 as the `PORT` environment variable, so you don't need to set it in `Dockerfile`:
64+
65+
Cloud Run starts its web server on port 8080, automatically injected into the `PORT` environment variable. Add an `import os` at the top of `main.py` as well as a "main" at the bottom to start the server (if executed directly which our `Dockerfile` does):
66+
67+
```python
68+
if __name__ == '__main__':
69+
app.run(debug=True, threaded=True, host='0.0.0.0',
70+
port=int(os.environ.get('PORT', 8080)))
71+
```
72+
73+
Doublecheck there are no files/folders named, `app.yaml`, `appengine_config.py`, nor `lib`, and that `requirements.txt` and `templates/index.html` are the same as before unless you added a production web server like `gunicorn` to your `requirements.txt'.
74+
75+
---
76+
77+
## Next
78+
79+
Congratulations... your app is fully modernized now, concluding this tutorial. From here, there is only one more things you can investigate:
80+
81+
1. If you're seeking an alternative to containerizing your app *without* Docker, consider the alternative Step 4a which is identical to the sample app in *this* tutorial except it uses [Cloud Buildpacks](https://github.com/GoogleCloudPlatform/buildpacks) instead of Docker.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
*.md
22
*.pyc
33
*.pyo
4-
*.pyd
5-
.git
4+
.git/
5+
.gitignore
66
__pycache__

0 commit comments

Comments
 (0)