I am on the learning curve for gcloud app deploy. I have been struggling with running the .net HelloWorld example code from this location:
https://github.com/GoogleCloudPlatform/dotnet-docs-samples/tree/master/appengine/flexible/HelloWorld
The example runs fine on a desktop when I start it with Visual Studio. But, I can't get past the step of running using "gcloud app deploy" from a cmd window. Below are details of two runs, first as an out-of-the-box, and second as after adding a doocker file.
Is anyone else able to run the HelloWorld example as is with the current version of gcloud sdk?
Thanks for your help,
Bob
Here is the gcloud version info:
gcloud --version
Google Cloud SDK 299.0.0
bq 2.0.58
core 2020.06.26
gsutil 4.51
RUN 1
Here is the tail end of the gcloud output after a fresh install of gcloud sdk, and a fresh clone of /dotnet-docs-samples/...
...
Step #0: Status: Downloaded newer image for gcr.io/gcp-runtimes/aspnetcorebuild@sha256:f5552a5efdaf278a3124ea10fd1c9636b09fc9f98f9e620cbd71279797576b3f
Step #0: gcr.io/gcp-runtimes/aspnetcorebuild@sha256:f5552a5efdaf278a3124ea10fd1c9636b09fc9f98f9e620cbd71279797576b3f
Step #0: No .deps.json file found for the app
Finished Step #0
ERROR
ERROR: build step 0 "gcr.io/gcp-runtimes/aspnetcorebuild@sha256:f5552a5efdaf278a3124ea10fd1c9636b09fc9f98f9e620cbd71279797576b3f" failed: step exited with non-zero status: 1
------------------------------------------------------------------------------------------------------------------------
ERROR: (gcloud.app.deploy) Cloud build failed. Check logs at https://console.cloud.google.com/cloud-build/builds/44677e0d-0fcb-4460-907b-835cbf621f5e?project=704308180369 Failure status: UNKNOWN: Error Response: [2] Build failed; check build logs for details
RUN 2
After some searching around, I found a suggestion to switch to using a custom runtime, and a docker file. So I made two changes, one in the app.yaml file, and adding the docker file.
Here is the app.yaml file.
runtime: custom
env: flex
# This sample incurs costs to run on the App Engine flexible environment.
# The settings below are to reduce costs during testing and are not appropriate
# for production use. For more information, see:
# https://cloud.google.com/appengine/docs/flexible/python/configuring-your-app-with-app-yaml
manual_scaling:
instances: 1
resources:
cpu: 1
memory_gb: 4
disk_size_gb: 10
env_variables:
# The __ in My__Greeting will be translated to a : by ASP.NET.
My__Greeting: Hello AppEngine!
readiness_check:
app_start_timeout_sec: 600
Here is the Dockerfile. The file came from this location:
https://github.com/dotnet/dotnet-docker/blob/50e95cd9af6458ce0db21e6ec952e29c3ee1fadf/2.1/aspnet/alpine3.10/amd64/Dockerfile
ARG REPO=mcr.microsoft.com/dotnet/core/runtime-deps
FROM $REPO:2.1-alpine3.10
# Install ASP.NET Core
ENV ASPNETCORE_VERSION 2.1.15
RUN wget -O aspnetcore.tar.gz https://dotnetcli.azureedge.net/dotnet/aspnetcore/Runtime/$ASPNETCORE_VERSION/aspnetcore-runtime-$ASPNETCORE_VERSION-linux-musl-x64.tar.gz \
&& aspnetcore_sha512='4a6ab78abc08c3e02c948de0af5fd324269785adad1b4e17bb849025ab280b7b8216cb48da5d480270cf3d596b342cedd4dc77eeaae82151fea44816e3856c69' \
&& echo "$aspnetcore_sha512 aspnetcore.tar.gz" | sha512sum -c - \
&& mkdir -p /usr/share/dotnet \
&& tar -zxf aspnetcore.tar.gz -C /usr/share/dotnet \
&& rm aspnetcore.tar.gz \
&& ln -s /usr/share/dotnet/dotnet /usr/bin/dotnet
Here is the tail end of the run using the docker file.
...
},
"handlers": [
{
"script": {
"scriptPath": "PLACEHOLDER"
},
"urlRegex": ".*"
}
],
"manualScaling": {
"instances": 1
},
"resources": {
"cpu": 1.0,
"diskGb": 10,
"memoryGb": 0.5
},
"runtime": "vm"
}"
DEBUG: Operation [apps/solitairesupport/operations/a41d48d9-6fc8-422b-84b6-1e18b3a70162] not complete. Waiting to retry.
Updating service [default] (this may take several minutes).../DEBUG: Operation [apps/solitairesupport/operations/a41d48d9-6fc8-422b-84b6-1e18b3a70162] not complete. Waiting to retry.
Updating service [default] (this may take several minutes)...-DEBUG: Operation [apps/solitairesupport/operations/a41d48d9-6fc8-422b-84b6-1e18b3a70162] not complete. Waiting to retry.
[MANY LINES REMOVED HERE]
Updating service [default] (this may take several minutes)...-DEBUG: Operation [apps/solitairesupport/operations/a41d48d9-6fc8-422b-84b6-1e18b3a70162] not complete. Waiting to retry.
Updating service [default] (this may take several minutes).../DEBUG: Operation [apps/solitairesupport/operations/a41d48d9-6fc8-422b-84b6-1e18b3a70162] complete. Result: {
"done": true,
"error": {
"code": 9,
"message": "\nApplication startup error! Code: APP_CONTAINER_CRASHED\n"
},
"metadata": {
"@type": "type.googleapis.com/google.appengine.v1.OperationMetadataV1",
"insertTime": "2020-07-03T17:06:36.191Z",
"method": "google.appengine.v1.Versions.CreateVersion",
"target": "apps/solitairesupport/services/default/versions/20200703t100554",
"user": "xxxx@gmail.com"
},
"name": "apps/solitairesupport/operations/a41d48d9-6fc8-422b-84b6-1e18b3a70162"
}
Updating service [default] (this may take several minutes)...failed.
DEBUG: (gcloud.app.deploy) Error Response: [9]
Application startup error! Code: APP_CONTAINER_CRASHED
Traceback (most recent call last):
File "...AppData\Local\Google\Cloud SDK\google-cloud-sdk\lib\googlecloudsdk\calliope\cli.py", line 983, in Execute
resources = calliope_command.Run(cli=self, args=args)
File "...\Local\Google\Cloud SDK\google-cloud-sdk\lib\googlecloudsdk\calliope\backend.py", line 807, in Run
resources = command_instance.Run(args)
File "...\Local\Google\Cloud SDK\google-cloud-sdk\lib\surface\app\deploy.py", line 117, in Run
default_strategy=flex_image_build_option_default))
File "...\Local\Google\Cloud SDK\google-cloud-sdk\lib\googlecloudsdk\command_lib\app\deploy_util.py", line 651, in RunDeploy
ignore_file=args.ignore_file)
File "...\Local\Google\Cloud SDK\google-cloud-sdk\lib\googlecloudsdk\command_lib\app\deploy_util.py", line 437, in Deploy
extra_config_settings)
File "...\Local\Google\Cloud SDK\google-cloud-sdk\lib\googlecloudsdk\api_lib\app\appengine_api_client.py", line 208, in DeployService
poller=done_poller)
File "...\Local\Google\Cloud SDK\google-cloud-sdk\lib\googlecloudsdk\api_lib\app\operations_util.py", line 314, in WaitForOperation
sleep_ms=retry_interval)
File "...\Local\Google\Cloud SDK\google-cloud-sdk\lib\googlecloudsdk\api_lib\util\waiter.py", line 264, in WaitFor
sleep_ms, _StatusUpdate)
File "...\Local\Google\Cloud SDK\google-cloud-sdk\lib\googlecloudsdk\api_lib\util\waiter.py", line 326, in PollUntilDone
sleep_ms=sleep_ms)
File "...\Local\Google\Cloud SDK\google-cloud-sdk\lib\googlecloudsdk\core\util\retry.py", line 229, in RetryOnResult
if not should_retry(result, state):
File "...\Local\Google\Cloud SDK\google-cloud-sdk\lib\googlecloudsdk\api_lib\util\waiter.py", line 320, in _IsNotDone
return not poller.IsDone(operation)
File "...\Local\Google\Cloud SDK\google-cloud-sdk\lib\googlecloudsdk\api_lib\app\operations_util.py", line 183, in IsDone
encoding.MessageToPyValue(operation.error)))
googlecloudsdk.api_lib.app.operations_util.OperationError: Error Response: [9]
Application startup error! Code: APP_CONTAINER_CRASHED
ERROR: (gcloud.app.deploy) Error Response: [9]
Application startup error! Code: APP_CONTAINER_CRASHED
Ok, I'm familiar with Google Cloud Platform but not (now) as familiar with .NET.
I'm using Linux (!) and Cloud Shell:
gcloud alpha cloud-shell ssh
I cloned the repo and made no other changes to it.
I am able to run the project locally and test it:
dotnet run
and, from another shell:
curl localhost:8080
Hello World!
NOTE it's unstated (perhaps obvious) but you must
dotnet run
(betterdotnet publish
) to create the./bin/Debug
directory.
I created a project, set up billing, created an app engine app:
PROJECT="[[YOUR-PROJECT-ID]]"
BILLING="[[YOUR-BILLING-ID]]"
REGION="[[YOUR-REGION]]"
gcloud projects create ${PROJECT}
gcloud beta billing projects link ${PROJECT} --billing-account=${BILLING}
gcloud app create --project=${PROJECT} --region=${REGION}
Then, per documentation:
dotnet publish
The contents of ./bin/Debug/netcoreapp2.1/publish
:
56 Jul 6 16:23 appsettings.json
544 Jul 6 16:23 app.yaml
223992 Jul 6 16:27 HelloWorld.deps.json
8192 Jul 6 16:27 HelloWorld.dll
1708 Jul 6 16:27 HelloWorld.pdb
213 Jul 6 16:27 HelloWorld.runtimeconfig.json
516 Jul 6 16:30 web.config
NOTE contains
app.yaml
andHelloWorld.deps.json
Then:
gcloud app deploy ./bin/Debug/netcoreapp2.1/publish/app.yaml \
--project=${PROJECT}
And:
ENDPOINT=$(\
gcloud app describe \
--project=${PROJECT} \
--format="value(defaultHostname)")
curl ${ENDPOINT}
Hello AppEngine!
Then, in the ./appengine/flexible/HelloWorld
directory, I created Dockerfile
:
FROM mcr.microsoft.com/dotnet/core/sdk:2.1 AS builder
WORKDIR /source
COPY *.sln .
COPY *.csproj .
RUN dotnet restore
COPY . .
RUN dotnet publish -c release -o /app --no-restore
FROM mcr.microsoft.com/dotnet/core/aspnet:2.1
WORKDIR /app
COPY --from=builder /app ./
ENTRYPOINT ["dotnet", "HelloWorld.dll"]
NOTE using this as a guide.
NOTE I downgraded to
2.1
(rather than3.1
) to avoid a dotnet build error but that's due to my unfamiliarity with the runtime(s).
I changed Program.cs
to force the use of :8080
:
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.UseUrls("http://0.0.0.0:8080")
.Build();
}
I revised app.yaml
to use custom runtime:
runtime: custom
env: flex
Then:
gcloud app deploy --project=${PROJECT}
Works.