[MUSIC PLAYING]
WESLEY CHUN: Hi, developers.
Welcome to "Serverless Migration Station,"
where we show you one way you can
modernize your code on one of our serverless compute
platforms.
I'm Wesley Chun, joined by my friend, Martin,
and our little friend, Porter, to take you
on an alternate journey from App Engine into Cloud Run.
MARTIN OMANDER: Good to be here again, Wes.
You showed us how to containerize our app
for Cloud Run last time.
Why are we doing it again today?
WESLEY CHUN: Well, I'm glad you asked, Martin.
In the module 4 video, we did show developers
how to use Docker to containerize our App Engine
apps for Cloud Run.
Check it out if you missed it.
Containerizing your App Engine app for Cloud Run
is still on to do list today, but this time, we'll
do it without needing to know about Docker, or Docker files,
or how containers are put together.
MARTIN OMANDER: OK, that sounds great.
But how are we going to containerize
an app without Docker?
WESLEY CHUN: Yeah.
Well, we're going to use Google Cloud Buildpacks to do the job.
Instead of having to describe all the steps for building
the container, Buildpacks lets you off the hook
because it does the heavy lifting.
It looks at your code, what language it's in,
its third-party dependencies, and so on,
then builds the most efficient container image it can.
Check out these links and this video from one
of our colleagues to learn more about Cloud Buildpacks.
MARTIN OMANDER: That's good info.
But I'm curious, where did these Buildpacks come from?
WESLEY CHUN: Yeah, well, they originated from Heroku
back in 2011.
And since then, Buildpacks took off
for different languages, different cloud vendors.
But in 2018, the Cloud Native Computing Foundation unified
Buildpacks under a common standard.
Google Cloud Buildpacks are 100% compatible
with the Cloud Native Buildpacks and adheres to its open spec.
Check out the links to the Cloud Native Buildpacks and its spec.
Cloud Buildpacks containerizes apps
to be deployed on Google Cloud, whether Cloud Run,
GKE, which is our managed Kubernetes service,
or Compute Engine VMs.
MARTIN OMANDER: OK, sounds good.
I can't wait to try it.
So I did look ahead and I found out
there's one module 5 finish folder, which is Python 3.
What happened to Python 2, Wes?
WESLEY CHUN: Well, unfortunately, Buildpacks
don't support Python 2.
So if you do have a Python 2 app, you got to use Docker.
But so our starting point will be the Python 3 version
of the Maldo 2 Cloud NDB app.
We didn't containerize that one with Docker last time,
so let's pause right now so all of you
can go grab the code from the module 2b folder,
or use your own from the module 2 migration.
Got it?
You can also follow along in the codelab
and get hands-on experience containerizing it
with Cloud Buildpacks.
Let's start by confirming the module 2 code works.
Whether using your app or ours, redeploy with gcloud app deploy
and verify you get the same output
as from previous modules.
If you've done any of these migration modules,
you know that this app typically doesn't change at all.
That's the purpose, right?
Migrating without breaking anything?
Just like in module 4, we're switching products
from App Engine to Cloud Run, so make
a full copy of your module2 app folder,
because like with Docker, you're going to delete app.yaml,
as it's not used in Cloud Run.
Next, let's tackle requirements.txt.
Quick review.
App Engine and Cloud Functions are source-based
and start your app with a production-ready server.
Since Cloud Run is a little bit more DIY,
you have to roll your own.
Python App Engine uses gunicorn if you don't specify your own,
so we're going to use that with Cloud Run
by adding it to requirements.txt,
so it's identical to the one in module2b folder
except with gunicorn at the top, since I
like to put mine in lowest to highest level order.
Yes, version numbers are a good practice.
I left them out here because they change all the time.
However, they will be updated in the repo.
Like with Docker, the app itself doesn't change.
We're just containerizing it, right?
The last thing needed is to launch gunicorn
to start our app.
With Docker, there's either a command or entry point
directive at the end of the Docker file
to kick off gunicorn.
With Cloud Buildpacks, there is no app.yaml nor Dockerfile.
Instead, we use a Heroku-style Procfile.
It's basically a config file describing your app's processes
and how to start them.
For our app, there's only one process, the web server.
It's basically the entry point directive from app.yaml
or the Dockerfile.
So create yours with this one line specifying gunicorn
as our web process.
And boom, that is it.
We're also going to drop some links down below so you
can learn more about Procfiles.
And that, we say, is a wrap.
Run the same gcloud run deploy SVC_NAME --
.
Command as you did with Docker, or the longer version,
with the platform type, region, and so on,
if you're lazy like me.
And in about a minute or less, your app
will be available globally on Cloud Run.
It should work the same as before, whether on App Engine
or Cloud Run with Docker.
Now you've containerized your App Engine app again,
but this time, without a Dockerfile.
Congratulations.
MARTIN OMANDER: Wow.
I didn't know creating and deploying
a container would be that easy.
Buildpacks are amazing.
Since I don't have to worry about Dockerfiles anymore,
I'm thinking about how to increase my app's presence.
While my users here in the US don't have any issues,
my friends in Sweden are saying it's sometimes laggy.
Can I deploy my container to other regions?
WESLEY CHUN: Oh, for sure, Martin.
In these past few videos, we used the magic one-line
build and deploy command to get you started with the least
friction.
That's gcloud run deploy with --source
to specify the code to deploy.
For more sophisticated usage, let's talk about breaking it up
into two separate commands that'll
make it more flexible to do the other things,
like what you asked.
MARTIN OMANDER: Sounds good, Wes.
I'm willing to give up some convenience so I can more
easily deploy my app elsewhere.
But you said that one-line command builds and deploys
my container.
Can I guess that the two separate commands
are one for the build and the other for the deploy?
WESLEY CHUN: Precisely.
With the one-line command, we got your app
from code all the way to Cloud Run
without discussing container images or other resources,
like Cloud Build, Container Registry, or its successor,
Artifact Registry.
But since the cat's out of the bag,
here's the gcloud build submit --tag command.
You provide the full image path, which
is made up of the registry namespace,
like gcr.io or package.dev, respectively, your project
ID, image name, and possibly the region.
When you build your image, it has
to be registered before you can deploy to Cloud Run.
Registries help manage images, provide access control,
lets you check for vulnerabilities,
and is where you plug into CI/CD integrations.
Check out the links to the gcloud
build submit command, as well as both registries, to learn more.
MARTIN OMANDER: OK, so that's the build and register step.
Now how do I deploy the same container image
to multiple regions?
WESLEY CHUN: Hold on.
We're getting there, Martin.
Now that the image is in the registry,
it's straightforward to deploy.
But instead of gcloud run deploy --source,
it's gcloud run deploy --image, where
you provide the image pathname.
Using this command, you can deploy the same image
to other regions without having to build identical containers.
Another benefit to having your image in the registry
is that you can launch services directly
from the Cloud Console whenever you want from wherever you are.
In other words, you don't have to be on a command line
at your terminal.
You can be in Sweden to launch that service there.
MARTIN OMANDER: OK, I feel good about containerizing my App
Engine app for Cloud Run.
What are some other App Engine migrations to consider?
WESLEY CHUN: Yeah, well, where you usually go usually
depends on the services you're using.
Apps using Cloud NDB may consider
migrating to Cloud Datastore if you have
other code using that library.
If so, take a look at module 3.
But if all you have are apps using Cloud NDB,
just stay where you are.
If you're excited about the Firebase features in Cloud
Firestore, you can consider that migration in modules 6 and 10.
If your app uses App Engine task queues,
consider migrating to Cloud Tasks.
You can learn more about those in modules 7, 8, and 9.
Finally, if your app only has one basic function
or if you're interested in breaking up a larger App Engine
app into a set of microservices, check out module 11
to learn about migrating to Cloud Functions.
MARTIN OMANDER: Whoa.
That's a lot of options.
Thanks for pointing us to possible next stops, as well as
these last two videos showing users
how to containerize their App Engine apps for Cloud Run.
WESLEY CHUN: Yeah, and thank all of you
for staying with us on these short journeys
in modernizing your serverless apps.
This is Wesley Chun from Google Cloud on behalf
of Martin and Porter, and we look forward
to seeing you at the next "Migration Station"
or on another "Serverless Expedition" soon.
[MUSIC PLAYING]