Sample Cloud Foundry to Cloud Run migration: Spring Music

This sample migration uses theSpring Music project to show how a Cloud Foundry application can be built as an OCI-compliant application image. This sample is using thelift and shift strategy, which usesopen source components from the Cloud Foundry ecosystem. After you create the application image, you need to configure the application for deployment to Cloud Run.

Before you start

  • Make sure you have set up a new project for Cloud Run as describedin thesetup page.
  • Make sure you have aREGISTRY_URI for storingcontainers. Cloud Run recommends using Artifact Registry.
  • If you are under a domain restriction organization policyrestricting unauthenticated invocations for your project, you will need to access your deployed service as described underTesting private services.

  • Install Docker on your workstation. Docker is used to create intermediate images to build theproject.

Permissions required to deploy

For this guide you need permissions to build, store the built container imageand deploy.

You must have the following roles:

Project Structure

For this guide we suggest that you create a project directory e.g.cr-spring-music/and create sub-directories as you progress through the guide.

cr-spring-music/├── build├── run└── spring-music

Create the build Image

This section creates a build image usingcflinux3 as the baseimage. The build image is used as the build environment for creating theapplication image.

  1. Create a directory calledbuild/ andcd into it:

    mkdirbuild &&cdbuild
  2. In thebuild/ folder, create a new file calledDockerfile and paste inthe following code:

    ARGCF_LINUX_FS=cloudfoundry/cflinuxfs3FROMgolang:1.20-bullseyeASbuilder_buildWORKDIR/buildRUN["git","clone","--depth=1","https://github.com/cloudfoundry/buildpackapplifecycle.git"]WORKDIR/build/buildpackapplifecycleRUN["go","mod","init","code.cloudfoundry.org/buildpackapplifecycle"]RUN["go","mod","tidy"]RUNCGO_ENABLD=0gobuild-o/builder./builder/FROM$CF_LINUX_FS# Set up container tools related to building applicationsWORKDIR/lifecycleCOPY--from=builder_build/builder/lifecycle/builder# Set up environment to match Cloud Foundry's build.# https://docs.cloudfoundry.org/devguide/deploy-apps/environment-variable.html#app-system-envWORKDIR/staging/appWORKDIR/tmpENVCF_INSTANCE_ADDR=127.0.0.1:8080\CF_INSTANCE_IP=127.0.0.1\CF_INSTANCE_INTERNAL_IP=127.0.0.1\VCAP_APP_HOST=127.0.0.1\CF_INSTANCE_PORT=8080\LANG=en_US.UTF-8\INSTANCE_GUID=00000000-0000-0000-0000-000000000000\VCAP_APPLICATION={}\VCAP_SERVICES={}\CF_STACK=cflinuxfs3
  3. Use Cloud Build to build and publish thebuilder image

    gcloudbuilds\submit--tag"REGISTRY_URI/builder:stable"

    ReplaceREGISTRY_URI with the address of the Artifact Registry where youwant to publish the build image. For example:REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/builder:stable.

Create the runtime Image

This section creates a run image usingcflinux3 as the baseimage. The run image is used as the base image when you create the finalapplication image.

  1. Create a directory calledrun/ andcd into it:

    mkdirrun &&cdrun
  2. In therun/ folder, create a new shell script calledentrypoint.bashwith the following code:

    #!/usr/bin/env bashset-eif[["$@"==""]];thenexec/lifecycle/launcher"/home/vcap/app"""""elseexec/lifecycle/launcher"/home/vcap/app""$@"""fi
  3. In therun/ folder, create a new file calledDockerfile and paste in thefollowing code:

    ARGCF_LINUX_FS=cloudfoundry/cflinuxfs3FROMgolang:1.20-bullseyeASlauncher_buildWORKDIR/buildRUN["git","clone","--depth=1","https://github.com/cloudfoundry/buildpackapplifecycle.git"]WORKDIR/build/buildpackapplifecycleRUN["go","mod","init","code.cloudfoundry.org/buildpackapplifecycle"]RUN["go","mod","tidy"]RUNCGO_ENABLD=0gobuild-o/launcher./launcher/FROM$CF_LINUX_FS# Set up container tools related to launching the applicationWORKDIR/lifecycleCOPYentrypoint.bash/lifecycle/entrypoint.bashRUN["chmod","+rx","/lifecycle/entrypoint.bash"]COPY--from=launcher_build/launcher/lifecycle/launcher# Set up environment to match Cloud FoundryWORKDIR/home/vcapUSERvcap:vcapENTRYPOINT["/lifecycle/entrypoint.bash"]# Expose 8080 to allow app to be run on Cloud Foundry,# and PORT so the container can be run locally.# These do nothing on Cloud Run.EXPOSE8080/tcp# Set up environment variables similar to Cloud Foundry.ENVCF_INSTANCE_ADDR=127.0.0.1:8080\CF_INSTANCE_IP=127.0.0.1\INSTANCE_IP=127.0.0.1\CF_INSTANCE_INTERNAL_IP=127.0.0.1\VCAP_APP_HOST=127.0.0.1\CF_INSTANCE_PORT=80\LANG=en_US.UTF-8\CF_INSTANCE_GUID=00000000-0000-0000-0000-000000000000\INSTANCE_GUID=00000000-0000-0000-0000-000000000000\CF_INSTANCE_INDEX=0\INSTANCE_INDEX=0\PORT=8080\VCAP_APP_PORT=8080\VCAP_APPLICATION={}\VCAP_SERVICES={}
  4. Use Cloud Build to build and publish theruntime image:

    gcloudbuildssubmit\--tag"REGISTRY_URI/runtime:stable"

    ReplaceREGISTRY_URI with the address to the Artifact Registry where you wantto publish the build image. For example:REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/runtime:stable.

Build Spring Music for Cloud Foundry

To clone theSpringMusic project and run the build commands as if we were deploying the project toCloud Foundry:

  1. Clone theSpring Music repository:

    gitclonehttps://github.com/cloudfoundry-samples/spring-music.git
  2. For the purposes of this guide, we will be using an older version of theSpring Music application that uses Java 8 and Spring Boot 2. To do this wewill move to an older revision of the Spring Music project:

    gitcheckout610ba471a643a20dee7a62d88a7879f13a21d6a3
  3. Move into the repository:

    cdspring-music
  4. Build the Spring Music binary:

    ./gradlewcleanassemble

You now have abuild/ folder with the compiled Spring Music app ready tobe pushed into a Cloud Foundry instance.

Convert Spring Music into a Cloud Run compatible application

You must take the output of the build command to prepare theSpring Music artifact for deployment into Cloud Run.

  1. Create a staging directorycr-app and asrc sub-directory inside of it:

    mkdir-pcr-app/src
  2. Mimiccf push by extracting the contents of the compiled JAR into thesrcdirectory:

    unzipbuild/libs/spring-music-1.0.jar-dcr-app/src
  3. Change directory intocr-app/:

    cdcr-app/
  4. Create a new file calledDockerfile. ThisDockerfile will use thebuild image and runtime image created in the previous steps to create the runnable application image forSpring Music, using the Java buildpack.

  5. Paste the following code into theDockerfile:

    ARGBUILD_IMAGEARGRUN_IMAGEFROM$BUILD_IMAGEasbuildCOPYsrc/staging/appCOPYsrc/tmp/appARGBUILDPACKSRUN/lifecycle/builder\-buildArtifactsCacheDir=/tmp/cache\-buildDir=/tmp/app\-buildpacksDir=/tmp/buildpacks\-outputBuildArtifactsCache=/tmp/output-cache\-outputDroplet=/tmp/droplet\-outputMetadata=/tmp/result.json\"-buildpackOrder=${BUILDPACKS}"\"-skipDetect=true"FROM$RUN_IMAGECOPY--from=build/tmp/dropletdropletRUNtar-xzfdroplet &&rmdroplet

Build Spring Music as an OCI compliant image

In this step, you instruct Cloud Build how to construct an OCI-compliant imageusing the build image, runtime image, and application Dockerfilecreated in the previous steps.

To create the OCI-compliant image:

  1. Create a file calledcloudbuild.yaml. This is abuild configuration that will instruct Cloud Build how to build the application.

  2. Paste the following configuration intocloudbuild.yaml:

    steps:-name:gcr.io/cloud-builders/dockerargs:-'build'-'--network'-'cloudbuild'-'--tag'-'${_TAG}'-'--build-arg'-'BUILD_IMAGE=${_BUILD_IMAGE}'-'--build-arg'-'RUN_IMAGE=${_RUN_IMAGE}'-'--build-arg'-'BUILDPACKS=${_BUILDPACKS}'-'.'images:-"${_TAG}"options:# Substitute build environment variables as an array of KEY=VALUE formatted strings here.env:[]substitutions:_BUILD_IMAGE:REGISTRY_URI/builder:stable_RUN_IMAGE:REGISTRY_URI/runtime:stable_BUILDPACKS:https://github.com/cloudfoundry/java-buildpack_TAG:REGISTRY_URI/spring-music:latest
    • ReplaceREGISTRY_URI with the URI of thecontainer registry where you have published the builder and runner.
  3. Build the application image using Cloud Build:

    gcloudbuildssubmit.

    When the build completes, make note of the resulting image URI. You willneed it when deploying the application in the next steps. The resultingimage will be an OCI-compliant container image for running the Spring Musicapp, built using open source Cloud Foundry components.

Deploy to Cloud Run

You must create a service definition file to use in Cloud Run:

  1. Create a service account for your application:

    gcloudiamservice-accountscreatespring-music
  2. Create aservice.yaml file with the following code:

    apiVersion:serving.knative.dev/v1kind:Servicemetadata:name:"spring-music"# Set this to be the project number of the project you're deploying to.namespace:"PROJECT_NUMBER"labels:cloud.googleapis.com/location:us-central1migrated-from:cloud-foundryannotations:run.googleapis.com/ingress:allspec:template:metadata:annotations:autoscaling.knative.dev/minScale:'1'autoscaling.knative.dev/maxScale:'1'run.googleapis.com/cpu-throttling:'true'run.googleapis.com/startup-cpu-boost:'true'run.googleapis.com/sessionAffinity:'false'spec:containerConcurrency:1000timeoutSeconds:900serviceAccountName:spring-music@PROJECT_NUMBER.iam.gserviceaccount.comcontainers:-name:user-container# Set the following value to either:# - The image you built for your application in the last section of the guide.image:SPRING_IMAGE_URIports:-name:http1containerPort:8080env:-name:VCAP_APPLICATIONvalue:|-{"application_id": "00000000-0000-0000-0000-000000000000","application_name": "spring-music","application_uris": [],"limits": {"disk": 0,"mem": 1024},"name": "spring-music","process_id": "00000000-0000-0000-0000-000000000000","process_type": "web","space_name": "none","uris": []}-name:MEMORY_LIMITvalue:'1024M'resources:limits:memory:1024Micpu:"1"startupProbe:httpGet:path:/port:8080timeoutSeconds:1failureThreshold:30successThreshold:1periodSeconds:2livenessProbe:httpGet:path:/port:8080timeoutSeconds:1failureThreshold:1successThreshold:1periodSeconds:30traffic:-percent:100latestRevision:true
  3. Deploy the service to Cloud Run:

    gcloudrunservicesreplaceservice.yaml

    Once the deployment completes, you will be able to visit the running SpringMusic application at the deployed URL.

What's Next

Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.

Last updated 2026-02-19 UTC.