Proxy requests for local and remote service parity in Docker
Learn how to proxy requests conditionally to remote services while preserving local fallbacks for consistent environments.
Lesson Content
We have an Express app that serves an image of Herman from the local public/images directory. To keep local and remote environments consistent, we’ll proxy image requests through a CDN whenever BASE_IMAGE_URL is defined, and fall back to the local static directory when it isn’t.
First, install the express-http-proxy middleware with Yarn:
yarn add express-http-proxyRequire the module near the top of the Express application:
const proxy = require('express-http-proxy');The proxy should only be used when the BASE_IMAGE_URL environment variable exists. Define proxyBaseImageUrl with the proxy middleware when it does, and with the local static middleware otherwise:
const baseImageUrl = process.env.BASE_IMAGE_URL;
const proxyBaseImageUrl = baseImageUrl
? proxy(baseImageUrl, {
proxyReqPathResolver: function (req) {
const newPath = baseImageUrl + req.path;
console.log(newPath);
return newPath;
}
})
: express.static(path.join(__dirname, 'public/images'));The first argument passed to proxy() is the base URL for the remote service. The second argument is an options object containing proxyReqPathResolver. This function receives the request and returns the path that the proxy requests from the remote service.
The resolver combines the BASE_IMAGE_URL value with the requested image path. It also logs the final URL, so you can see when a request is proxied and where it goes.
Use proxyBaseImageUrl for the /images route:
const path = require('path');
const express = require('express');
const proxy = require('express-http-proxy');
const baseImageUrl = process.env.BASE_IMAGE_URL;
const proxyBaseImageUrl = baseImageUrl
? proxy(baseImageUrl, {
proxyReqPathResolver: function (req) {
const newPath = baseImageUrl + req.path;
console.log(newPath);
return newPath;
}
})
: express.static(path.join(__dirname, 'public/images'));
const app = express();
app.use('/images', proxyBaseImageUrl);
app.listen(8080);When BASE_IMAGE_URL isn’t defined, requests such as /images/herman.jpg use the local public/images directory. When it is defined, the same request is sent to the configured remote base URL instead.
Start the application with the CDN URL assigned to BASE_IMAGE_URL. The following example points to a Google Cloud Storage bucket:
BASE_IMAGE_URL=https://storage.googleapis.com/03dc42f3e56e458e92f57f6c692aea3d node index.jsWhen you request Herman’s image, the console shows the resolved remote URL:
https://storage.googleapis.com/03dc42f3e56e458e92f57f6c692aea3d/herman.jpgThis gives the application the same /images request path in both environments. Local development serves the file directly, while the configured environment proxies the request through the CDN or remote storage service.
Join the discussion!
Comments
Want to comment on this lesson?
Log in to leave comments.