Sample Cloud Foundry to Cloud Run migration: Spring Music Stay organized with collections Save and categorize content based on your preferences.
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 a
REGISTRY_URIfor 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:
- Cloud Build Editor role
- Artifact Registry Admin role
- Storage Admin role
- Cloud Run Admin role
- Service Account User role
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-musicCreate 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.
Create a directory called
build/andcdinto it:mkdirbuild &&cdbuildIn the
build/folder, create a new file calledDockerfileand 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=cflinuxfs3Use Cloud Build to build and publish the
builderimagegcloudbuilds\submit--tag"REGISTRY_URI/builder:stable"Replace
REGISTRY_URIwith 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.
Create a directory called
run/andcdinto it:mkdirrun &&cdrunIn the
run/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""$@"""fiIn the
run/folder, create a new file calledDockerfileand 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={}Use Cloud Build to build and publish the
runtimeimage:gcloudbuildssubmit\--tag"REGISTRY_URI/runtime:stable"Replace
REGISTRY_URIwith 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:
Clone theSpring Music repository:
gitclonehttps://github.com/cloudfoundry-samples/spring-music.gitFor 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:
gitcheckout610ba471a643a20dee7a62d88a7879f13a21d6a3Move into the repository:
cdspring-musicBuild 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.
Create a staging directory
cr-appand asrcsub-directory inside of it:mkdir-pcr-app/srcMimic
cf pushby extracting the contents of the compiled JAR into thesrcdirectory:unzipbuild/libs/spring-music-1.0.jar-dcr-app/srcChange directory into
cr-app/:cdcr-app/Create a new file called
Dockerfile. ThisDockerfilewill use thebuild image and runtime image created in the previous steps to create the runnable application image forSpring Music, using the Java buildpack.Paste the following code into the
Dockerfile: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:
Create a file called
cloudbuild.yaml. This is abuild configuration that will instruct Cloud Build how to build the application.Paste the following configuration into
cloudbuild.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- Replace
REGISTRY_URIwith the URI of thecontainer registry where you have published the builder and runner.
- Replace
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:
Create a service account for your application:
gcloudiamservice-accountscreatespring-musicCreate a
service.yamlfile 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- Replace
PROJECT_NUMBERwith your project number. - Replace
SPRING_IMAGE_URIwith the URI of theapplication image created underbuild Spring Music as an OCI compliant image.
- Replace
Deploy the service to Cloud Run:
gcloudrunservicesreplaceservice.yamlOnce the deployment completes, you will be able to visit the running SpringMusic application at the deployed URL.
What's Next
- For a more in-depth look at the containerization process seeMigrate to OCI containers.
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.