In Cloud Build, you can create steps, with each step using a base image. Images can be common ones to interact with gcloud
or docker
, but you can also create your own.
When building custom images in Docker, you might have your ENTRYPOINT
as the name of an executable, then you can send various runtime parameters to it. How the docker
Cloud Builder image is defined in the Dockerfile
However, when you’re using Google Cloud buildpacks, you specify an optional Procfile
with your application, when you need to configure an application entrypoint different to the default.
Problems arise if you’re trying to define a custom entrypoint, then additionally customise the runtime parameters. The Cloud Native Buildpacks Specification v3 doesn’t (at the time of writing) specify how a Procfile should be processed, so the implementation is up to the provider.
You can use pack inspect
to see how an image’s processes have been parsed into a command and arguments. For instance a Procfile of web: python main.py
used in a cloud buildpack may result in the following:
Processes:
TYPE SHELL COMMAND ARGS
web (default) bash python3 main.py
Specifically, the entrypoint was parsed as a complex command, and not a single command with zero or more args.
The complexity of exec and shell form ENTRYPOINTs in Docker aside, there is a simpler way to solve the issue.
The way I found to reduce the complexity is to introduce an execution detail where you allow the python file to be executable, or package it, in that such a way that at the operating system level, it’s a single command to start the process.
Take the following example, where the image is build in build.cloudbuild.yaml
and built in cloudbuild.yaml
: GitHub Gist
The image is built specifically using the --workspace
flag of not the default workspace. /workspace
is used by both Buildpacks and Cloud Build, and in my investigations I found conflict here. The default volume /workspace
is used by Cloud Build to pass information between steps, but also as a source of the files within your current working directly when running Cloud Build configurations. If your image also uses this as the default workspace, when using Cloud Build, the image contains none of your custom files.
Additionally of note, I’m using main.py
here. Recent changes to Cloud buildpacks means that Python buildpacks now use gunicorn main:app
as a default. This functionality is similar to how App Engine works.
Other languages that have single executables may not have these issues to begin with.
I’m also sure there’s cleaner patterns. but this one has worked for me.