Getting Started Deploying Grails Apps
Page last updated: August 20, 2015
This guide is intended to walk you through deploying a Grails app to Cloud Foundry. If you experience a problem following the steps below, check the Troubleshooting Cloud Foundry topic or refer to the Troubleshooting Application Deployment and Health topic.
Sample App Step
If you want to go through this tutorial using the sample app, run git clone https://github.com/cloudfoundry-samples/pong_matcher_grails.git
to clone the pong_matcher_grails
app from GitHub, and follow the instructions in the Sample App Step sections.
Note: Ensure that your Grails app runs locally before continuing with this procedure.
Deploy a Grails Application
This section describes how to deploy a Grails application to Cloud Foundry.
Prerequisites
- A Grails app that runs locally on your workstation
- Intermediate to advanced Grails knowledge
- The cf Command Line Interface (CLI)
- JDK 1.7 or 1.8 for Java 7 or 8 configured on your workstation
Note: You can develop Grails applications in Groovy, Java 7 or 8, or any JVM language. The Cloud Foundry Java buildpack uses JDK 1.8, but you can modify the buildpack and the manifest for your app to compile to JDK 1.7. Refer to Step 8: Configure the Deployment Manifest.
Step 1: Declare App Dependencies
Declare all the dependency tasks for your app in the build script of your chosen build tool. The table lists build script information for Gradle, Grails, and Maven and provides documentation links for each build tool.
Build Tool | Build Script | Documentation |
---|---|---|
Gradle | build.gradle | Gradle User Guide |
Grails | BuildConfig.groovy | Grails: Configuration - Reference Documentation |
Maven | pom.xml | Apache Maven Project Documentation |
Sample App Step
You can skip this step. The pong_matcher_grails/app/grails-app/conf/BuildConfig.groovy
file contains the dependencies for the pong_matcher_grails
sample app, as the example below shows.
dependencies {
// specify dependencies here under either 'build', 'compile', 'runtime', 'test' or 'provided' scopes e.g.
// runtime 'mysql:mysql-connector-java:5.1.29'
// runtime 'org.postgresql:postgresql:9.3-1101-jdbc41'
test "org.grails:grails-datastore-test-support:1.0-grails-2.4"
runtime 'mysql:mysql-connector-java:5.1.33'
}
Step 2: Allocate Sufficient Memory
Use the cf push -m
command to specify the amount of memory that should be allocated to the application. Memory allocated this way is done in preset amounts of 64M
, 128M
, 256M
, 512M
, 1G
, or 2G
. For example:
$ cf push -m 128M
When your app is running, you can use the cf app APP_NAME
command to see memory utilization.
Sample App Step
You can skip this step. In the manifest.yml
of the pong_matcher_grails
sample app, the memory
sub-block of the applications
block allocates 1 GB to the app.
Step 3: Provide a JDBC Driver
The Java buildpack does not bundle a JDBC driver with your application. If your application accesses a SQL RDBMS, you must do the following:
- Include the appropriate driver in your application.
- Create a dependency task for the driver in the build script for your build tool or IDE.
Sample App Step
You can skip this step. The pong_matcher_grails
sample app declares a MySQL JDBC driver in the pong_matcher_grails/app/grails-app/conf/DataSource.groovy
file because the app uses ClearDB, which is a database-as-service for MySQL-powered apps. The example below shows this declaration.
dataSource {
pooled = true
jmxExport = true
driverClassName = "com.mysql.jdbc.Driver"
dialect = org.hibernate.dialect.MySQL5InnoDBDialect
uri = new URI(System.env.DATABASE_URL ?: "mysql://foo:bar@localhost")
username = uri.userInfo ? uri.userInfo.split(":")[0] : ""
password = uri.userInfo ? uri.userInfo.split(":")[1] : ""
url = "jdbc:mysql://" + uri.host + uri.path
properties {
dbProperties {
autoReconnect = true
}
}
}
Step 4: (Optional) Configure a Procfile
A Procfile enables you to declare required runtime processes, called process types, for your web app. Process managers in a server use the process types to run and manage the workload.
When you deploy, Cloud Foundry determines if a Procfile exists and uses the Procfile to configure your app with the specified settings.
In a Procfile, you declare one process type per line and use the following syntax, as shown in the example below:
PROCESS_TYPE
is the command name in the format of an alphanumeric string.COMMAND
is the command line to launch the process.
Example process type syntax:
PROCESS_TYPE: COMMAND
You create a Procfile and add a command line for a web
process type. Store the Procfile in the root directory of your app. The example shows a process type that starts the launch script created by the build process.
Example Procfile:
web: build/install/MY-PROJECT-NAME/bin/MY-PROJECT-NAME]
Sample App Step
You can skip this step. The pong_matcher_grails
app does not require a Procfile.
Step 5: Create and Bind a Service Instance for a Grails Application
This section describes using the CLI to configure a ClearDB managed service instance for an app.
Cloud Foundry supports two types of service instances:
- Managed services integrate with Cloud Foundry through service brokers that offer services and plans and manage the service calls between Cloud Foundry and a service provider.
- User-provided service instances enable you to connect your application to pre-provisioned external service instances.
For more information about creating and using service instances, refer to the Services Overview topic.
Create a Service Instance
Run cf marketplace
to view managed and user-provided services and plans available to you.
The example shows two of the available managed database-as-a-service providers and their offered plans: cleardb
database-as-a-service for MySQL-powered apps and elephantsql
PostgreSQL as a Service.
$ cf marketplace Getting services from marketplace in org Cloud-Apps / space development as [email protected]... OK service plans description ... cleardb spark, boost, amp Highly available MySQL for your apps ... elephantsql turtle, panda, elephant PostgreSQL as a Service ...
Run cf create-service SERVICE PLAN SERVICE_INSTANCE
to create a service instance for your app. Choose a SERVICE and PLAN from the list, and provide a unique name for the SERVICE_INSTANCE.
Sample App Step
Run cf create-service cleardb spark mysql
. This creates a service instance named mysql
that uses the cleardb
service and the mysql
plan, as the example below shows.
$ cf create-service cleardb spark mysql Creating service mysql in org Cloud-Apps / space development as [email protected].... OK
Bind a Service Instance
When you bind an app to a service instance, Cloud Foundry writes information about the service instance to the VCAP_SERVICES app environment variable. The app can use this information to integrate with the service instance.
Most services support bindable service instances. Refer to your service provider’s documentation to confirm if they support this functionality.
You can bind a service to an application with the command cf bind-service APPLICATION SERVICE_INSTANCE
.
Alternately, you can configure the deployment manifest file by adding a services
sub-block to the applications
block and specifying the service instance. For more information and an example on service binding using a manifest, see the Sample App step.
Sample App Step
You can skip this step because the service instance is already bound. Open the manifest.yml
file in a text editor to view the bound service instance information. Locate the file in the app root directory and search for the services
sub-block in the applications
block, as the example below shows.
--- applications: ... services: - mysql
Step 6: Configure the Deployment Manifest
You can specify deployment options in the manifest.yml
that the cf push
command uses when deploying your app.
Refer to the Deploying with Application Manifests topic for more information.
Sample App Step
You can skip this step. The manifest.yml
file for the pong_matcher_grails
sample app does not require any additional configuration to deploy the app.
Step 7: Log in and Target the API Endpoint
Run cf login -a API_ENDPOINT
, enter your login credentials, and select a space and org. The API endpoint is the URL of the Cloud Controller in your Cloud Foundry instance.
Sample App Step
You must do this step to run the sample app.
Step 8: Deploy the Application
Note: You must use the cf CLI to deploy apps.
From the root directory of your application, run cf push APP-NAME -p PATH-TO-FILE.war
to deploy your application.
Note: You must deploy the .war
artifact for a Grails app, and you must include the path to the .war
file in the cf push
command using the -p
option if you do not declare the path in the applications
block of the manifest file. For more information, refer to the Grails section in the Tips for Java Developers topic.
cf push APP-NAME
creates a URL route to your application in the form HOST.DOMAIN, where HOST is your APP-NAME and DOMAIN is specified by your administrator. Your DOMAIN isshared-domain.com
. For example: cf push my-app
creates the URL my-app.shared-domain.com
.
The URL for your app must be unique from other apps that Cloud Foundry hosts or the push will fail. Use the following options to help create a unique URL:
-n
to assign a different HOST name for the app--random-route
to create a URL that includes the app name and random wordscf help push
to view other options for this command
If you want to view log activity while the app deploys, launch a new terminal window and run cf logs APP-NAME
.
Once your app deploys, browse to your app URL. Search for the urls
field in the App started
block in the output of the cf push
command. Use the URL to access your app online.
Sample App Step
1. Change to the app
directory, and run ./grailsw war
to build the app.
2. Run cf push pong_matcher_grails -n HOST_NAME
to push the app.
Example: cf push pong_matcher_grails -n my-grails-app
Note: You do not have to include the -p
flag when you deploy the sample app. The sample app manifest declares the path to the archive that cf push
uses to upload the app files.
The example below shows the terminal output of deploying the pong_matcher_grails
app. cf push
uses the instructions in the manifest file to create the app, create and bind the route, and upload the app. It then binds the app to the mysql
service and follows the instructions in the manifest to start two instances of the app, allocating 1 GB of memory between the instances. After the instances start, the output displays their health and status.
$ cf push pong_matcher_grails -n my-grails-app Using manifest file /Users/example/workspace/pong_matcher_grails/app/manifest.yml Creating app pong_matcher_grails in org Cloud-Apps / space development as [email protected]... OK Creating route my-grails-app.cfapps.io... OK Binding my-grails-app.cfapps.io to pong_matcher_grails... OK Uploading pong_matcher_grails... Uploading app files from: /Users/example/workspace/pong_matcher_grails/app/target/pong_matcher_grails-0.1.war Uploading 4.8M, 704 files OK Binding service mysql to app pong_matcher_grails in org Cloud-Apps / space development as [email protected]... OK Starting app pong_matcher_grails in org Cloud-Apps / space development as [email protected]... OK -----> Downloaded app package (38M) -----> Java Buildpack Version: v2.5 | https://github.com/cloudfoundry/java-buildpack.git#840500e -----> Downloading Open Jdk JRE 1.8.0_25 from https://download.run.pivotal.io/openjdk/lucid/x86_64/openjdk-1.8.0_25.tar.gz (1.5s) Expanding Open Jdk JRE to .java-buildpack/open_jdk_jre (1.1s) -----> Downloading Spring Auto Reconfiguration 1.5.0_RELEASE from https://download.run.pivotal.io/auto-reconfiguration/auto-reconfiguration-1.5.0_RELEASE.jar (0.0s) Modifying /WEB-INF/web.xml for Auto Reconfiguration -----> Downloading Tomcat Instance 8.0.14 from https://download.run.pivotal.io/tomcat/tomcat-8.0.14.tar.gz (0.4s) Expanding Tomcat to .java-buildpack/tomcat (0.1s) -----> Downloading Tomcat Lifecycle Support 2.4.0_RELEASE from https://download.run.pivotal.io/tomcat-lifecycle-support/tomcat-lifecycle-support-2.4.0_RELEASE.jar (0.0s) -----> Downloading Tomcat Logging Support 2.4.0_RELEASE from https://download.run.pivotal.io/tomcat-logging-support/tomcat-logging-support-2.4.0_RELEASE.jar (0.0s) -----> Downloading Tomcat Access Logging Support 2.4.0_RELEASE from https://download.run.pivotal.io/tomcat-access-logging-support/tomcat-access-logging-support-2.4.0_RELEASE.jar (0.0s) -----> Uploading droplet (83M) 0 of 2 instances running, 2 starting 0 of 2 instances running, 2 starting 0 of 2 instances running, 2 starting 2 of 2 instances running App started Showing health and status for app pong_matcher_grails in org Cloud-Apps / space development as [email protected]... OK requested state: started instances: 2/2 usage: 1G x 2 instances urls: my-grails-app.cfapps.io state since cpu memory disk #0 running 2014-11-10 05:07:33 PM 0.0% 686.4M of 1G 153.6M of 1G #1 running 2014-11-10 05:07:36 PM 0.0% 677.2M of 1G 153.6M of 1G
Step 9: Test Your Deployed App
You’ve deployed an app to Cloud Foundry!
Use the cf CLI to review information and administer your app and your Cloud Foundry account. For example, you can edit the manifest.yml
to increase the number of app instances from 1 to 3, and redeploy the app with a new app name and host name.
See the Manage Your Application with the cf CLI section for more information.
Sample App Step
To test the sample app, do the following:
1. To export the test host, run export HOST=SAMPLE_APP_URL
, substituting the URL for your app for SAMPLE_APP_URL
.
2. To clear the database from any previous tests, run:
curl -v -X DELETE $HOST/all
You should get a response of
3. To request a match as “andrew”, run:
curl -v -H "Content-Type: application/json" -X PUT $HOST/match_requests/firstrequest -d '{"player": "andrew"}'
You should again get a response of 200
.
4. To request a match as a different player, run:
curl -v -H "Content-Type: application/json" -X PUT $HOST/match_requests/secondrequest -d '{"player": "navratilova"}'
5. To check the status of the first match request, run:
curl -v -X GET $HOST/match_requests/firstrequest
The last line of the output shows the match_id
.
6. Replace MATCH_ID
with the match_id
value from the previous step in the following command:
curl -v -H "Content-Type: application/json" -X POST $HOST/results -d '
{
"match_id":"MATCH_ID",
"winner":"andrew",
"loser":"navratilova"
}'
You should receive a 201 Created
response.
Alternative Methods for Pushing Apps
Integrate a Plugin for Your Build Tool
Cloud Foundry provides plugins for Maven and Gradle. You can deploy and manage your apps using Maven or Gradle command-line syntax and configure security credentials.
For more information, refer to the Build Tool Integration topic.
Manage Your Application with the cf CLI
Run cf help
to view a complete list of commands, grouped by task categories, and run cf help COMMAND
for detailed information about a specific command. For more information about using the cf CLI, refer to the cf Command Line Interface (CLI) topics, especially the Getting Started with cf CLI v6 topic.
Note: You cannot perform certain tasks in the CLI because these are commands that only a Cloud Foundry administrator can run. If you are not a Cloud Foundry administrator, the following message displays for these types of commands:
error code: 10003, message: You are not authorized to perform the requested action
Troubleshooting
If your application fails to start, verify that the application starts in your local environment. Refer to the Troubleshooting Application Deployment and Health topic to learn more about troubleshooting.
App Deploy Fails
Even when the deploy fails, the app might exist on Cloud Foundry. Run cf apps
to review the apps in the currently targeted org and space. You might be able to correct the issue using the CLI, or you might have to delete the app and redeploy.
App Requires a Unique URL
Cloud Foundry requires that each app that you deploy have a unique URL. Otherwise, the new app URL collides with an existing app URL and Cloud Foundry cannot successfully deploy the app. You can fix this issue by running cf push
with either of the following flags to create a unique URL:
-n
to assign a different HOST name for the app.--random-route
to create a URL that includes the app name and random words. Using this option might create a long URL, depending on the number of words that the app name includes.