{"id":23674558,"url":"https://github.com/pawel-slowik/docker-containers-proxy","last_synced_at":"2025-08-20T05:20:18.683Z","repository":{"id":267026929,"uuid":"900059881","full_name":"pawel-slowik/docker-containers-proxy","owner":"pawel-slowik","description":"Nginx proxy for Docker containers","archived":false,"fork":false,"pushed_at":"2025-02-19T11:29:12.000Z","size":12,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-19T12:29:46.660Z","etag":null,"topics":["docker","http","nginx","proxy"],"latest_commit_sha":null,"homepage":"","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/pawel-slowik.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":"2024-12-07T18:50:07.000Z","updated_at":"2025-02-19T11:29:15.000Z","dependencies_parsed_at":"2024-12-07T20:17:25.716Z","dependency_job_id":"a617ec7e-e50e-47e7-af8c-b4ead34ce630","html_url":"https://github.com/pawel-slowik/docker-containers-proxy","commit_stats":null,"previous_names":["pawel-slowik/docker-containers-proxy"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pawel-slowik%2Fdocker-containers-proxy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pawel-slowik%2Fdocker-containers-proxy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pawel-slowik%2Fdocker-containers-proxy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pawel-slowik%2Fdocker-containers-proxy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pawel-slowik","download_url":"https://codeload.github.com/pawel-slowik/docker-containers-proxy/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239706972,"owners_count":19683983,"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":["docker","http","nginx","proxy"],"created_at":"2024-12-29T13:27:33.436Z","updated_at":"2025-08-20T05:20:18.678Z","avatar_url":"https://github.com/pawel-slowik.png","language":"Python","readme":"![Build Status][build-badge]\n\n[build-badge]: https://github.com/pawel-slowik/docker-containers-proxy/workflows/tests/badge.svg\n\n\n# Nginx proxy for Docker containers\n\nThis script configures and starts a [nginx](https://nginx.org/) HTTP proxy for\ncurrently running [Docker](https://www.docker.com/) containers.\n\nIt's meant to be used as a tool for exposing the HTTP service from multiple\ncontainers, using host names instead of port numbers to distinguish between\nthem. It's mainly useful in a local development environment with multiple\nunrelated dockerized projects. To aid in this, it provides a simple dashboard\nlisting the exposed containers along with their URLs.\n\n\n## Usage scenario\n\nWhen setting up multiple unrelated projects with docker compose, port conflicts\nare pretty much unavoidable. They can be solved by customizing port numbers in a\n`docker-compose.override.yml` file or via environment variables, if the project\nsupports them. However, this still leaves us with URLs of the form\n`http://127.0.0.1:8080` for one project and `http://127.0.0.1:8081` for another,\nwhich can be easily mixed up. The aim of this project is to replace the URLs\nwith something along the lines of `http://project-one.test` and\n`http://another-project.test`. The included dashboard makes it easier to get an\noverview of running services / projects and to pick the URL of the project we\nare currently working on.\n\n\n## Installation\n\nThere's no packaged version of this script. Clone this repository and call\n`docker_container_proxy.py` with appropriate path.\n\n\n### Requirements\n\nThe script requires Python 3.x to run. Also, since it is designed to be run on\nthe Docker host (not inside a container), the `docker` and `/usr/sbin/nginx`\nbinaries should be callable. Make sure you have installed the relevant packages\nfor your distribution.\n\nThe script does not require root privileges, unless you wish to bind the proxy\nto a privileged port.\n\n\n## Usage\n\nStart the Docker containers for your projects first. Then, run\n`/path/docker_container_proxy.py --dry-run` and verify the generated\nconfiguration. If you wish to customize it, run `/path/docker_container_proxy.py\n--help` and have a look at the available options:\n\n    options:\n      -p PORT    listen on port (default: 8080)\n      -h HOST    proxy host (default: localhost)\n      -d DOMAIN  domain for containers (default: test)\n\nIf you are satisfied with the result, re-run the command without the `--dry-run`\nflag. This will save the generated configuration into a file and start the nginx\nserver. It will also print the proxied URL of each container, along with the URL\nof the dashboard.\n\nPlease note that even though the generated configuration refers to proxied\ncontainers using host names in the `-d` domain, the script does not modify your\nDNS setup in any way. Therefore you'll need to alter your DNS configuration so\nthat the generated host names point to the IP address that the proxy is\nlistening on (most likely `127.0.0.1`).\n\nYou can change the location of the generated files by setting the\n`XDG_DATA_HOME` environment variable.\n\n\n### Example\n\nGiven the following command:\n\n    ./docker_container_proxy.py -p 8080 -h localhost -d docker.test --dry-run\n\nand `docker ps` output:\n\n    CONTAINER ID   IMAGE                      COMMAND                  CREATED          STATUS          PORTS                                       NAMES\n    af1da218c0ca   slim-soap-server-nginx     \"/docker-entrypoint.…\"   56 minutes ago   Up 56 minutes   0.0.0.0:32769-\u003e80/tcp, :::32769-\u003e80/tcp     slim-soap-server-nginx-1\n    58fd11957911   slim-soap-server-php-fpm   \"docker-php-entrypoi…\"   57 minutes ago   Up 56 minutes   9000/tcp                                    slim-soap-server-php-fpm-1\n    d0133fbafe51   districts-nginx            \"/docker-entrypoint.…\"   4 hours ago      Up 2 minutes    0.0.0.0:32770-\u003e80/tcp, :::32770-\u003e80/tcp     districts-nginx-1\n    6150a9101dea   districts-php              \"docker-php-entrypoi…\"   4 hours ago      Up 2 minutes    9000/tcp                                    districts-php-fpm-1\n    5437d3707dd3   phpactor                   \"phpactor language-s…\"   6 hours ago      Up 6 hours      0.0.0.0:4000-\u003e4000/tcp, :::4000-\u003e4000/tcp   upbeat_tharp\n    85d416281770   mariadb:10.5               \"docker-entrypoint.s…\"   7 hours ago      Up 2 minutes    3306/tcp                                    districts-sql-1\n\nthe script will generate the following nginx configuration:\n\n    pid /home/test/.local/share/docker_container_proxy/nginx.pid;\n    error_log /home/test/.local/share/docker_container_proxy/error.log;\n\n    events { }\n\n    http {\n        access_log /home/test/.local/share/docker_container_proxy/access.log;\n\n        server {\n            listen 8080 default_server;\n            server_name _;\n            return 400;\n        }\n\n        server {\n            listen 8080;\n            server_name _dashboard.docker.test;\n            location / {\n                add_header Content-Type text/html;\n                return 200 '\u003c!DOCTYPE html\u003esome generated HTML here...\u003c/html\u003e';\n            }\n        }\n\n        server {\n            listen 8080;\n            server_name slim-soap-server.docker.test;\n            location / {\n                proxy_pass http://localhost:32769;\n            }\n        }\n\n        server {\n            listen 8080;\n            server_name districts.docker.test;\n            location / {\n                proxy_pass http://localhost:32770;\n            }\n        }\n    }\n\nMain points worth noting:\n\n- Only two containers have been proxied, `slim-soap-server-nginx-1` and\n  `districts-nginx-1`, because they are the only ones that run a service on the\n  HTTP port 80 and make it available from outside of the container.\n- The names of the containers have been simplified for use in server names e.g.\n  `slim-soap-server-nginx-1` to `slim-soap-server`.\n- There's a catch-all / default proxy that always responds with a HTTP 400 Bad\n  Request error. This is to make sure that the proxied servers only handle\n  requests that are explicitly targeted at a given server.\n- There's also a simple dashboard listing all the proxied containers with their\n  respective URLs. It can be accessed with the `_dashboard` host name.\n- As mentioned above in the section regarding DNS configuration, the generated\n  host names must be made resolvable, e.g. by manually adding entries to the\n  `/etc/hosts` file:\n\n        127.0.0.1    slim-soap-server.docker.test\n        127.0.0.1    districts.docker.test\n\nAfter re-running the command without the `--dry-run` flag the output will\ninclude URLs of the proxied containers:\n\n    http://_dashboard.docker.test:8080/\n    http://slim-soap-server.docker.test:8080/\n    http://districts.docker.test:8080/\n    configuration saved to /home/test/.local/share/docker_container_proxy/nginx.conf\n    proxy restarted\n\n\n## Alternatives\n\n[Traefik](https://traefik.io/) is a popular solution that can handle this and\nmany more scenarios. An important difference is that Traefik is designed to be\nrun *inside* a container and therefore must share a Docker network with the\nproxied service(s). This script does not have that requirement, but on the other\nhand, since it runs *outside* of a container, the proxied service must be\nexposed to the Docker host (which is not required for Traefik). Basically, this\nscript only handles a single use case and may be used when installing Traefik\nfeels like overkill.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpawel-slowik%2Fdocker-containers-proxy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpawel-slowik%2Fdocker-containers-proxy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpawel-slowik%2Fdocker-containers-proxy/lists"}