GoogleCloudPlatform / app-maven-plugin

The library has moved to https://github.com/GoogleCloudPlatform/appengine-plugins/tree/main/app-maven-plugin
Apache License 2.0
102 stars 42 forks source link

appengine:deploy inside Docker container #472

Closed deepfriedbrain closed 2 years ago

deepfriedbrain commented 2 years ago

I have a GAE Java 11 Standard runtime application. I'm using appengine-maven-plugin v2.4.3 in my project. When executing mvn -e clean package appengine:deploy on MacOS natively, it works as expected.

But when I'm running it inside a gloud-sdk-docker (v394.0.0-alpine) based container, it downloads the Google Cloud SDK and CLI every time I run mvn -e clean package appengine:deploy command. Please refer to the container logs below.

My container already has the cloud SDK. This is the Dockerfile for my container:

FROM google/cloud-sdk:394.0.0-alpine
RUN apk --no-cache add openjdk11
ENV JAVA_HOME /usr/lib/jvm/java-11-openjdk/jre
RUN apk --no-cache add maven
RUN gcloud components install cloud-datastore-emulator beta

The other goals like exec:java and package work fine and do not reinstall the SDK or CLI.

For the deploy goal, do I need to set some environment variables or mount a volume so that the plugin doesn't install the Cloud SDK and CLI over and over again each time I run it?

The logs below shows the installation of Cloud SDK and CLI:

my-app-1 | [INFO] --- appengine-maven-plugin:2.4.3:deploy (default-cli) @ PMProc --- my-app-1 | Jul 21, 2022 6:11:36 PM com.google.cloud.tools.managedcloudsdk.install.Downloader download my-app-1 | INFO: Downloading https://dl.google.com/dl/cloudsdk/channels/rapid/google-cloud-sdk.tar.gz to /root/.cache/google-cloud-tools-java/managed-cloud-sdk/downloads/google-cloud-sdk.tar.gz my-app-1 | Welcome to the Google Cloud CLI! my-app-1 | WARNING: You appear to be running this script as root. This may cause my-app-1 | the installation to be inaccessible to users other than the root user. my-app-1 | Beginning update. This process may take several minutes. my-app-1 | my-app-1 | my-app-1 | Your current Google Cloud CLI version is: 394.0.0 my-app-1 | Installing components from version: 394.0.0 my-app-1 | my-app-1 | ┌─────────────────────────────────────────────────────────────────────────────┐ my-app-1 | │ These components will be installed. │ my-app-1 | ├─────────────────────────────────────────────────────┬────────────┬──────────┤ my-app-1 | │ Name │ Version │ Size │ my-app-1 | ├─────────────────────────────────────────────────────┼────────────┼──────────┤ my-app-1 | │ BigQuery Command Line Tool │ 2.0.75 │ 1.6 MiB │ my-app-1 | │ BigQuery Command Line Tool (Platform Specific) │ 2.0.73 │ < 1 MiB │ my-app-1 | │ Cloud Storage Command Line Tool │ 5.11 │ 15.5 MiB │ my-app-1 | │ Cloud Storage Command Line Tool (Platform Specific) │ 5.6 │ < 1 MiB │ my-app-1 | │ Google Cloud CLI Core Libraries (Platform Specific) │ 2022.01.28 │ < 1 MiB │ my-app-1 | │ anthoscli │ 0.2.28 │ 47.7 MiB │ my-app-1 | │ gcloud cli dependencies │ 2021.04.16 │ < 1 MiB │ my-app-1 | └─────────────────────────────────────────────────────┴────────────┴──────────┘ my-app-1 | my-app-1 | For the latest full release notes, please visit: my-app-1 | https://cloud.google.com/sdk/release_notes my-app-1 | my-app-1 | ╔════════════════════════════════════════════════════════════╗ my-app-1 | ╠═ Creating update staging area ═╣ my-app-1 | ╚════════════════════════════════════════════════════════════╝ my-app-1 | ╔════════════════════════════════════════════════════════════╗ my-app-1 | ╠═ Installing: BigQuery Command Line Tool ═╣ my-app-1 | ╚════════════════════════════════════════════════════════════╝ my-app-1 | ╔════════════════════════════════════════════════════════════╗ my-app-1 | ╠═ Installing: BigQuery Command Line Tool (Platform Spec... ═╣ my-app-1 | ╚════════════════════════════════════════════════════════════╝ my-app-1 | ╔════════════════════════════════════════════════════════════╗ my-app-1 | ╠═ Installing: Cloud Storage Command Line Tool ═╣ my-app-1 | ╚════════════════════════════════════════════════════════════╝ my-app-1 | ╔════════════════════════════════════════════════════════════╗ my-app-1 | ╠═ Installing: Cloud Storage Command Line Tool (Platform... ═╣ my-app-1 | ╚════════════════════════════════════════════════════════════╝ my-app-1 | ╔════════════════════════════════════════════════════════════╗ my-app-1 | ╠═ Installing: Default set of gcloud commands ═╣ my-app-1 | ╚════════════════════════════════════════════════════════════╝ my-app-1 | ╔════════════════════════════════════════════════════════════╗ my-app-1 | ╠═ Installing: Google Cloud CLI Core Libraries (Platform... ═╣ my-app-1 | ╚════════════════════════════════════════════════════════════╝ my-app-1 | ╔════════════════════════════════════════════════════════════╗ my-app-1 | ╠═ Installing: anthoscli ═╣ my-app-1 | ╚════════════════════════════════════════════════════════════╝ my-app-1 | ╔════════════════════════════════════════════════════════════╗ my-app-1 | ╠═ Installing: anthoscli ═╣ my-app-1 | ╚════════════════════════════════════════════════════════════╝ my-app-1 | ╔════════════════════════════════════════════════════════════╗ my-app-1 | ╠═ Installing: gcloud cli dependencies ═╣ my-app-1 | ╚════════════════════════════════════════════════════════════╝ my-app-1 | ╔════════════════════════════════════════════════════════════╗ my-app-1 | ╠═ Creating backup and activating new installation ═╣ my-app-1 | ╚════════════════════════════════════════════════════════════╝ my-app-1 | my-app-1 | Performing post processing steps... my-app-1 | ....................................................................................................................done. my-app-1 | my-app-1 | Update done! my-app-1 | my-app-1 | WARNING: There are other instances of Google Cloud tools on your system PATH. my-app-1 | Please remove the following to avoid confusion or accidental invocation: my-app-1 | my-app-1 | /google-cloud-sdk/bin/docker-credential-gcloud my-app-1 | /google-cloud-sdk/bin/bq my-app-1 | /google-cloud-sdk/bin/java_dev_appserver.sh my-app-1 | /google-cloud-sdk/bin/endpointscfg.py my-app-1 | /google-cloud-sdk/bin/anthoscli my-app-1 | /google-cloud-sdk/bin/gcloud my-app-1 | /google-cloud-sdk/bin/gsutil my-app-1 | /google-cloud-sdk/bin/dev_appserver.py my-app-1 | /google-cloud-sdk/bin/git-credential-gcloud.sh my-app-1 | my-app-1 | my-app-1 | my-app-1 | This will install all the core command line tools necessary for working with my-app-1 | the Google Cloud Platform. my-app-1 | my-app-1 | ==> Source [/root/.cache/google-cloud-tools-java/managed-cloud-sdk/LATEST/google-cloud-sdk/completion.bash.inc] in your profile to enable shell command completion for gcloud. my-app-1 | ==> Source [/root/.cache/google-cloud-tools-java/managed-cloud-sdk/LATEST/google-cloud-sdk/path.bash.inc] in your profile to add the Google Cloud SDK command line tools to your $PATH. my-app-1 | my-app-1 | For more information on how to get started, please visit: my-app-1 | https://cloud.google.com/sdk/docs/quickstarts my-app-1 | my-app-1 | my-app-1 | [INFO] Staging the application to: /app/target/appengine-staging my-app-1 | [INFO] Detected App Engine app.yaml based application. my-app-1 | Jul 21, 2022 6:12:55 PM com.google.cloud.tools.appengine.operations.GcloudRunner run

chanseokoh commented 2 years ago

Try setting <cloudSdkHome>:

<plugins>
   <plugin>
     <groupId>com.google.cloud.tools</groupId>
     <artifactId>appengine-maven-plugin</artifactId>
     <version>2.4.3</version>
     <configuration>
       ...
       <cloudSdkHome>/usr/foo/path/to/cloudsdk</cloudSdkHome>
     </configuration>
  </plugin>
</plugins>

cloudSdkHome | Optional parameter to configure the location of the gcloud CLI. If this property is not specified, then the plugin automatically downloads the gcloud CLI.

deepfriedbrain commented 2 years ago

@chanseokoh Yes, that was it. It no longer reinstalls the cloud SDK or CLI. But can you help me understand why this parameter is not needed when I'm using the same pom.xml locally? There must be something else on the local machine that provides the location of the Cloud SDK to the plugin.

Thanks so much for your help!

Edit: On my local machine, I do see google-cloud-sdk/bin in the $PATH. So could that be the reason that I didn't encounter this issue on local? I'll test it out later and confirm.

chanseokoh commented 2 years ago

It's because locally it should have already installed a Cloud CLI at (by default on Linux) ~/.cache/google-cloud-tools-java/managed-cloud-sdk/LATEST/google-cloud-sdk. In the log you shared above, you can find the path too.

deepfriedbrain commented 2 years ago

I see this path in the logs:

/Users/<my-user-name>/Library/Application Support/google-cloud-tools-java/managed-cloud-sdk/LATEST/google-cloud-sdk/bin/gcloud

How does the plugin pick up this location? Where is this configured?

When I run, which gcloud, it shows a different path which is set in the PATH env var. I have multiple version of gcloud on my machine and need to do some cleanup.

This is one of the reasons I'm moving to containers and clean up the mess on my laptop.

chanseokoh commented 2 years ago

How does the plugin pick up this location? Where is this configured?

It's an application detail, and basically the user is not supposed to know it. The Cloud CLI installed by the App Engine plugin is a private one. It's exclusive and specific to the plugin on the machine and not to be shared by anyone. The directory is automatically managed by the plugin and may contain multiple versions of Cloud CLI (if you have ever configured <cloudSdkVersion>). As a cache like ~/.m2, you can freely delete the entire cache; the plugin will re-download it.

When I run, which gcloud, it shows a different path which is set in the PATH env var.

Most likely it's the one that you installed yourself in the past. It's your own CLI and unrelated to the CLI installations managed by the plugin. The only way to force the plugin to use a non-managed CLI is to configure <cloudSdkHome>.

deepfriedbrain commented 2 years ago

Thanks for the explanations.

Ideally I would like to maintain a single pom.xml that works inside and outside the container, at least until I have fully transitioned to using the containers. As things stand right now, I have to add <cloudSdkHome> for the containerized environment, and remember to remove it when using the local environment. Is it possible to use an environment variable to provide the SDK Home instead of using the <cloudSdkHome> config param inside the pom.xml? That way I can set the environment variable in the Dockerfile while creating the image.

Alternatively, can I configure the path where the plugin downloads the SDK so that I can point it to a folder inside my project home and use it for both local and containerized environments?

chanseokoh commented 2 years ago

How about <cloudSdkHome>${env.MY_CLOUD_CLI_HOME}<cloudSdkHome>? Or, you can leverage the Maven profiles. Or both. You can also think about creating a symlink to a Cloud CLI home to make the paths in different envs in sync.

Remember that if you specify your own Cloud CLI, the plugin doesn't auto-manage it, so it is your responsibility to maintain it up-to-date.

deepfriedbrain commented 2 years ago

One of those will meet my needs. Thank you so much for your help.