Pushing apps with sidecar processes
Page last updated:
You can run additional processes in the same container as your app. These additional processes are called sidecar processes, or sidecars. An example of a sidecar is an Application Performance Monitoring (APM) tool.
The cf CLI v6 commands described in this topic are unsupported, but are supported in cf CLI v7. The latest supported cf CLI release is cf CLI v8. To upgrade to cf CLI v7, see Upgrading to cf CLI v7. To upgrade to cf CLI v8, see Upgrading to cf CLI v8.
Note This feature requires that your Cloud Foundry deployment uses capi-release 1.790 or later.
About sidecars
When you provide a sidecar for your app, Cloud Foundry packages the required code and configuration needed to run the sidecar and app in the same droplet. It deploys this droplet in a single container on Diego. Both processes within the container undergo health checks independently.
You can push sidecar processes with your app by using one of two methods:
- Using an app manifest. For instructions, see Push an app with a sidecar Using an app manifest.
- With a custom buildpack. For instructions, see Sidecar buildpacks.
For additional information about sidecars, see Sidecars in the Cloud Foundry API (CAPI) documentation.
For sample apps that use sidecars, see the capi-sidecar-samples repository on GitHub. These sample apps use an app manifest.
Use cases
You can use sidecars for processes that depend on each other or must run in the same container.
For example, you can use sidecars for processes that must:
- Communicate over a UNIX socket or through localhost
- Share the same file system
- Be scaled and placed together
- Have fast interprocess communication
Limitations
Sidecars have these limitations:
The start and stop order of app processes and their sidecars is undefined.
App processes and sidecars are codependent. If either fails or exits, the other does also.
Sidecars are not independently scalable. Sidecars share resources with the main app process and other sidecars within the container.
Sidecars only support PID-based health checks. HTTP health checks for sidecars are not supported.
Requirements for Java apps
These sections describe several requirements that are specific to pushing sidecars with Java apps.
Reserving memory
You must allocate memory to the sidecar. If you do not, the Java buildpack allocates all of the available memory to the app. As a result, the sidecar does not have enough memory and the app fails to start.
To allocate memory to the sidecar, use the memory
property in the app manifest. For example:
sidecars:
- name: SIDECAR-NAME
process_types: [ 'PROCESS-TYPES' ]
command: START-COMMAND
memory: 256MB
Where:
SIDECAR-NAME
is a name you give your sidecar.PROCESS-TYPES
is a list of app processes for the sidecar to attach to, such asweb
orworker
. You can attach multiple sidecars to each process type your app uses.START-COMMAND
is the command used to start the sidecar. For example,./binary
orjava -jar java-file.jar
.
You must also allocate memory to sidecars that you push with a custom buildpack. For more information, see Sidecar buildpacks.
Packaging binaries
If your sidecar is a binary file rather than a set of buildable source files, then you must package the binary file with your Java app.
In some cases, the Java buildpack requires you to push a .jar
file. If this is the case with your app, you must include the sidecar binary in the .jar
file.
To package the sidecar binary with the .jar
file, run:
zip JAR -u SIDECAR-BINARY
Where:
JAR
is your.jar
file.SIDECAR-BINARY
is your sidecar binary.
For more information about packaging assets with your Java app, see Cloud Foundry documentation.
Push an app with a sidecar using an app manifest
These sections explain how to push an app with a sidecar using an app manifest. For an example that you can try yourself, see Sidecar tutorial.
When pushing a Java app, follow the requirements listed in Requirements for Java Apps.
Prerequisites
Before you can push an app with a sidecar with an app manifest, you must have:
An app that is running or ready to be pushed.
A file that Cloud Foundry can run inside the application container as a sidecar process. For example, an executable binary, a Java .jar file, or Ruby scripts.
Procedure
To push an app with a sidecar:
Create an app or use an existing app. To create an app:
cf create-app APP-NAME
Where
APP-NAME
is the name you give your app.Create a manifest file in the root directory of your app, such as
manifest.yml
. Otherwise, use an existing manifest file for your app. For more information, see Deploying with app manifests.Add the following values to your app manifest file under the
applications
key:sidecars: - name: SIDECAR-NAME process_types: [ 'PROCESS-TYPES' ] command: START-COMMAND
Where:
SIDECAR-NAME
is a name you give your sidecar.PROCESS-TYPES
is a list of app processes for the sidecar to attach to, such asweb
orworker
. You can attach multiple sidecars to each process type your app uses.START-COMMAND
is the command used to start the sidecar. For example,./binary
orjava -jar java-file.jar
.
This example manifest file includes multiple sidecars:
--- applications: - name: my-app sidecars: - name: authenticator process_types: [ 'web', 'worker' ] command: bundle exec run-authenticator - name: performance monitor process_types: [ 'web' ] command: bundle exec run-performance-monitor
To apply the manifest file to your app:
cf apply-manifest -f PATH-TO-MANIFEST
Where
PATH-TO-MANIFEST
is the path to your manifest file.To push your app:
cf push APP-NAME
Where
APP-NAME
is the name of your app.
Sidecar tutorial
You can explore sidecars using the app in the capi-sidecar-samples repository on GitHub. The following sections describe the app, how to build and push the app, and some ways to observe the app and its processes after pushing.
In this tutorial, you are pushing the Ruby sample app. You can also follow this tutorial for a Java app using the sidecar-dependent-java-app
and push_java_app_with_binary_sidecar.sh
in the samples repository. When pushing a Java app, follow the requirements listed in Requirements for Java apps.
About the sample app
The capi-sidecar-samples repository contains:
A simple Ruby app: This app is named
sidecar-dependent-app
. It includes a/config
endpoint that calls to the sidecar and prints the response, as shown in this code snippet:get '/config' do puts "Sending a request to the config-server sidecar at localhost:#{ENV['CONFIG_SERVER_PORT']}/config/" response = Typhoeus.get("localhost:#{ENV['CONFIG_SERVER_PORT']}/config/") puts "Received #{response.body} from the config-server sidecar" response.body end
A Golang sidecar: The
config-server-sidecar
produces aconfig-server
binary. It provides apps with their required configuration over its/config
endpoint. It also accepts connections only over localhost on theCONFIG_SERVER_PORT
port. This means the sidecar must be co-located in the same container as the app, so that it shares the same network namespace as the main app.
The following diagram illustrates the app architecture:
Push the app and sidecar
If you do not have Go installed, download the config-server_linux_x86-64
binary from CAPI Sidecar sample releases in the capi-sidecar-samples
repository in GitHub.
To push the app and sidecar:
In a terminal window, clone the Git repository to your workspace by running:
git clone https://github.com/cloudfoundry-samples/capi-sidecar-samples.git
Go to the
config-server-sidecar
directory.Build the binary for the sidecar by running:
GOOS=linux GOARCH=amd64 go build -o config-server .
To create the app:
cf create-app sidecar-dependent-app
Go to the
sidecar-dependent-app
directory.Open and review the
manifest.yml
file. Undersidecars
, the sidecar is specified with a name, process type, and start command. Underenv
, an environment variable defines the port on which the app and sidecar communicate.To apply the manifest to the app:
cf apply-manifest
To push the app:
cf push sidecar-dependent-app
After you push the app, you can further explore it as described in the sections below:
- View processes running in the app container via SSH
- View the web URL and app logs via SSH
- View and debug processes running in the app container via HTTP
View processes running in the app container via SSH
To view the app and sidecar process running in the container:
SSH into the application container by running:
cf ssh sidecar-dependent-app
To see both the
rackup
process for the main app andconfig-server
process for the sidecar, run:ps aux
The output you might see resembles this example output:
vcap@f00949bd-6601-4731-6f7e-e859:~$ ps aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.0 1120 0 ? S 22:17 0:00 /tmp/garden-init vcap 7 0.0 0.0 106716 4508 ? S 22:17 0:00 ./config-server vcap 13 0.0 0.1 519688 35412 ? S 22:17 0:00 /home/vcap/deps/0/vendor_bundle/ruby/2.4.0/bin/rackup config.ru -p 8080 vcap 24 0.0 0.0 116344 10792 ? S 22:17 0:00 /tmp/lifecycle/diego-sshd --allowedKeyExchanges= --address=0.0.0.0:2222 --allowUnauthenticatedClients=false --inhe root 82 0.0 0.0 108012 4548 ? S 22:17 0:00 /etc/cf-assets/healthcheck/healthcheck -port=8080 -timeout=1000ms -liveness-interval=30s vcap 215 0.3 0.0 70376 3756 pts/0 S 23:12 0:00 /bin/bash vcap 227 0.0 0.0 86268 3116 pts/0 R 23:12 0:00 ps aux
To see that the sidecar is listening on the port specified by
CONFIG_SERVER_PORT
and that the mainruby
process is connected to it, run:lsof -i | grep $CONFIG_SERVER_PORT
The output you see might resemble this example output:
vcap@f00949bd-6601-4731-6f7e-e859:~$ lsof -i | grep $CONFIG_SERVER_PORT config-se 7 vcap 3u IPv4 17265901 0t0 TCP *:8082 (LISTEN) config-se 7 vcap 5u IPv4 17265992 0t0 TCP localhost:8082->localhost:42266 (ESTABLISHED) ruby 13 vcap 11u IPv4 17274965 0t0 TCP localhost:42266->localhost:8082 (ESTABLISHED)
View the web URL and app logs via SSH
To view the web URL and logs for the app:
In a browser, go to the
config
endpoint of thesidecar-dependent-app
. For example:https://sidecar-dependent-app.example.com/config
.See that the browser displays
Scope
andPassword
information. This is the configuration that the app fetches from theconfig-server
sidecar.Begin streaming logs for the app by running:
cf logs sidecar-dependent-app
In your browser, refresh the
/config
endpoint page and observe that the log stream in your terminal displays logs for both the sidecar and the main app process.In a separate terminal from your log stream, SSH into the application container by running:
cf ssh sidecar-dependent-app
Stop the sidecar process by running:
kill -9 $(pgrep config-server)
View the output in the terminal where you are streaming the app logs. The app logs indicate that the sidecar process failed and that Diego restarted the application container. For example:
2019-04-17T16:48:55.41-0700 [API/0] OUT App instance exited with guid 21df1eb8-f25d-43b2-990b-c1a417310553 payload: {"instance"=>"a8db0eed-7371-4805-5ad3-4596", "index"=>0, "cell_id"=>"86808ce7-afc2-47da-9e79-522a62a48cff", "reason"=>"CRASHED", "exit_description"=>"APP/PROC/WEB/SIDECAR/CONFIG-SERVER: Exited with status 137", "crash_count"=>1, "crash_timestamp"=>1555544935367052708, "version"=>"50892dcb-274d-4cf6-b944-3eda1e000283"}
View and debug processes running in the app container via HTTP
Sidecars can be used to collect debug information (e.g. thread dumps) from another process running in the same container. This is especially useful if you want to debug a running process using an HTTP request, for instance if you do not have ssh access to the application container.
This is an example of a simple routable debug sidecar for java applications, but the same concept can be adapted to more advanced debug tooling and other languages or frameworks.
Prerequisites
Before you begin, you must have:
A java app with a manifest that is ready to be pushed. For example, the java sample app from CF Acceptance Tests.
A route to map to the debug sidecar
Procedure
To add a debug sidecar to the java app:
Create a sidecar that responds to HTTP requests and calls
kill -3
on the java process. When a java process receives the resulting SIGQUIT signal, it will print a thread dump to STDOUT. For an example, see the java_debug_sidecar on GitHub.Place the sidecar binary in the root directory of your java app
Add the following to your app manifest:
sidecars: - name: debug-sidecar process_types: [ 'web' ] command: START-COMMAND memory: 256MB
Where
START-COMMAND
is the command used to start the sidecar. For the above example sidecar,./java_debug_sidecar
.Push the java application. For example:
cf push APP-NAME -f manifest.yml -m 1G
Where
APP-NAME
is the name of your app.Map a route to the sidecar process’s port. For detailed steps, see Configuring Cloud Foundry to route traffic to apps on custom ports.
cf curl -X PATCH /v3/routes/ROUTE-GUID/destinations -d '{ "destinations": [ { "app": { "guid": "APP-GUID", "process": { "type": "web" } }, "port": PORT, "protocol": "http1" } ] }'
Where:
APP-GUID
is the GUID of your app.ROUTE-GUID
is the GUID of the route to map to the sidecar.PORT
is a custom port on which your app is configured to receive requests. This is8081
for the above example.
Restart the app to complete the port mapping
cf restart APP_NAME
Where
APP-NAME
is the name of your app.Tail the app logs:
cf logs APP_NAME
Where
APP-NAME
is the name of your app.In another terminal, make a HTTP request to the sidecar, to trigger the thread dump. For example:
curl https://debug-sidecar.example.com/threaddump
Observe the thread dump in the app logs
Next Steps
Now that you have a simple debugging sidecar working, here are some ideas for next steps:
- Use more sophisticated debugging tools
- Return the debug information in the HTTP response, rather than logging to STDOUT
- Inject the debug sidecar via a Sidecar buildpacks. For example: java-debug-buildpack on GitHub.
- Add authentication for the debug sidecar’s HTTP route, for instance using an authentication Route Service.