{"id":15345453,"url":"https://github.com/jthomas/openwhisk-web-action-http-proxy","last_synced_at":"2025-04-11T18:22:15.747Z","repository":{"id":140706047,"uuid":"175608376","full_name":"jthomas/openwhisk-web-action-http-proxy","owner":"jthomas","description":"Proxies HTTP traffic from Apache OpenWhisk Web Actions to existing web applications.","archived":false,"fork":false,"pushed_at":"2019-04-30T09:17:13.000Z","size":20155,"stargazers_count":3,"open_issues_count":1,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-11T18:22:05.974Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jthomas.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-03-14T11:27:53.000Z","updated_at":"2019-04-30T09:17:17.000Z","dependencies_parsed_at":null,"dependency_job_id":"c5d9d14e-188c-4165-b676-3cabb1bec909","html_url":"https://github.com/jthomas/openwhisk-web-action-http-proxy","commit_stats":{"total_commits":11,"total_committers":2,"mean_commits":5.5,"dds":0.2727272727272727,"last_synced_commit":"25cfa90dbcacc240196b50bd2040af89da8637db"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jthomas%2Fopenwhisk-web-action-http-proxy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jthomas%2Fopenwhisk-web-action-http-proxy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jthomas%2Fopenwhisk-web-action-http-proxy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jthomas%2Fopenwhisk-web-action-http-proxy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jthomas","download_url":"https://codeload.github.com/jthomas/openwhisk-web-action-http-proxy/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248456386,"owners_count":21106607,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-01T11:13:26.592Z","updated_at":"2025-04-11T18:22:15.715Z","avatar_url":"https://github.com/jthomas.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Apache OpenWhisk Web Action HTTP Proxy\n\nThis project proxies HTTP traffic from [Apache OpenWhisk](http://openwhisk.incubator.apache.org/) [Web Actions](https://github.com/apache/incubator-openwhisk/blob/master/docs/webactions.md) to existing web applications.\n\n[HTTP events](https://github.com/apache/incubator-openwhisk/blob/master/docs/webactions.md#http-context) received by the Web Action Proxy are forwarded as HTTP requests to the web application. HTTP responses from the web application are returned as Web Action [responses](https://github.com/apache/incubator-openwhisk/blob/master/docs/webactions.md#handling-http-requests-with-actions).\n\nThis proxy is designed to be built into a Docker image that will run the stateless web applications. Using [Docker support](https://github.com/apache/incubator-openwhisk/blob/master/docs/actions-docker.md) in Apache OpenWhisk, web applications can then be executed on the serverless platform with minimal modifications.\n\n![Web Action Proxy](./web-action-proxy.png)\n\n_**Please note: This is an alpha-stage experiment!** Don't expect everything to work. This project is designed to run small simple stateless web applications on Apache OpenWhisk. Please don't attempt to \"lift 'n' shift\" a huge stateful enterprise app server onto the platform!_\n\n## Why?\n\nThere are lots of existing (simple) stateless web applications that could easily be ran on a serverless platform. People have already written a [number](https://github.com/IBM/expressjs-openwhisk) [of](https://github.com/claudiajs/claudia) [custom](https://github.com/logandk/serverless-wsgi) [plugins](https://github.com/Miserlou/Zappa) for web application frameworks to support running those framework applications on serverless platforms.\n\nThese projects allow developers to continue to use frameworks they are familiar when building serverless web applications and provide an easy path to \"lift and shift\" existing web applications to serverless platforms.\n\nUsing framework plugins as the approach, to allowing web application to run on serverless platforms, needs the same custom proxy plugin re-implemented for every different framework. This project provides a mechanism, using an external HTTP proxy process, to support any existing web application without needing a custom framework plugin.\n\n## Node.js + Express Example\n\nThis is an [example Node.js web application](https://github.com/jthomas/express_example), built using the [Express web application framework](https://expressjs.com/): \n\n![https://camo.githubusercontent.com/2aa43809d8d8a9f9ccb906c1028d81f1ba1913d9/687474703a2f2f7368617065736865642e636f6d2f696d616765732f61727469636c65732f657870726573735f6578616d706c652e6a7067](https://camo.githubusercontent.com/2aa43809d8d8a9f9ccb906c1028d81f1ba1913d9/687474703a2f2f7368617065736865642e636f6d2f696d616765732f61727469636c65732f657870726573735f6578616d706c652e6a7067)\n\nThe web application renders static HTML content for three routes (`/`,  `/about` and `/contact`). CSS files and fonts are also served by the backend.\n\n**Use these steps to run this web application on Apache OpenWhisk using the Web Action Proxy...**\n\n- Clone project repo.\n\n```\ngit clone https://github.com/jthomas/express_example\n```\n\n- Install project dependencies in the `express_example` directory.\n\n```\nnpm install\n```\n\n- Bundle web application and libraries into zip file.\n\n```\nzip -r action.zip *\n```\n\n- Create the Web Action (using a custom runtime image) with the following command.\n\n```\nwsk action create --docker jamesthomas/generic_node_proxy --web true --main \"npm start\" -p \"__ow_proxy_port\" 3000 web_app action.zip\n```\n\n- Retrieve the Web Action URL for the new action.\n\n```\nwsk action get web_app --url\n```\n\n- Open the Web Action URL in a HTTP web browser. *(Note: Web Action URLs must end with a forward-slash to work correctly, e.g. `https://\u003cOW_HOST\u003e/api/v1/web/\u003cNAMESPACE\u003e/default/web_app/`).*\n\n![Web Action Proxy Express JS](http://jamesthom.as/images/express-js-web-action-proxy.gif)\n\nIf this works, the web application should load as above. Clicking links in the menu will navigate to different pages in the application.\n\n#### custom runtime image\n\nThis example Web Action uses my own pre-built custom runtime image for Node.js web applications (`jamesthomas/generic_node_proxy`). This was created from the following Dockerfile to support dynamic runtime injection of web application source files.\n\n```\nFROM node:10\n\nADD proxy /app/\nWORKDIR /app\nEXPOSE 8080\n\nCMD ./proxy\n```\n\n## Runtime Mode Options\n\nThe proxy binary needs to be executed in a Docker container alongside the web application process.\n\nBoth HTTP processes must be started on different ports. The proxy uses port 8080 and the web application can use any other port. An environment variable or action parameter can be used to configure the local port to proxy.\n\nTwo  different options are available for getting web application source files into the runtime environment.\n\n- **[Build source files directly into the container image alongside proxy binary.](#usage-sources-files-in-image)**\n- **[Dynamically inject source files into container runtime during initialisation.](#usage-dynamic-runtime-injection)**\n\nBuilding source files into the container is simpler and incurs lower cold-starts delays, but means source code will be publicly available on Docker Hub. Injecting source files through the action zips means the public container image can exclude all private source files and secrets. The extra initialisation time for dynamic injection does add to cold-start delays.\n\n## Configuration\n\nHTTP proxy options can be defined using environment variables (defined in Dockerfiles) or default action parameters. The following configuration options are supported.\n\n### environment variables\n\n- `PROXY_HOST` - host to proxy (default: `localhost`).\n- `PROXY_PORT` - local port used by the web application (default: `80`).\n- `PROXY_ALIVE_PATH` - URL path to check for `200` response indicating server is available (default: `/`).\n- `PROXY_ALIVE_DELAY`- poll delay (ms) in between liveness checks (default: `100`)\n- `PROXY_PROTOCOL` - protocol prefix used in proxy requests (default: `http`)\n\n### action parameters\n\n- `__ow_proxy_host` - host to proxy (default: `localhost`).\n- `__ow_proxy_port` - local port used by the web application (default: `80`).\n- `__ow_proxy_alive_path` - URL path to check for `200` response when server is available (default: `/`).\n- `__ow_proxy_alive_delay`- poll delay (ms) in between liveness checks (default: `100`)\n- `__ow_proxy_protocol` - protocol prefix used in proxy requests (default: `http`)\n- `__ow_proxy_env_\u003cENV_VAR_NAME\u003e` - set custom environment variable in runtime.\n\n*note: the web application cannot use port 8080 as this is used by the proxy to expose the runtime API.* \n\n## Usage (Dynamic Runtime Injection)\n\nDynamic runtime injection needs you to build a Docker image containing just the proxy binary and runtime dependencies. Application source files are provided in the action zip file and extracted into the runtime upon initialisation. The proxy will start the app server on the first request.\n\n### define custom docker image\n\nThis image should contain just the proxy binary and necessary dependencies (e.g node.js runtime).\n\n```\nFROM image:version\n\nADD proxy /app/\nWORKDIR /app\nEXPOSE 8080\n\nCMD ./proxy\n```\n\nThe Dockerfile must have the following commands.\n\n- `COPY/ADD proxy \u003cdest\u003e` - Add the proxy binary from this project to the runtime filesystem \n- `EXPOSE 8080` - Expose the proxy port used to handle requests from the platform.\n- `CMD ./proxy` - Starts HTTP proxy process to handle platform requests.\n\n*Environment variables can also be defined here to set proxy configuration options, instead of using default action parameters as shown below.*\n\n### build custom docker image\n\n- Run the Docker build command to create a new image.\n\n```\ndocker build -t \u003cREPO\u003e/\u003cIMAGE\u003e .\n```\n\n- Push the image to a public Docker Hub repository.\n\n```\ndocker push \u003cREPO\u003e/\u003cIMAGE\u003e\n```\n\n*Using Docker images in Apache OpenWhisk needs those images to be available on Docker Hub. Private container registries are not currently supported in the platform.*\n\n### use image with openwhisk web actions\n\n- Bundle application source files into a zip file.\n\n```\nzip -r action.zip *\n```\n\n- Create the Web Action from the Docker image with the following command.\n  - Replace `\u003cSTART_COMMAND\u003e` with the command needed to start the web application server.\n  - Replace `\u003cPROXY_PORT\u003e` with the port used by the web application server.\n  - Replace `\u003cACTION_NAME\u003e` with an action name.\n\n```\nwsk action create --docker \u003cREPO\u003e/\u003cIMAGE\u003e --web true --main \"\u003cSTART_COMMAND\u003e\" -p \"__ow_proxy_port\" \u003cPROXY_PORT\u003e \u003cACTION_NAME\u003e action.zip\n```\n\n- Retrieve the Web Action URL for the new action.\n\n```\nwsk action get \u003cACTION_NAME\u003e --url\n```\n\n### invoke the web action\n\nWeb Action URLs are in this format.\n\n```\nhttps://\u003cOW_HOST\u003e/api/v1/web/\u003cNAMESPACE\u003e/default/\u003cACTION_NAME\u003e/\n```\n\nInvoking these URLs with HTTP requests will proxy the web application from inside the container.\n\nRequests to the base Web Action URL will be treated as requests to the URL root for the web application. Subpaths requests on the base Web Action URL will be forwarded as sub-paths to the web application.\n\n## Usage (Sources Files In Image)\n\nWith an existing Docker image containing application runtime and source files, you can just extend the image with extra commands as shown below.\n\n### from an existing web app image\n\n```\nFROM app_runtime:version\n\nENV PROXY_PORT 5000\nCOPY proxy /app\nEXPOSE 8080\n\nCMD ./app/script.sh\n```\n\nThe Dockerfile used to build the runtime image must have the following commands.\n\n- `ENV PROXY_PORT \u003cLOCAL_PORT\u003e` - Sets the local port used by the web application to proxy.\n\n- `COPY/ADD proxy \u003cdest\u003e` - Add the proxy binary from this project to the runtime filesystem \n- `EXPOSE 8080` - Expose the proxy port used to handle requests from the platform.\n\nThe `CMD` for the image should start both processes in the foreground. This can be achieved using a bash script as follows.\n\n```\n#!/bin/bash\n\n./\u003cPROXY_LOCATION\u003e/proxy \u0026 \u003cWEB APP START CMD\u003e\n```\n\n### build custom docker image\n\n- Run the Docker build command to create a new image.\n\n```\ndocker build -t \u003cREPO\u003e/\u003cIMAGE\u003e .\n```\n\n- Push the image to a public Docker Hub repository.\n\n```\ndocker push \u003cREPO\u003e/\u003cIMAGE\u003e\n```\n\n*Using Docker images in Apache OpenWhisk needs those images to be available on Docker Hub. Private container registries are not currently supported in the platform.*\n\n### use image with openwhisk web actions\n\n- Create the Web Action from the Docker image with the following command.\n\n```\nwsk action create \u003cACTION_NAME\u003e --docker \u003cREPO/IMAGE\u003e --web true\n```\n\n- Retrieve the Web Action URL for the new action.\n\n```\nwsk action get \u003cACTION_NAME\u003e --url\n```\n\n### invoke the web action\n\nWeb Action URLs are in this format.\n\n```\nhttps://\u003cOW_HOST\u003e/api/v1/web/\u003cNAMESPACE\u003e/default/\u003cACTION_NAME\u003e/\n```\n\nInvoking these URLs with HTTP requests will proxy the web application from inside the container.\n\nRequests to the base Web Action URL will be treated as requests to the URL root for the web application. Subpaths requests on the base Web Action URL will be forwarded as sub-paths to the web application.\n\n## Examples\n\nSee the `examples` directory for sample applications with build instructions for the following runtimes.\n\n- [Node.js with Express.js](./examples/nodejs+express)\n- [Python with Flask](./examples/python+flask)\n- [Java with OpenLiberty](./examples/java+openliberty)\n\n## Challenges\n\nThis experiment is still in the alpha-stage and comes with many restrictions at the moment...\n\n- HTTP request and responses sizes are limited to the maximum sizes allowed by Apache OpenWhisk for input parameters and activation results. This defaults to 1MB in the open-source project and 5MB on IBM Cloud Functions.\n- Page links must use URLs with relative paths to the Web Action URL rather than the host root, e.g. `href=\"home\"` rather than `href=\"/home\"`. This is due to the Web Actions being served from a sub-path of the platform  (`/api/v1/web/\u003cNAMESPACE\u003e/default/\u003cACTION\u003e`) rather than the host root.\n- Docker images will be pulled from the public registry on the first invocation. This will lead to long cold-start times for the first request after the action has been created. Large image sizes = longer delays. This only occurs on the first invocation.\n- Web app startup times affect cold start times. The proxy blocks waiting for the web application to start before responding. This delay is included in each cold start. Concurrent HTTP requests from a web browser for static page assets will (initially) result in multiple cold starts.\n- Web Sockets and other complex HTTP features, e.g. server-side events, cannot be supported.\n- Web applications will run in ephemeral container environments that are paused between requests and destroyed without warning. This is not a traditional web application environment, e.g. running background tasks will not work. \n\nLots of things haven't been tested and won't be supported outside simple web applications. Buyer beware.\n\n## Development\n\nThe HTTP Web Action proxy is written using Node.js. \n\nProxy source code is bundled into a binary executable using the [nexe](https://github.com/nexe/nexe) project.\n\n```\nnpm run build\n```\n\nThis command will run the build script in a Linux container to generate a compatible binary for the runtime.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjthomas%2Fopenwhisk-web-action-http-proxy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjthomas%2Fopenwhisk-web-action-http-proxy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjthomas%2Fopenwhisk-web-action-http-proxy/lists"}