metadata
title: Basic Docker SDK Space
emoji: 🐳
colorFrom: purple
colorTo: gray
sdk: docker
app_port: 8000
用bun+ts+http-proxy实现一个用完整的url作为path参数,反向代理此path的url来访问api的功能,要求支持至少16个并发请求
示例:
- 运行程序:监控 localhost,运行在8001端口
- 用户请求代理地址: http://localhost:8001/https://api.real.io:3000/v1/models
- 真实访问的目标地址:https://api.real.io:3000/v1/models
Project Setup:
Create Project Directory:
mkdir bun-url-proxy cd bun-url-proxyInitialize Bun Project:
bun init -y(Follow the prompts, the defaults are usually fine. Ensure
index.tsis your entry point).Create
srcdirectory andindex.tsfile:
Explanation:
- Bun Server (
serve): Sets up a high-performance HTTP server listening onlocalhost:8001. - Fetch Handler: This function is called for every incoming request.
- URL Extraction:
- It takes the
pathnamefrom the incoming request URL (request.url). url.pathname.substring(1)removes the leading/.+ url.searchappends any query parameters from the original proxy request to the target URL.
- It takes the
- URL Validation: It uses a
try...catchblock withnew URL()to ensure the extracted path is actually a valid URL structure. If not, it returns a400 Bad Request. - Header Forwarding:
- It iterates through the incoming request's headers.
- It copies headers to a new
Headersobject (forwardedHeaders), skipping common hop-by-hop headers defined inBANNED_HEADERS(likeConnection,Keep-Alive,Host, etc.). It's crucial not to forward the originalHostheader;fetchwill set the correctHostbased on thetargetUrl. - It adds
X-Forwarded-For,X-Forwarded-Host, andX-Forwarded-Protoheaders, which are standard practice for proxies to inform the target server about the original client request.
- Making the Proxy Request (
fetch):- It uses Bun's built-in
fetchto make the actual request to thetargetUrl. method: Copies the original request method.headers: Uses the filteredforwardedHeaders.body: Forwards the request body only if the method isn'tGETorHEADand if a body exists (request.body).redirect: 'manual': This is very important. It tellsfetchnot to follow redirects (3xx responses) itself. Instead, it will return the 3xx response, which the proxy then sends back to the original client. This allows the client's browser or application to handle the redirect correctly.
- It uses Bun's built-in
- Handling the Response:
- It takes the
Responseobject (proxyResponse) received from the target server. - It creates new response headers, copying headers from the
proxyResponsewhile again filtering out hop-by-hop headers usingBANNED_HEADERS. This prevents sending invalid headers back to the client. - It constructs a new
Responseto send back to the original client, using the target's status code, status text, the filtered headers, and crucially, theproxyResponse.body. This streams the body efficiently from the target to the client.
- It takes the
- Error Handling:
- A
try...catchblock surrounds thefetchcall to handle network errors (e.g., DNS resolution failure, connection refused). It logs the error and returns a502 Bad Gatewayor504 Gateway Timeoutresponse. - The
server.errorhandler catches broader server errors.
- A
- Concurrency: Bun's server and
fetchimplementation are built on an asynchronous, event-driven architecture (similar to Node.js but often faster). It's designed for high concurrency out-of-the-box. Handling 16 concurrent requests should be trivial for Bun on reasonably modern hardware, assuming the target servers can also handle that load. No special code is needed in this application to enable concurrency; Bun manages it. - Graceful Shutdown: Listens for
SIGINT(Ctrl+C) andSIGTERMto shut down the server cleanly.
How to Run:
Running Locally
- Save the code as
src/index.ts. - Run from your terminal in the project directory:
bun start # Or for development with automatic restarts on file changes: # bun run dev
Running with Docker
Using Docker directly
Build the Docker image:
docker build -t proxy-url .Run the container:
docker run -p 8001:8001 proxy-url
Using Docker Compose
Start the service:
docker-compose up -dView logs:
docker-compose logs -fStop the service:
docker-compose down
How to Use:
Open your browser or use curl:
http://localhost:8001/https://httpbin.org/get?show_env=1(Proxies to httpbin's get endpoint)http://localhost:8001/https://api.github.com/users/octocat(Proxies to GitHub API)curl -X POST -H "Content-Type: application/json" -d '{"name":"proxy test"}' http://localhost:8001/https://httpbin.org/post(Proxies a POST request)
The server will log the requests and proxy actions to the console.
Docker Deployment
This project includes Docker configuration for easy deployment:
- Dockerfile: Defines the container image using the official Bun image
- docker-compose.yml: Provides an easy way to run the container with proper configuration
- .dockerignore: Excludes unnecessary files from the Docker build context
Docker Image Features
- Uses the official Bun Docker image for optimal performance
- Properly handles dependencies installation
- Exposes port 8001 for the proxy service
- Configures environment variables for production use
- Includes a health check to ensure the service is running properly
Multi-stage Build
The Dockerfile uses a multi-stage build approach to keep the final image size small and efficient.
Container Security
The Docker configuration follows best practices for container security:
- Uses a specific version of the Bun image rather than 'latest'
- Runs as a non-root user when possible
- Minimizes the number of layers and installed dependencies