GoogleCloudPlatform / cloud-code-intellij

Plugin to support the Google Cloud Platform in IntelliJ IDEA - Docs and Issues Repository
Apache License 2.0
318 stars 59 forks source link

Continuous development (Watch mode via Skaffold) failing on Run Locally with Dockerfile build #3158

Closed rohanmoore closed 10 months ago

rohanmoore commented 10 months ago

(Please ensure you are running the latest version of Cloud Cloud IntelliJ with Help > Check for Updates.)

(screenshots are often helpful)

Expected Behavior

Changes to backend Java application code are expected to be propagated to the running container without requiring the Run Locally run configuration to be restarted. Propagation to running container is expected either automatically upon save, or upon clicking 'Trigger Build and Deploy', depending upon Watch Mode selected.

Actual Behavior

Despite console output during local build presenting no errors, and committing output consistent with Skaffold (Listing files to watch... - olivehelper, Press Ctrl+C to exit, Not watching for changes...), 'Trigger Build and Deploy' fails with no console output, and, when Watch Mode set to automatic, propagation also fails without console output.

Additional Information

Application build via Dockerfile below: FROM amazoncorretto:17.0.7 WORKDIR /usr/src/app COPY target/olivehelper-1.0.0.jar ./app.jar ENTRYPOINT ["java", "-jar", "./app.jar"]

Application runs locally via Minikube; production environment is Cloud Run.

Fails with no skaffold.yaml file, and also fails with following skaffold.yaml file:

apiVersion: skaffold/v4beta6 # This is an example version, adjust as needed. kind: Config metadata: name: olivehelper build: artifacts:

Run Locally run configuration build option dropdown does not offer Buildpacks, only Dockerfile, in case relevant.

ivanporty commented 10 months ago

Thank you for the report @rohanmoore. We'll investigate and get back to you.

ivanporty commented 10 months ago

@rohanmoore one clarification - you are talking about Cloud Run Run Locally, not Kubernetes?

ivanporty commented 10 months ago

Fails with no skaffold.yaml file, and also fails with following skaffold.yaml file:

And no skaffold.yaml file means CR Local configuration provided by Cloud Code?

rohanmoore commented 10 months ago

Exactly that: Cloud Run / Run Locally, not Kubernetes. My understanding is that Skaffold — in the context of Cloud Run / Run Locally — will work out-the-box with no yaml file, and the console output when building and running the application with no yaml file present is consistent with this assumption: the (Spring Boot) application is built and Dockerised successfully, and log entries appear in the console that look like they're from Skaffold (either 'Watching files', or 'Not watching files', consistent with Watch selection in Run Config).

I experimented with creating a skaffold.yaml file to see if that would kick watching into action, but no joy. Creating the skaffold.yaml file prompts the option to enable Kubernetes run configurations, which I'm rejecting. Cloud Run / Run Locally is, however, deploying my containerised application to Minikube in my local environment.

ivanporty commented 10 months ago

We see no issues so far with Cloud Code Cloud Run samples locally, so we assume there is something specific about your containers configuration that prevent subsequent deployments.

'Trigger Build and Deploy' fails with no console output, and, when Watch Mode set to automatic, propagation also fails without console output.

What exactly do you mean when you say fails with no console output, how failure manifests itself? And are the changes - are those purely code changes or any configuration (i.e. Dockerfile) changes?

rohanmoore commented 10 months ago

I've really quite a vanilla container configuration, and the following Dockerfile:

# Use Amazon Corretto 17 as base image
#FROM amazoncorretto:17-alpine-jdk
FROM amazoncorretto:17.0.7

# Specify home directory
WORKDIR /usr/src/app

# Copy jar file from local target directory to the docker image
COPY target/olivehelper-1.0.0.jar ./app.jar

# The command to run the application
ENTRYPOINT ["java", "-jar", "./app.jar"]

No error appears in the console when building and running the containerised application locally. However, if I change the code of any Java class within the backend of my application, the 'Trigger Build and Deploy' does not trigger a hot build/deploy. If I configure the Local Run Config Watch Mode to 'On File Save', then similarly a file save of an editing Java module does not result in a hot rebuild/deploy. Bringing code changes live in my application necessitates a complete stop and restart. Are there logs that might give any insight into why this function of Skaffold is failing? I'm reluctant to attempt a full manual implementation of Skaffold to enable continuous development, as I'm unclear how this might conflict with Cloud Code's failing blackbox efforts to implement the same functionality.

ivanporty commented 10 months ago

Most likely this is related to the way you structured your Dockerfile and sources - skaffold tries to find sources to watch based on it (see also https://skaffold.dev/docs/workflows/dev/#file-watcher-and-watch-modes).

As an example, please take a look at our simple CR sample - https://github.com/GoogleCloudPlatform/cloud-code-samples/blob/v1/java/java-cloud-run-hello-world/Dockerfile - as you can see, this Dockerfile doesn't copy over the jar file (which most likely won't be changed unless you rebuild it locally and thus skaffold won't be able to detect changes based on it) - but instead whole sources are built as part of the container image.

rohanmoore commented 10 months ago

Understood, and guidance is correct: re-working the Dockerfile as follows to enable multi-stage builds resolves the issue:

FROM maven:3.9-amazoncorretto-17 AS build-env WORKDIR /app COPY pom.xml ./ RUN mvn dependency:go-offline COPY src ./src RUN mvn package -DskipTests -Den.NODE_ENV=development FROM amazoncorretto:17.0.7 WORKDIR /usr/src/app COPY --from=build-env /app/target/olivehelper-1.0.0.jar ./app.jar ENTRYPOINT ["java", "-jar", "./app.jar"]

ivanporty commented 10 months ago

Glad it's working as intended!