DEV Community

Arun Shinde for Google Developer Experts

Posted on • Originally published at Medium on

Enhancing Web Application Security with Cloud Run Sidecar Containers

Cloud Run offers a robust serverless platform for deploying containerized applications. By utilizing sidecar containers, developers gain enhanced control over security, resource optimization, and application architecture. This article explores a practical use case of leveraging sidecar containers to strengthen a web application’s security posture.

The Challenge: Securing Monolithic Applications

Traditional web applications often bundle frontend and backend components into a single deployable unit, leading to:

  • Tight Coupling: Frontend and backend are packaged together (e.g., in a single JAR file).
  • Large Deployment Size: The combined size of the backend code and static assets can be significant
  • Inefficient Resource Usage: The backend, often a full-fledged application server like Spring Boot with Tomcat, is used to serve both dynamic content and static files.
  • Security Risks: Security rules applied at the backend might not be optimal for the frontend, potentially leaving it vulnerable.

The Solution: Sidecar Containers

Cloud Run sidecar containers provide a powerful approach to decouple frontend and backend components, enhancing security and efficiency.

Development Environment:

The following development environment was used for this project:

  • Operating System: macOS
  • IDE: Eclipse
  • JDK: OpenJDK 23
  • Node.js: v20.11.0

Deployment to Cloud Run:

The application will be deployed using the Cloud Run dashboard within the Google Cloud Console. The image is getting pushed into the Container Registry and not in the Artifact Registry.

Use Case: Separating Static Content and Business Logic

To demonstrate this approach, let’s consider a web application with a Java backend and a frontend composed of static files. I have created a GitHub repository with the code for a Cloud Run multi-container application.

Implementing Sidecar Containers:

A sample Java Spring Boot application with the following structure demonstrates this approach:

Nginx Sidecar Deployment

The static folder contains only index.html. The Nginx configuration files located in the code repository at below locations.

src/main/resources/docker-files/frontend-container/default.conf
src/main/resources/docker-files/frontend-container/nginx.conf
src/main/resources/docker-files/frontend-container/Dockerfile
Enter fullscreen mode Exit fullscreen mode

To create the Nginx sidecar container image, use the following commands:

docker buildx build -t gcr.io/{project_name}/{project_name}-frontend:latest -f src/main/resources/docker-files/frontend-container/Dockerfile --platform linux/amd64 .
docker push gcr.io/{project_name}/{project_name}-frontend:latest
Enter fullscreen mode Exit fullscreen mode

Java Sidecar Deployment

To prepare the Java backend for deployment, create a JAR with excluding static content from application using a Maven profile. This profile is already created in the pom.xml called exclude-static. Execute following command from the terminal.

mvn clean package -P exclude-static
Enter fullscreen mode Exit fullscreen mode

The Dockerfile for the backend container utilizes this JAR file to build the container image. To create the Java sidecar container image, use the following commands:

docker buildx build -t gcr.io/{project_name}/{project_name}-backend:latest -f src/main/resources/docker-files/backend-container/Dockerfile --platform linux/amd64
docker push gcr.io/{project_name}/{project_name}-backend:latest
Enter fullscreen mode Exit fullscreen mode

Deploying to Cloud Run

Navigate to Cloud Run: In the Google Cloud Console, go to the Cloud Run dashboard.

Create a New Service: Click “Create Service” to deploy the application as a new service. (You can also deploy to an existing service if needed.)

Nginx Container:

  • Select the Nginx image you pushed to Container Registry (or Artifact Registry, the recommended replacement).
  • Set Memory to 512 MB and CPU to 1.
  • Leave other values at their defaults.
  • Click Done.

Cloud Run Deployment

Cloud Run Deployment Settings

Cloud Run Deployment Container

Java Backend Container:

  • Click “Add Container.”
  • Select the Java image you pushed to Container Registry (or Artifact Registry)
  • Set Memory to 512 MB and CPU to 1.
  • Container startup order: Select the Nginx container as the main container to ensure it starts first.
  • Health Check: Configure a startup probe with the following values Initial delay (10 seconds), Timeout (5 seconds), Failure threshold(3)
  • Leave other values at their defaults.
  • Click Done.

Cloud Run Deploy

Deploy: Click “Deploy” to deploy the service with both containers.

Test Out:

After deploying the application, you can test it out by:

Accessing the Cloud Run Service URL: This will display the content from index.html, served by the Nginx sidecar container.

Request Served from Nginx
Request served from the Nginx server

Appending Servlet Paths: Add /hello-servlet-1 or /hello-servlet-2 to the URL to access the respective content from those servlets. These requests will be served by the Java backend container.

Request Served from Nginx - HelloServlet1
Request served from the HelloServlet1 servlet

Request Served from Nginx - HelloServlet2
Request served from the HelloServlet2 servlet

Now check what security configs applied by the server when those requests served.

Request Served from Nginx - Security default.conf
Response Headers — All added security configs in the default.conf has been applied.

Request Served from Nginx - Security Java Server
No security configs added by Nginx server on Java Servlet response. We can add rules if required.

Security Benefits of Container Separation

  • Improved Security: Isolating components minimizes the impact of potential vulnerabilities.
  • Enhanced Performance: Optimizes resource usage.
  • Faster Deployments: Smaller container images result in quicker deployments.
  • Increased Scalability: Independently scale components.
  • Simplified Maintenance: Decoupled components are easier to maintain.

Beyond Static Content

Sidecar containers can also be used for:

  • Monitoring, logging, Observability
  • Asynchronous tasks
  • Security scanning
  • API management
  • Data transformation

Conclusion

Cloud Run sidecar containers provide a powerful tool for enhancing the security and performance of your web applications. By decoupling components and applying targeted security measures, you can significantly improve your application’s overall security posture and user experience.


Top comments (0)