ENR = Easy Nginx Redirects
[](https://github.com/pavelsr/enr)
[](https://docs.python.org/3/)
[](https://nginx.org/)
[](https://www.docker.com/)
[](https://opensource.org/licenses/MIT)
[](https://pypi.org/project/enr/)
[](https://t.me/serikoff)
CLI utility for quick & easy generating nginx configuration and running Docker containers with nginx reverse proxy.
Uses only Python standard library without external dependencies. So the utility works immediately after copying files - does not require installation of additional Python packages.
This utility demonstrates the capabilities of nginx's [ngx_http_proxy_module](https://nginx.org/en/docs/http/ngx_http_proxy_module.html) using directives: `proxy_pass`, `proxy_pass_header`, `proxy_intercept_errors`, `proxy_ssl_verify`. These are the specific directives currently implemented, but `ngx_http_proxy_module` module offers many more options. The project serves as an example of a Python wrapper for automatic Docker container configuration and nginx-proxy integration, as well as building Python modules into a single executable script. You can fork this project and customize the nginx and Docker templates for your needs. Pull requests are welcome.
<!-- Created by https://github.com/ekalinin/github-markdown-toc (gh-md-toc README.md)-->
Table of Contents
=================
* [Table of Contents](#table-of-contents)
* [Use Cases](#use-cases)
* [Installation](#installation)
* [Quick Installation](#quick-installation)
* [Other installation ways](#other-installation-ways)
* [Installation from source code](#installation-from-source-code)
* [Notes about pipx](#notes-about-pipx)
* [If GitHub is blocked in your network](#if-github-is-blocked-in-your-network)
* [Usage](#usage)
* [nginx-proxy Compatibility](#nginx-proxy-compatibility)
* [Integration with nginx-proxy](#integration-with-nginx-proxy)
* [Quick nginx-proxy deployment](#quick-nginx-proxy-deployment)
* [Under the Hood](#under-the-hood)
* [Requirements](#requirements)
* [Dependencies](#dependencies)
* [Generated Nginx Configuration](#generated-nginx-configuration)
* [Docker Container Running](#docker-container-running)
* [Features & Roadmap](#features--roadmap)
* [Development & Contributing](#development--contributing)
* [Version Management](#version-management)
* [Versioning F.A.Q.](#versioning-faq)
* [Versioning scheme](#versioning-scheme)
* [Pre-commit Hooks](#pre-commit-hooks)
<!-- Created by https://github.com/ekalinin/github-markdown-toc (gh-md-toc README.md) -->
# Use Cases
- 🐳 **One-click proxying for any local (Dockerized and non-Dockerized) or remote HTTP or HTTPS service**. This tools runs proxy service as single docker container that is convenient to manage. Support docker networks and hostnames, `host.docker.internal` domain
- 🔒 **Secure Access to Any Service**. Make any web service accessible through HTTPS with just one command, even if it doesn't have security certificates
- 🏗️ **Website Constructor Integration**. Free domain binding for website builders like Tilda, Wix, Webflow, etc. Best for fully static sites, forms may require additional configuration
- 🔗 **Custom Subdomain Links**. Create short, easy-to-remember subdomain links using your own domain name instead of generic shortener services
- 😉 **Your Own Everything**. PRs and forks are welcome
# Installation
## Quick Installation
Since it uses only Python standard library without external dependencies you can install it via:
```bash
curl -fsSL --compressed https://raw.githubusercontent.com/pavelsr/enr/main/enr.pyz > /usr/local/bin/enr && \
chmod +x /usr/local/bin/enr
```
or you can install it as regular Python module:
```shell
# pipx (recommended)
pipx install enr # or from GitHub:
pipx install git+https://github.com/pavelsr/enr.git@main
# pip
pip install enr # or from GitHub:
pip install git+https://github.com/pavelsr/enr.git@main
```
## Other installation ways
<details>
<summary>Other installation ways</summary>
### Installation from source code
```bash
git clone https://github.com/pavelsr/enr.git
cd enr
# Run without installation
./enr.py example.com http://localhost:3000
# Editable install (convenient for test and development):
pip install -e .
# Install development dependencies
pip install -e ".[dev]"
# Install using flit in development mode
flit install --symlink
# Creates enr.pyz from modules:
make build # Creates enr.pyz from modules
# Or use flit directly
flit build
```
### Notes about pipx
Since this is a CLI utility, it's recommended to install it using pipx to avoid conflicts with other Python packages:
```bash
# Install pipx if not already installed
python -m pip install --user pipx
python -m pipx ensurepath
# Install ENR
pipx install enr
```
**Advantages of pipx installation:**
- ✅ Isolated environment - no conflicts with other Python packages
- ✅ Easy updates - `pipx upgrade enr`
- ✅ Easy uninstall - `pipx uninstall enr`
- ✅ Global availability - `enr` command available everywhere
### If GitHub is blocked in your network
You can copy the project manually using scp or rsync from a machine where GitHub is NOT blocked:
```bash
# Using scp, only enr.pyz
scp ./enr.pyz user@host.example.com:/usr/local/bin/enr
# Using scp, whole source code
ssh user@host.example.com "mkdir -p ~/enr" && scp -r * user@host.example.com:~/enr/
# Using rsync, whole source code (requires rsync on both machines)
rsync -avz . user@host.example.com:~/enr/
```
**Note**: Replace `user@host.example.com` with your actual server details. The rsync command automatically creates the 'enr' folder if it doesn't exist.
</details>
# Usage
```
usage: enr [-h] [--port PORT] [--container-name CONTAINER_NAME] [--network NETWORK] [--config-dir CONFIG_DIR] [--dry-run] [--force] [--with-letsencrypt] [--version] server_name proxy_pass
positional arguments:
server_name Domain name for the server
proxy_pass Upstream server URL (e.g., http://localhost:3000)
options:
-h, --help show this help message and exit
--port PORT, -p PORT Port to listen on (default: 80)
--container-name CONTAINER_NAME, -n CONTAINER_NAME
Docker container name (defaults to server_name)
--network NETWORK Docker network name (default: nginx-proxy)
--config-dir CONFIG_DIR, -d CONFIG_DIR
Directory to save nginx config (default: current directory)
--dry-run Generate config only, don't run Docker container
--force, -f Force overwrite existing config file
--with-letsencrypt Automatically add Let's Encrypt environment variables for SSL support
--version Show version and exit
Examples:
enr example.com http://<container_name>:3000
enr example.com http://host.docker.internal:8000 --port 3000
enr example.com http://host.docker.internal:8000 --with-letsencrypt
enr shop.example.com https://marketplace.example/seller/<seller_id>
enr example.com https://example.tilda.ws --container-name my-tilda-proxy
enr test.com http://localhost:5000 --dry-run --config-dir ./configs --force
```
## nginx-proxy Compatibility
ENR is specifically designed to work with [nginx-proxy](https://github.com/nginx-proxy/nginx-proxy) - a popular solution for automatic Docker container proxying. ENR automatically:
- Generates compatible nginx configurations
- Runs containers in the `nginx-proxy` network (by default)
- Sets the `VIRTUAL_HOST` environment variable for automatic discovery
- Adds Let's Encrypt variables for SSL certificates when using HTTPS
### Integration with nginx-proxy
```bash
# Start nginx-proxy (if not already running)
docker run -d -p 80:80 -p 443:443 \
--name nginx-proxy \
--restart always \
-v /var/run/docker.sock:/tmp/docker.sock:ro \
nginxproxy/nginx-proxy
# Imagine that you have non-dockerized service running at 8000 port locally
# Using ENR with nginx-proxy
./enr.py example.com http://host.docker.internal:8000
```
### Quick nginx-proxy deployment
For a complete example of nginx-proxy deployment with Let\x27s Encrypt support, see:
**🔗 https://gitlab.com/pavelsr/nginx-proxy**
This repository contains ready-to-use scripts for quick deployment of nginx-proxy with automatic SSL certificate management.
# Under the Hood
Some Technical Overview about Architecture and Implementation Details
## Requirements
- Python 3.11+ (recommended), 3.10+ (minimum)
- Docker
For full functionality, it is recommended to use:
- **[nginx-proxy](https://github.com/nginx-proxy/nginx-proxy)** - automatic Docker container proxying
- **[nginx-proxy-letsencrypt](https://github.com/nginx-proxy/acme-companion)** - automatic Let's Encrypt SSL certificates
## Dependencies
**The project has no external dependencies** - uses only Python standard library:
- `argparse` - command line argument processing
- `pathlib` - file system path operations
- `subprocess` - running Docker commands
- `str.format()` - nginx configuration formatting (instead of jinja2)
- `zipapp` - building single script (instead of stickytape or PyInstaller)
## Generated Nginx Configuration
The utility creates an nginx configuration of the following type:
```nginx
server {
server_name example.com;
listen 80;
location / {
proxy_pass http://localhost:3000;
proxy_pass_header Host;
proxy_intercept_errors on;
error_page 301 302 307 = @handle_redirect;
# recursive_error_pages on;
}
location @handle_redirect {
set $saved_redirect_location '$upstream_http_location';
proxy_pass $saved_redirect_location;
}
}
```
## Docker Container Running
After generating the configuration, the utility runs a Docker container with the command:
```bash
# For HTTP
docker run --network nginx-proxy \
-e VIRTUAL_HOST=example.com \
-v $(pwd)/example.com.proxy.conf:/etc/nginx/conf.d/default.conf \
--name example.com \
-d --restart always nginx:alpine
# For HTTPS (Let's Encrypt variables are automatically added)
docker run --network nginx-proxy \
-e VIRTUAL_HOST=example.com \
-e LETSENCRYPT_HOST=example.com \
-e LETSENCRYPT_EMAIL=443@example.com \
-v $(pwd)/example.com.proxy.conf:/etc/nginx/conf.d/default.conf \
--name example.com \
-d --restart always nginx:alpine
```
# Features & Roadmap
Implemented Features:
- [x] **Easy to use** - one command to set up reverse proxy
- [x] **No external dependencies** - only Python needed (recommended version 3.11)
- [x] **Single script** - can be installed with one curl command, without git/pip/pipx
- [x] **Docker integration** - automatic container running
- [x] **nginx-proxy integration** - nginx-proxy automatically discover containers by `VIRTUAL_HOST`
- [x] **Automatic protocol addition** - automatically adds `http://` to domains without protocol
- [x] **Automatic arguments addition** - automatically adds arguments for support `host.docker.internal`
- [x] **Automatic Let's Encrypt SSL support** - automatically adds environment variables for HTTPS
- [x] **Named configurations** - files are created as `{server_name}.proxy.conf` for better organization
- [x] **Single-source versionin** - `__init__.py`
- [x] **Flit-based build system**
- [x] **Zipapp-based single-file build**
TODO (Roadmap):
- [ ] **Nginx configs as named templates**
- [ ] **More high-level tests**
- [ ] **traefik and other proxy servers integration**
# Development & Contributing
All necessary development commands are available in the Makefile following best practices. To view the complete list of commands, run:
```bash
make help
```
<details>
<summary>Common Makefile commands</summary>
```bash
# Install development dependencies
make install-dev
# Install pre-commit hooks
make pre-commit-install
# Run all checks (formatting, linting, tests)
make check
# Or separately:
make format # Code formatting
make lint # Style checking
make test # Run tests
# Pre-commit hooks
make pre-commit-run # Manual pre-commit hooks run
make pre-commit-clean # Clean pre-commit cache
# Clean temporary files
make clean
```
</details>
## Git Guidelines
Before submitting a PR:
1. **Squash your commits** into a single, meaningful commit. E.g.
```bash
git reset --soft HEAD~42
git commit -m "feat: add new nginx configuration feature"
```
2. **Use descriptive commit messages** that explain what the change does
E.g.
```bash
git commit -m "fix: resolve docker container startup issue (#456)"
```
**Good practice**: Include issue number if one exists (as shown in the example above)
FYI: I prefer [trunk-based development](https://trunkbaseddevelopment.com/) rather than [gitflow branching model](https://nvie.com/posts/a-successful-git-branching-model/)
## Version Management
**To change version ONLY ONE STEP REQUIRED:** Update version in `__init__.py`: `__version__ = "x.y.z"`
**That's it!** All other files automatically get the new version when you run:
- `make build` - builds single script with current version
- `make build-dist` - builds distribution packages with current version
<details>
<summary>Benefits of this approach</summary>
- **Single source of truth**: Version managed in ONE file only (`__init__.py`)
- **Automatic propagation**: All other files automatically get the version from this file
- **Flit dynamic versioning**: Uses flit's built-in `dynamic = ["version"]` feature
- **No git dependency**: Version management works independently of git tags
- **No manual sync needed**: Version is automatically read from module during build
</details>
<details>
<summary>Files that automatically get the version</summary>
```
pyenr/
├── enr/
│ └── init.py # ← MAIN VERSION FILE (change here ONLY)
├── pyproject.toml # ← gets version automatically via flit dynamic
├── setup.py # ← imports version from enr.init (legacy compatibility)
├── enr.pyz # ← single executable script (built via make build)
└── dist/ # ← packages get version automatically
```
</details>
### Versioning F.A.Q.
**Q: How to check current version?**
A: Run `python -c "import enr; print(enr.__version__)"`
**Q: Version didn't update after changing version.py?**
A: Make sure to run `make build` or `make build-dist` after changing the version. Flit will automatically read the new version.
**Q: Flit build failed?**
A: Make sure all files are committed to git, as flit requires a clean git state.
### Versioning scheme
This project follows [Semantic Versioning](https://semver.org/)
## Pre-commit Hooks
The project uses pre-commit hooks for automatic code quality checking before each commit
**What is automatically checked:**
- ✅ Single script build (`make build`)
- ✅ Code formatting (Black)
- ✅ Style checking (ruff)
- ✅ Test running (pytest)
- ✅ Automatic addition of changed `enr.pyz` to commit
Raw data
{
"_id": null,
"home_page": null,
"name": "enr",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.10",
"maintainer_email": null,
"keywords": "nginx, reverse-proxy, docker, cli, devops, proxy, redirect, auto-redirect",
"author": null,
"author_email": "Pavel Serikov <devpasha@proton.me>",
"download_url": "https://files.pythonhosted.org/packages/dd/61/5b1d77583beb725f6f3a66bd9aaa8b2e033bd8bfd802d2c0e8ee8b281b54/enr-0.1.1.tar.gz",
"platform": null,
"description": "ENR = Easy Nginx Redirects\n\n[](https://github.com/pavelsr/enr)\n[](https://docs.python.org/3/)\n[](https://nginx.org/)\n[](https://www.docker.com/)\n[](https://opensource.org/licenses/MIT)\n[](https://pypi.org/project/enr/)\n[](https://t.me/serikoff)\n\nCLI utility for quick & easy generating nginx configuration and running Docker containers with nginx reverse proxy.\n\nUses only Python standard library without external dependencies. So the utility works immediately after copying files - does not require installation of additional Python packages.\n\nThis utility demonstrates the capabilities of nginx's [ngx_http_proxy_module](https://nginx.org/en/docs/http/ngx_http_proxy_module.html) using directives: `proxy_pass`, `proxy_pass_header`, `proxy_intercept_errors`, `proxy_ssl_verify`. These are the specific directives currently implemented, but `ngx_http_proxy_module` module offers many more options. The project serves as an example of a Python wrapper for automatic Docker container configuration and nginx-proxy integration, as well as building Python modules into a single executable script. You can fork this project and customize the nginx and Docker templates for your needs. Pull requests are welcome.\n\n<!-- Created by https://github.com/ekalinin/github-markdown-toc (gh-md-toc README.md)-->\n\nTable of Contents\n=================\n\n* [Table of Contents](#table-of-contents)\n* [Use Cases](#use-cases)\n* [Installation](#installation)\n * [Quick Installation](#quick-installation)\n * [Other installation ways](#other-installation-ways)\n * [Installation from source code](#installation-from-source-code)\n * [Notes about pipx](#notes-about-pipx)\n * [If GitHub is blocked in your network](#if-github-is-blocked-in-your-network)\n* [Usage](#usage)\n * [nginx-proxy Compatibility](#nginx-proxy-compatibility)\n * [Integration with nginx-proxy](#integration-with-nginx-proxy)\n * [Quick nginx-proxy deployment](#quick-nginx-proxy-deployment)\n* [Under the Hood](#under-the-hood)\n * [Requirements](#requirements)\n * [Dependencies](#dependencies)\n * [Generated Nginx Configuration](#generated-nginx-configuration)\n * [Docker Container Running](#docker-container-running)\n* [Features & Roadmap](#features--roadmap)\n* [Development & Contributing](#development--contributing)\n * [Version Management](#version-management)\n * [Versioning F.A.Q.](#versioning-faq)\n * [Versioning scheme](#versioning-scheme)\n * [Pre-commit Hooks](#pre-commit-hooks)\n\n\n<!-- Created by https://github.com/ekalinin/github-markdown-toc (gh-md-toc README.md) -->\n\n# Use Cases\n\n- \ud83d\udc33 **One-click proxying for any local (Dockerized and non-Dockerized) or remote HTTP or HTTPS service**. This tools runs proxy service as single docker container that is convenient to manage. Support docker networks and hostnames, `host.docker.internal` domain\n- \ud83d\udd12 **Secure Access to Any Service**. Make any web service accessible through HTTPS with just one command, even if it doesn't have security certificates\n- \ud83c\udfd7\ufe0f **Website Constructor Integration**. Free domain binding for website builders like Tilda, Wix, Webflow, etc. Best for fully static sites, forms may require additional configuration\n- \ud83d\udd17 **Custom Subdomain Links**. Create short, easy-to-remember subdomain links using your own domain name instead of generic shortener services\n- \ud83d\ude09 **Your Own Everything**. PRs and forks are welcome\n\n# Installation\n\n## Quick Installation\n\nSince it uses only Python standard library without external dependencies you can install it via:\n\n```bash\ncurl -fsSL --compressed https://raw.githubusercontent.com/pavelsr/enr/main/enr.pyz > /usr/local/bin/enr && \\\n chmod +x /usr/local/bin/enr\n```\n\nor you can install it as regular Python module:\n\n```shell\n# pipx (recommended)\npipx install enr # or from GitHub:\npipx install git+https://github.com/pavelsr/enr.git@main\n\n# pip\npip install enr # or from GitHub:\npip install git+https://github.com/pavelsr/enr.git@main\n```\n\n## Other installation ways\n\n<details>\n<summary>Other installation ways</summary>\n\n### Installation from source code\n\n```bash\ngit clone https://github.com/pavelsr/enr.git\ncd enr\n# Run without installation\n./enr.py example.com http://localhost:3000\n# Editable install (convenient for test and development):\npip install -e .\n# Install development dependencies\npip install -e \".[dev]\"\n# Install using flit in development mode\nflit install --symlink\n# Creates enr.pyz from modules:\nmake build # Creates enr.pyz from modules\n# Or use flit directly\nflit build\n```\n\n### Notes about pipx \n\nSince this is a CLI utility, it's recommended to install it using pipx to avoid conflicts with other Python packages:\n\n```bash\n# Install pipx if not already installed\npython -m pip install --user pipx\npython -m pipx ensurepath\n\n# Install ENR\npipx install enr\n```\n\n**Advantages of pipx installation:**\n- \u2705 Isolated environment - no conflicts with other Python packages\n- \u2705 Easy updates - `pipx upgrade enr`\n- \u2705 Easy uninstall - `pipx uninstall enr`\n- \u2705 Global availability - `enr` command available everywhere\n\n### If GitHub is blocked in your network\n\nYou can copy the project manually using scp or rsync from a machine where GitHub is NOT blocked:\n\n```bash\n# Using scp, only enr.pyz\nscp ./enr.pyz user@host.example.com:/usr/local/bin/enr\n\n# Using scp, whole source code\nssh user@host.example.com \"mkdir -p ~/enr\" && scp -r * user@host.example.com:~/enr/\n\n# Using rsync, whole source code (requires rsync on both machines)\nrsync -avz . user@host.example.com:~/enr/\n```\n\n**Note**: Replace `user@host.example.com` with your actual server details. The rsync command automatically creates the 'enr' folder if it doesn't exist.\n\n</details>\n\n\n# Usage\n\n```\nusage: enr [-h] [--port PORT] [--container-name CONTAINER_NAME] [--network NETWORK] [--config-dir CONFIG_DIR] [--dry-run] [--force] [--with-letsencrypt] [--version] server_name proxy_pass\n\npositional arguments:\n server_name Domain name for the server\n proxy_pass Upstream server URL (e.g., http://localhost:3000)\n\noptions:\n -h, --help show this help message and exit\n --port PORT, -p PORT Port to listen on (default: 80)\n --container-name CONTAINER_NAME, -n CONTAINER_NAME\n Docker container name (defaults to server_name)\n --network NETWORK Docker network name (default: nginx-proxy)\n --config-dir CONFIG_DIR, -d CONFIG_DIR\n Directory to save nginx config (default: current directory)\n --dry-run Generate config only, don't run Docker container\n --force, -f Force overwrite existing config file\n --with-letsencrypt Automatically add Let's Encrypt environment variables for SSL support\n --version Show version and exit\n\nExamples:\nenr example.com http://<container_name>:3000\nenr example.com http://host.docker.internal:8000 --port 3000\nenr example.com http://host.docker.internal:8000 --with-letsencrypt\nenr shop.example.com https://marketplace.example/seller/<seller_id>\nenr example.com https://example.tilda.ws --container-name my-tilda-proxy\nenr test.com http://localhost:5000 --dry-run --config-dir ./configs --force\n```\n\n## nginx-proxy Compatibility\n\nENR is specifically designed to work with [nginx-proxy](https://github.com/nginx-proxy/nginx-proxy) - a popular solution for automatic Docker container proxying. ENR automatically:\n\n- Generates compatible nginx configurations\n- Runs containers in the `nginx-proxy` network (by default)\n- Sets the `VIRTUAL_HOST` environment variable for automatic discovery\n- Adds Let's Encrypt variables for SSL certificates when using HTTPS\n\n### Integration with nginx-proxy\n\n```bash\n# Start nginx-proxy (if not already running)\ndocker run -d -p 80:80 -p 443:443 \\\n --name nginx-proxy \\\n --restart always \\\n -v /var/run/docker.sock:/tmp/docker.sock:ro \\\n nginxproxy/nginx-proxy\n\n# Imagine that you have non-dockerized service running at 8000 port locally\n\n# Using ENR with nginx-proxy\n./enr.py example.com http://host.docker.internal:8000\n```\n\n### Quick nginx-proxy deployment\n\nFor a complete example of nginx-proxy deployment with Let\\x27s Encrypt support, see:\n**\ud83d\udd17 https://gitlab.com/pavelsr/nginx-proxy**\n\nThis repository contains ready-to-use scripts for quick deployment of nginx-proxy with automatic SSL certificate management.\n\n# Under the Hood\n\nSome Technical Overview about Architecture and Implementation Details\n\n## Requirements\n\n- Python 3.11+ (recommended), 3.10+ (minimum)\n- Docker\n\nFor full functionality, it is recommended to use:\n\n- **[nginx-proxy](https://github.com/nginx-proxy/nginx-proxy)** - automatic Docker container proxying\n- **[nginx-proxy-letsencrypt](https://github.com/nginx-proxy/acme-companion)** - automatic Let's Encrypt SSL certificates\n\n## Dependencies\n\n**The project has no external dependencies** - uses only Python standard library:\n\n- `argparse` - command line argument processing\n- `pathlib` - file system path operations\n- `subprocess` - running Docker commands\n- `str.format()` - nginx configuration formatting (instead of jinja2)\n- `zipapp` - building single script (instead of stickytape or PyInstaller)\n\n## Generated Nginx Configuration\n\nThe utility creates an nginx configuration of the following type:\n\n```nginx\nserver {\n server_name example.com;\n listen 80;\n\n location / {\n proxy_pass http://localhost:3000;\n proxy_pass_header Host;\n proxy_intercept_errors on;\n error_page 301 302 307 = @handle_redirect;\n # recursive_error_pages on;\n }\n\n location @handle_redirect {\n set $saved_redirect_location '$upstream_http_location';\n proxy_pass $saved_redirect_location;\n }\n}\n```\n\n## Docker Container Running\n\nAfter generating the configuration, the utility runs a Docker container with the command:\n\n```bash\n# For HTTP\ndocker run --network nginx-proxy \\\n -e VIRTUAL_HOST=example.com \\\n -v $(pwd)/example.com.proxy.conf:/etc/nginx/conf.d/default.conf \\\n --name example.com \\\n -d --restart always nginx:alpine\n\n# For HTTPS (Let's Encrypt variables are automatically added)\ndocker run --network nginx-proxy \\\n -e VIRTUAL_HOST=example.com \\\n -e LETSENCRYPT_HOST=example.com \\\n -e LETSENCRYPT_EMAIL=443@example.com \\\n -v $(pwd)/example.com.proxy.conf:/etc/nginx/conf.d/default.conf \\\n --name example.com \\\n -d --restart always nginx:alpine\n```\n\n# Features & Roadmap\n\nImplemented Features:\n\n- [x] **Easy to use** - one command to set up reverse proxy\n- [x] **No external dependencies** - only Python needed (recommended version 3.11)\n- [x] **Single script** - can be installed with one curl command, without git/pip/pipx\n- [x] **Docker integration** - automatic container running\n- [x] **nginx-proxy integration** - nginx-proxy automatically discover containers by `VIRTUAL_HOST`\n- [x] **Automatic protocol addition** - automatically adds `http://` to domains without protocol\n- [x] **Automatic arguments addition** - automatically adds arguments for support `host.docker.internal`\n- [x] **Automatic Let's Encrypt SSL support** - automatically adds environment variables for HTTPS\n- [x] **Named configurations** - files are created as `{server_name}.proxy.conf` for better organization\n- [x] **Single-source versionin** - `__init__.py`\n- [x] **Flit-based build system**\n- [x] **Zipapp-based single-file build**\n\nTODO (Roadmap):\n\n- [ ] **Nginx configs as named templates**\n- [ ] **More high-level tests**\n- [ ] **traefik and other proxy servers integration**\n\n# Development & Contributing\n\nAll necessary development commands are available in the Makefile following best practices. To view the complete list of commands, run:\n\n```bash\nmake help\n```\n\n<details>\n<summary>Common Makefile commands</summary>\n\n\n```bash\n# Install development dependencies\nmake install-dev\n\n# Install pre-commit hooks\nmake pre-commit-install\n\n# Run all checks (formatting, linting, tests)\nmake check\n\n# Or separately:\nmake format # Code formatting\nmake lint # Style checking\nmake test # Run tests\n\n# Pre-commit hooks\nmake pre-commit-run # Manual pre-commit hooks run\nmake pre-commit-clean # Clean pre-commit cache\n\n# Clean temporary files\nmake clean\n```\n</details>\n\n\n## Git Guidelines\n\nBefore submitting a PR:\n\n1. **Squash your commits** into a single, meaningful commit. E.g.\n\n ```bash\n git reset --soft HEAD~42\n git commit -m \"feat: add new nginx configuration feature\"\n ```\n\n2. **Use descriptive commit messages** that explain what the change does\n\n E.g.\n ```bash\n git commit -m \"fix: resolve docker container startup issue (#456)\"\n ```\n\n **Good practice**: Include issue number if one exists (as shown in the example above)\n\nFYI: I prefer [trunk-based development](https://trunkbaseddevelopment.com/) rather than [gitflow branching model](https://nvie.com/posts/a-successful-git-branching-model/)\n\n\n## Version Management\n\n**To change version ONLY ONE STEP REQUIRED:** Update version in `__init__.py`: `__version__ = \"x.y.z\"`\n\n**That's it!** All other files automatically get the new version when you run:\n- `make build` - builds single script with current version\n- `make build-dist` - builds distribution packages with current version\n\n<details>\n<summary>Benefits of this approach</summary>\n\n- **Single source of truth**: Version managed in ONE file only (`__init__.py`)\n- **Automatic propagation**: All other files automatically get the version from this file\n- **Flit dynamic versioning**: Uses flit's built-in `dynamic = [\"version\"]` feature\n- **No git dependency**: Version management works independently of git tags\n- **No manual sync needed**: Version is automatically read from module during build\n</details>\n\n\n<details>\n<summary>Files that automatically get the version</summary>\n\n```\npyenr/\n\u251c\u2500\u2500 enr/\n\u2502 \u2514\u2500\u2500 init.py # \u2190 MAIN VERSION FILE (change here ONLY)\n\u251c\u2500\u2500 pyproject.toml # \u2190 gets version automatically via flit dynamic\n\u251c\u2500\u2500 setup.py # \u2190 imports version from enr.init (legacy compatibility)\n\u251c\u2500\u2500 enr.pyz # \u2190 single executable script (built via make build)\n\u2514\u2500\u2500 dist/ # \u2190 packages get version automatically\n```\n\n</details>\n\n### Versioning F.A.Q.\n\n**Q: How to check current version?**\nA: Run `python -c \"import enr; print(enr.__version__)\"`\n\n**Q: Version didn't update after changing version.py?**\nA: Make sure to run `make build` or `make build-dist` after changing the version. Flit will automatically read the new version.\n\n**Q: Flit build failed?**\nA: Make sure all files are committed to git, as flit requires a clean git state.\n\n### Versioning scheme\n\nThis project follows [Semantic Versioning](https://semver.org/)\n\n## Pre-commit Hooks\n\nThe project uses pre-commit hooks for automatic code quality checking before each commit\n\n**What is automatically checked:**\n- \u2705 Single script build (`make build`)\n- \u2705 Code formatting (Black)\n- \u2705 Style checking (ruff)\n- \u2705 Test running (pytest)\n- \u2705 Automatic addition of changed `enr.pyz` to commit\n\n",
"bugtrack_url": null,
"license": null,
"summary": "CLI utility for easy nginx reverse proxy configuration with automatic redirect handling.",
"version": "0.1.1",
"project_urls": {
"Homepage": "https://github.com/pavelsr/enr",
"Repository": "https://github.com/pavelsr/enr"
},
"split_keywords": [
"nginx",
" reverse-proxy",
" docker",
" cli",
" devops",
" proxy",
" redirect",
" auto-redirect"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "875b1c19c4cc9214a5c47a6b92aedc6a2d36c49414051219b7289e7ad85f1165",
"md5": "e52a36599d12cc71cbe909d9e42d7af5",
"sha256": "8cfd1846265b45bcfc0552ddc2556149b3539aa0d5006976ba1b4a056d813141"
},
"downloads": -1,
"filename": "enr-0.1.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "e52a36599d12cc71cbe909d9e42d7af5",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.10",
"size": 12340,
"upload_time": "2025-09-02T12:08:15",
"upload_time_iso_8601": "2025-09-02T12:08:15.681147Z",
"url": "https://files.pythonhosted.org/packages/87/5b/1c19c4cc9214a5c47a6b92aedc6a2d36c49414051219b7289e7ad85f1165/enr-0.1.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "dd615b1d77583beb725f6f3a66bd9aaa8b2e033bd8bfd802d2c0e8ee8b281b54",
"md5": "080b4dd2949e34fd3de46f8acf1502c7",
"sha256": "61052a8397532598ebaa1c4d6cb5a9f39e2501ac52e90c4a514d4913a5dd9700"
},
"downloads": -1,
"filename": "enr-0.1.1.tar.gz",
"has_sig": false,
"md5_digest": "080b4dd2949e34fd3de46f8acf1502c7",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10",
"size": 19052,
"upload_time": "2025-09-02T12:08:16",
"upload_time_iso_8601": "2025-09-02T12:08:16.920653Z",
"url": "https://files.pythonhosted.org/packages/dd/61/5b1d77583beb725f6f3a66bd9aaa8b2e033bd8bfd802d2c0e8ee8b281b54/enr-0.1.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-09-02 12:08:16",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "pavelsr",
"github_project": "enr",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [],
"lcname": "enr"
}