{"id":13655186,"url":"https://github.com/nhumrich/small-prox","last_synced_at":"2025-07-26T06:14:42.921Z","repository":{"id":23307655,"uuid":"98681456","full_name":"nhumrich/small-prox","owner":"nhumrich","description":"A small local reverse proxy (such as nginx/haproxy) for routing to many local docker containers.","archived":false,"fork":false,"pushed_at":"2023-11-24T19:14:41.000Z","size":67,"stargazers_count":14,"open_issues_count":0,"forks_count":3,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-12T12:30:02.901Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nhumrich.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}},"created_at":"2017-07-28T19:32:47.000Z","updated_at":"2024-02-22T16:44:55.000Z","dependencies_parsed_at":"2023-11-24T20:24:18.697Z","dependency_job_id":"ee5c01b8-4d00-4c3d-8f0b-2ccfa95bd16f","html_url":"https://github.com/nhumrich/small-prox","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/nhumrich/small-prox","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nhumrich%2Fsmall-prox","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nhumrich%2Fsmall-prox/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nhumrich%2Fsmall-prox/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nhumrich%2Fsmall-prox/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nhumrich","download_url":"https://codeload.github.com/nhumrich/small-prox/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nhumrich%2Fsmall-prox/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267127948,"owners_count":24040154,"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","status":"online","status_checked_at":"2025-07-26T02:00:08.937Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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-08-02T03:00:59.264Z","updated_at":"2025-07-26T06:14:42.897Z","avatar_url":"https://github.com/nhumrich.png","language":"Python","funding_links":[],"categories":["Architecture"],"sub_categories":[],"readme":"\n# Small-Prox\n\u003cimg src=\"https://github.com/nhumrich/small-prox/assets/4661889/c4c96489-ffb0-4d5f-8b3c-2981faddebc8\" width=\"450\"/\u003e\n\nA small local reverse proxy (such as nginx/haproxy) for handling many local docker containers.\n\nThis proxy routes traffic to specific containers based on host or path.\nIt also allows you to route traffic to local ports, in case you're not\nusing docker for some services (common for local dev).\n\nAll configuration is done via docker/docker-compose and you do not need a seperate config file.\n\nThis proxy is intended to route traffic to specific services much like the\nload balancer would on a real environment (production). It helps develop locally.\n\n**Note: This proxy/project is intended to ease local development. There is no\nsecurity/performance considerations made at all. I do not recommend using this\nto route traffic anywhere except locally.**\n\n# How does it work?\nThe container listens on the docker socket and watches for containers to start up.\nThe containers have a label that specifies what host and path they want\nto handle traffic for, and this proxy sends it to them on those conditions.\n\nFor local forwarding, the container finds the host ip address and forwards there. For Docker on Mac (or windows), this is a dns address, but for linux its in the containers ip tables.\n\n# Getting started\n\nTo run the container simply use:\n\n```bash\ndocker run -d -p 80:80 -v /var/run/docker.sock:/var/run/docker.sock nhumrich/small-prox\n```\n\nor use docker-compose compose.yaml file:\n```yaml\nservices:\n  smallprox:\n    image: nhumrich/small-prox\n    ports:\n      - \"80:80\"\n    volumes:\n      - /var/run/docker.sock:/var/run/docker.sock\n```\n\n## Real World Example:\nLet's say you have a frontend site running at `localhost:3000` and a backend site running at `localhost:8080`. Don't forget to also add `127.0.0.1 mysite.local` to your /etc/hosts file.\n```yaml\nservices:\n  smallprox:\n    image: nhumrich/small-prox\n    ports:\n      - \"80:80\"\n    volumes:\n      - /var/run/docker.sock:/var/run/docker.sock\n    environment:\n      LOCAL_PORTS: \"mysite.local=3000,mysite.local/api=8080\"\n```\n\n### Forwarding to docker containers\nStart your container with a label:\n\n```bash\ndocker run -l proxy_expose=myapp.myhost.local=8080 myorg/mycontainer\n```\n\nThe format is:\n`proxy_expose={host}/{path}={port container listens on}`\n\nIf you are doing host based networking, you will need to add the hosts in your\n/etc/hosts file pointing to 127.0.0.1 or use an actual dns record that resolves\nto 127.0.0.1\n\n### Forwarding to local ports\nIf you would like to forward traffic to local ports, you can do this by setting\nenvironment variables on the small-prox container before you start it.\n\nThe environment variable is `LOCAL_PORTS` and excepts a comma-separated list of \nstrings in the format of `{host}/{path}={port}`.\n\n\n## Full list of config options\n\n### LOCAL_PORTS\n\nYou can send traffic to things running locally using the `LOCAL_PORTS` environment variable on the small-prox container.\nThis is a comma-seperated string. This setting always takes priority over any other settings.\nIf you have containers mapped to specific hosts or paths, the local_port always wins.\n\nSome examples:\n\n`LOCAL_PORTS: \"mysite.local=3000,mysite.local/api=8080\"` This Routes all traffic to mysite.local to \nport 3000 locally. It also routes traffic starting with `/api` to port 8080 instead.\n\n`LOCAL_PORTS: \"/=8000,/api=8080,/static=3000` This routes all traffic on _any host_ including localhost to port 8000.\nIf the path starts with `api` it will go to port 8080 instead, and likewise, all paths starting with static will go to 3000\n\n`LOCAL_PORTS: \"/api=8080,mysite.local/api=8181` This will route all traffic on _any host_ including localhost to port 8080 as \nlog as it starts with the `api` path prefix. However, if the host is specifically `mysite.local` it will go to port 8181 instead.\n\n### LOCAL_ADDRESS\n\nWhen running on Docker for Mac/Windows, docker adds some dns to allow this container to talk to the host.\nSometimes, that address is wrong (Typically when running docker inside WSL2 without using Docker for Windows)\n\nThis environment variable allows one to override the typical resolution IP address for \"local\" and use this instead.\nIf you have connection issues for `LOCAL_PORTS`, you could play around with this. \nIf you are using docker-compose, you could potentially add your own override.yaml file so that the setting applies only to you:\n\n```yaml\nservices:\n    proxy:\n        environment:\n            LOCAL_ADDRESS: '172.21.0.1'\n```\n\n### REMOTE_PORTS:\n\nThis environment variable is very similar to `LOCAL_PORTS` except that it sends traffic to anywhere, even potentially a remote address.\nThe proxy will rewrite the host header so that the receiving server does not know the original host used.\nTypically, this is needed when you want something like `service.local` to point to a remote service `myservice.example.com`.\nIt is a great feature for taking local-dependencies and moving them to the cloud.\nFor `LOCAL_PORTS` the right side of the `=` is a port, but for REMOTE_PORTS its a fully qualified url.\n\nExamples:\n\n`REMOTE_PORTS: \"/api=staging.example.com,myservice.local=123.123.123.123:8181`\n\n### DEBUG\n\nSetting `DEBUG=true` will make the proxy give you debug logs. Useful for debugging networking issues.\nIt should tell you what all the registered host-port mappings are, and also print out all incoming requests, and where it wants to send them.\n\n### NO_HTTPS_REDIRECT\n\nIf you are using ssl certificates, then the proxy will automatically redirect any http calls to https.\nIf you would like to disable the https redirect, you can set this: `NO_HTTPS_REDIRECT=true`, which disables it.\n\n### Container Ports\n\nThis is not configurable via environment variables, but instead via labels. You can have small-prox\nsend traffic to a specific container by adding a label to that container. Small prox reads docker labels\nto know which containers to send traffic too.\n\nAn example for docker compose:\n```yaml\nservices:\n  backend:\n    image: myorg/myimage\n    labels:\n      proxy_expose: local.example.com/api=8008\n\n```  \nThis will route all traffic from local.example.com that is prefixed with the `api` path, to this container on port 8008.\n\n### Intercept docker traffic\n\nSmall-prox is great for intercepting local traffic, such as local-host, and sending it wherever. (a container, a local service, etc.)\nBut its also useful for sending traffic that originates from a container! In order to do that, you need to tell docker to intercept \ntraffic for the host.\nYou can do that by adding network aliases. \n\nA full example in docker-compose:\n```yaml\nservices:\n  smallprox:\n    image: nhumrich/small-prox\n    ports:\n      - \"80:80\"\n    volumes:\n      - /var/run/docker.sock:/var/run/docker.sock\n    environment:\n      LOCAL_PORTS: \"mysite.local=3000,mysite.local/api=8080\"\n    networks:\n      default:\n        aliases:\n         - mysite.local\n```\n\nNow another container will go to small-prox when it calls `mysite.local`, which will then in turn end up in your local container.\n\n# FAQ\n \n### Can I use this in prod?\nI mean, you *could*, but I dont recommend it.\n\n### Does it support ssl?\nSure does! You just need to port forward port 443 as well, and also drop a `fullchain.pem` and `privkey.pem` file into\nthe `/certs/` directory in the container and ssl will work. You could either volume mount these in\nor build your own container on top of this one. The file names are the names letsencrypt uses. \n You could use self-signed certs, or you could create a DNS name that points to 127.0.0.1 and use dns\n validation to get a lets encrypt cert for your local dev.\n \n### Why did you build this? Why not just use jwilder/nginx-proxy (or similar)?\nThere are a couple reasons. `jwilder/nginx-proxy` is excellent but it only does\n host routing. I wanted path based routing as well. Also, I wanted to be able to\n route to local ports, for when i'm debugging locally and dont want to run my service inside a container.\n \nAnother possibility is just use nginx by itself. This works great until you want to change things, such\nas where a service is or what path/port it listens to. I was using a custom nginx image at my\norganization, but ended up having many many versions of it for all the different configurations\npeople wanted. I found that I wanted the \"configuration\" outside of the container, and \nin the persons repo. So, here is something a little more dynamic, and loads configuration from other places \n(docker labels). Plus, now that its in python, it gives me more flexibility to add things in the future\nif I want.z\n\n### Does this use nginx/similar under the hood?\nNo. This project is written entirely in python. I had thought of just implementing it by\nlooking for docker changes, updating the nginx configuration and restarting nginx.\nThe amount of work (not much) to do that, is about the same to just listen to http and \nforward packets. I decided to do it entirely in python as a learning experience for myself.\nSince the project is intended for local development only, I am not concerned about\nsecurity/performance issues. \nThat being said, this project uses asyncio and one of python's fastest http parsers, so you\nshouldn't notice any slowness from it. \n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnhumrich%2Fsmall-prox","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnhumrich%2Fsmall-prox","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnhumrich%2Fsmall-prox/lists"}