Skip to content

Commit 904617e

Browse files
authored
Update defaults for --hostname and --local-executor (#905)
* do it * Change defaults * integrate with ci/cd updates * Fix ci * Add dockerfile `SKIP_OPENSSL` option which will allow us to build container without openssl * Skip openssl for latest tag, add another openssl tag for images with openssl support * Push separate openssl image to GHCR for every PR
1 parent 13c64b5 commit 904617e

File tree

9 files changed

+196
-36
lines changed

9 files changed

+196
-36
lines changed

.github/workflows/test-library.yml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -766,6 +766,7 @@ jobs:
766766
--platform ${{
767767
needs.pre-setup.outputs.container-platforms
768768
}}
769+
--build-arg SKIP_OPENSSL=1
769770
--build-arg PROXYPY_PKG_PATH='dist/${{
770771
needs.pre-setup.outputs.wheel-artifact-name
771772
}}'
@@ -787,6 +788,43 @@ jobs:
787788
--platform ${{
788789
needs.pre-setup.outputs.container-platforms
789790
}}
791+
--build-arg SKIP_OPENSSL=1
792+
--build-arg PROXYPY_PKG_PATH='dist/${{
793+
needs.pre-setup.outputs.wheel-artifact-name
794+
}}'
795+
-t $LATEST_TAG .
796+
- name: Push openssl to GHCR
797+
run: >-
798+
REGISTRY_URL="ghcr.io/abhinavsingh/proxy.py";
799+
CONTAINER_TAG=$REGISTRY_URL:${{
800+
needs.pre-setup.outputs.container-version
801+
}}-openssl;
802+
docker buildx build
803+
--push
804+
--platform ${{
805+
needs.pre-setup.outputs.container-platforms
806+
}}
807+
--build-arg PROXYPY_PKG_PATH='dist/${{
808+
needs.pre-setup.outputs.wheel-artifact-name
809+
}}'
810+
-t $CONTAINER_TAG .
811+
- name: Tag openssl on GHCR
812+
if: >-
813+
github.event_name == 'push' &&
814+
(
815+
github.ref == format(
816+
'refs/heads/{0}', github.event.repository.default_branch
817+
) ||
818+
github.ref == 'refs/heads/master'
819+
)
820+
run: >-
821+
REGISTRY_URL="ghcr.io/abhinavsingh/proxy.py";
822+
LATEST_TAG=$REGISTRY_URL:openssl;
823+
docker buildx build
824+
--push
825+
--platform ${{
826+
needs.pre-setup.outputs.container-platforms
827+
}}
790828
--build-arg PROXYPY_PKG_PATH='dist/${{
791829
needs.pre-setup.outputs.wheel-artifact-name
792830
}}'
@@ -796,6 +834,7 @@ jobs:
796834
with:
797835
username: abhinavsingh
798836
password: ${{ secrets.DOCKER_ACCESS_TOKEN }}
837+
# TODO: openssl image is not published on DockerHub
799838
- name: Push to DockerHub
800839
run: >-
801840
REGISTRY_URL="abhinavsingh/proxy.py";
@@ -807,6 +846,7 @@ jobs:
807846
--platform ${{
808847
needs.pre-setup.outputs.container-platforms
809848
}}
849+
--build-arg SKIP_OPENSSL=1
810850
--build-arg PROXYPY_PKG_PATH='dist/${{
811851
needs.pre-setup.outputs.wheel-artifact-name
812852
}}'

Dockerfile

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
FROM python:3.10-alpine as base
2+
23
LABEL com.abhinavsingh.name="abhinavsingh/proxy.py" \
34
com.abhinavsingh.description="⚡ Fast • 🪶 Lightweight • 0️⃣ Dependency • 🔌 Pluggable • \
45
😈 TLS interception • 🔒 DNS-over-HTTPS • 🔥 Poor Man's VPN • ⏪ Reverse & ⏩ Forward • \
@@ -8,21 +9,24 @@ LABEL com.abhinavsingh.name="abhinavsingh/proxy.py" \
89
com.abhinavsingh.vcs-url="https://github.com/abhinavsingh/proxy.py" \
910
com.abhinavsingh.docker.cmd="docker run -it --rm -p 8899:8899 abhinavsingh/proxy.py" \
1011
org.opencontainers.image.source="https://github.com/abhinavsingh/proxy.py"
12+
1113
ENV PYTHONUNBUFFERED 1
14+
15+
ARG SKIP_OPENSSL
1216
ARG PROXYPY_PKG_PATH
1317

1418
COPY README.md /
1519
COPY $PROXYPY_PKG_PATH /
20+
1621
RUN pip install --upgrade pip && \
1722
pip install \
1823
--no-index \
1924
--find-links file:/// \
2025
proxy.py && \
2126
rm *.whl
2227

23-
# Install openssl to enable TLS interception & HTTPS proxy options within container
24-
# NOTE: You can comment out this line if you don't intend to use those features.
25-
RUN apk update && apk add openssl
28+
# Use `--build-arg SKIP_OPENSSL=1` to disable openssl installation
29+
RUN if [[ -z "$SKIP_OPENSSL" ]]; then apk update && apk add openssl; fi
2630

2731
EXPOSE 8899/tcp
2832
ENTRYPOINT [ "proxy" ]

Makefile

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ endif
3131
.PHONY: lib-release-test lib-release lib-profile lib-doc
3232
.PHONY: lib-dep lib-flake8 lib-mypy lib-speedscope container-buildx-all-platforms
3333
.PHONY: container container-run container-release container-build container-buildx
34-
.PHONY: devtools dashboard dashboard-clean
34+
.PHONY: devtools dashboard dashboard-clean container-without-openssl
3535

3636
all: lib-test
3737

@@ -175,12 +175,15 @@ dashboard-clean:
175175
if [[ -d dashboard/public ]]; then rm -rf dashboard/public; fi
176176

177177
container: lib-package
178-
$(MAKE) container-build -e PROXYPY_PKG_PATH=$$(ls dist/*.whl)
178+
docker build \
179+
-t $(PROXYPY_CONTAINER_TAG) \
180+
--build-arg PROXYPY_PKG_PATH=$$(ls dist/*.whl) .
179181

180-
container-build:
182+
container-without-openssl: lib-package
181183
docker build \
182184
-t $(PROXYPY_CONTAINER_TAG) \
183-
--build-arg PROXYPY_PKG_PATH=$(PROXYPY_PKG_PATH) .
185+
--build-arg SKIP_OPENSSL=1 \
186+
--build-arg PROXYPY_PKG_PATH=$$(ls dist/*.whl) .
184187

185188
# Usage:
186189
#

README.md

Lines changed: 130 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,17 @@
1212
[![Android, Android Emulator](https://img.shields.io/static/v1?label=tested%20with&message=Android%20%F0%9F%93%B1%20%7C%20Android%20Emulator%20%F0%9F%93%B1&color=darkgreen&style=for-the-badge)](https://abhinavsingh.com/proxy-py-a-lightweight-single-file-http-proxy-server-in-python/)
1313
[![iOS, iOS Simulator](https://img.shields.io/static/v1?label=tested%20with&message=iOS%20%F0%9F%93%B1%20%7C%20iOS%20Simulator%20%F0%9F%93%B1&color=darkgreen&style=for-the-badge)](https://abhinavsingh.com/proxy-py-a-lightweight-single-file-http-proxy-server-in-python/)
1414

15-
[![pypi version](https://img.shields.io/pypi/v/proxy.py)](https://pypi.org/project/proxy.py/)
16-
[![Python 3.x](https://img.shields.io/static/v1?label=Python&message=3.6%20%7C%203.7%20%7C%203.8%20%7C%203.9%20%7C%203.10&color=blue)](https://www.python.org/)
17-
[![Checked with mypy](https://img.shields.io/static/v1?label=MyPy&message=checked&color=blue)](http://mypy-lang.org/)
18-
[![lib](https://github.com/abhinavsingh/proxy.py/actions/workflows/test-library.yml/badge.svg?branch=develop&event=push)](https://github.com/abhinavsingh/proxy.py/actions/workflows/test-library.yml)
15+
[![pypi version](https://img.shields.io/pypi/v/proxy.py?style=flat-square)](https://pypi.org/project/proxy.py/)
16+
[![Python 3.x](https://img.shields.io/static/v1?label=Python&message=3.6%20%7C%203.7%20%7C%203.8%20%7C%203.9%20%7C%203.10&color=blue&style=flat-square)](https://www.python.org/)
17+
[![Checked with mypy](https://img.shields.io/static/v1?label=MyPy&message=checked&color=blue&style=flat-square)](http://mypy-lang.org/)
18+
19+
[![doc](https://img.shields.io/readthedocs/proxypy/latest?style=flat-square&color=darkgreen)](https://proxypy.readthedocs.io/)
1920
[![codecov](https://codecov.io/gh/abhinavsingh/proxy.py/branch/develop/graph/badge.svg?token=Zh9J7b4la2)](https://codecov.io/gh/abhinavsingh/proxy.py)
21+
[![lib](https://github.com/abhinavsingh/proxy.py/actions/workflows/test-library.yml/badge.svg?branch=develop&event=push)](https://github.com/abhinavsingh/proxy.py/actions/workflows/test-library.yml)
2022

21-
[![Contributions Welcome](https://img.shields.io/static/v1?label=Contributions&message=Welcome%20%F0%9F%91%8D&color=darkgreen)](https://github.com/abhinavsingh/proxy.py/issues)
22-
[![Need Help](https://img.shields.io/static/v1?label=Need%20Help%3F&message=Ask&color=darkgreen)](https://twitter.com/imoracle)
23-
[![Sponsored by Jaxl Innovations Private Limited](https://img.shields.io/static/v1?label=Sponsored%20By&message=Jaxl%20Innovations%20Private%20Limited&color=darkgreen)](https://github.com/jaxl-innovations-private-limited)
23+
[![Contributions Welcome](https://img.shields.io/static/v1?label=Contributions&message=Welcome%20%F0%9F%91%8D&color=darkgreen&style=flat-square)](https://github.com/abhinavsingh/proxy.py/issues)
24+
[![Need Help](https://img.shields.io/static/v1?label=Need%20Help%3F&message=Ask&color=darkgreen&style=flat-square)](https://twitter.com/imoracle)
25+
[![Sponsored by Jaxl Innovations Private Limited](https://img.shields.io/static/v1?label=Sponsored%20By&message=Jaxl%20Innovations%20Private%20Limited&color=darkgreen&style=flat-square)](https://github.com/jaxl-innovations-private-limited)
2426

2527
# Table of Contents
2628

@@ -93,6 +95,11 @@
9395
- [Inspect Traffic](#inspect-traffic)
9496
- [Chrome DevTools Protocol](#chrome-devtools-protocol)
9597
- [Frequently Asked Questions](#frequently-asked-questions)
98+
- [Deploying proxy.py in production](#deploying-proxypy-in-production)
99+
- [What not to do?](#what-not-to-do)
100+
- [Via Requirements](#via-requirements)
101+
- [Via Docker Container](#via-docker-container)
102+
- [Integrate your CI/CD with proxy.py](#integrate-your-cicd-with-proxypy)
96103
- [Stable vs Develop](#stable-vs-develop)
97104
- [Release Schedule](#release-schedule)
98105
- [Threads vs Threadless](#threads-vs-threadless)
@@ -124,8 +131,12 @@
124131
# Features
125132
- Fast & Scalable
126133

127-
- Scales by using all available cores on the system
134+
- Scale up by using all available cores on the system
135+
- Use `--num-acceptors` flag to control number of cores
136+
128137
- Threadless executions using asyncio
138+
- Use `--threaded` for synchronous thread based execution mode
139+
129140
- Made to handle `tens-of-thousands` connections / sec
130141

131142
```console
@@ -175,35 +186,40 @@
175186
[200] 100000 responses
176187
```
177188

178-
- See [Benchmark](https://github.com/abhinavsingh/proxy.py/tree/develop/benchmark#readme) for more details and how to run them locally.
189+
See [Benchmark](https://github.com/abhinavsingh/proxy.py/tree/develop/benchmark#readme) for more details and for how to run benchmarks locally.
179190

180191
- Lightweight
181-
- Uses `~5-20 MB` RAM
182-
- Compressed containers size is `~18.04 MB`
192+
- Uses only `~5-20 MB` RAM
193+
- No memory leaks
194+
- Start once and forget, no restarts required
195+
- Compressed containers size is only `~25 MB`
183196
- No external dependency other than standard Python library
197+
184198
- Programmable
185199
- Customize proxy behavior using [Proxy Server Plugins](#http-proxy-plugins). Example:
186200
- `--plugins proxy.plugin.ProxyPoolPlugin`
187-
- Optionally, enable builtin [Web Server Plugins](#http-web-server-plugins). Example:
188-
- `--plugins proxy.plugin.ReverseProxyPlugin`
189-
- Plugin API is currently in development phase, expect breaking changes
201+
- Optionally, enable builtin [Web Server](#http-web-server-plugins). Example:
202+
- `--enable-web-server --plugins proxy.plugin.ReverseProxyPlugin`
203+
- Plugin API is currently in *development phase*. Expect breaking changes. See [Deploying proxy.py in production](#deploying-proxypy-in-production) on how to ensure reliability across code changes.
190204
- Real-time Dashboard
191205
- Optionally, enable [proxy.py dashboard](#run-dashboard).
192-
- Available at `http://localhost:8899/dashboard`.
206+
- Use `--enable-dashboard`
207+
- Then, visit `http://localhost:8899/dashboard`
193208
- [Inspect, Monitor, Control and Configure](#inspect-traffic) `proxy.py` at runtime
194209
- [Chrome DevTools Protocol](#chrome-devtools-protocol) support
195-
- Extend dashboard using plugins
196-
- Dashboard is currently in development phase, expect breaking changes
210+
- Extend dashboard frontend using `typescript` based [plugins](https://github.com/abhinavsingh/proxy.py/tree/develop/dashboard/src/plugins)
211+
- Dashboard is currently in *development phase* Expect breaking changes.
197212
- Secure
198213
- Enable end-to-end encryption between clients and `proxy.py`
199214
- See [End-to-End Encryption](#end-to-end-encryption)
200215
- Private
201-
- Everyone deserves privacy. Browse with malware and adult content protection
216+
- Protection against DNS based traffic blockers
217+
- Browse with malware and adult content protection enabled
202218
- See [DNS-over-HTTPS](#cloudflarednsresolverplugin)
203219
- Man-In-The-Middle
204220
- Can decrypt TLS traffic between clients and upstream servers
205221
- See [TLS Interception](#tls-interception)
206-
- Supported proxy protocols
222+
- Supported http protocols for proxy requests
207223
- `http(s)`
208224
- `http1`
209225
- `http1.1` with pipeline
@@ -226,6 +242,8 @@
226242

227243
# Install
228244

245+
Consult [Deploying proxy.py in production](#deploying-proxypy-in-production) when deploying production grade applications using `proxy.py`.
246+
229247
## Using PIP
230248

231249
### Stable Version with PIP
@@ -1738,6 +1756,96 @@ Now point your CDT instance to `ws://localhost:8899/devtools`.
17381756

17391757
# Frequently Asked Questions
17401758

1759+
## Deploying proxy.py in production
1760+
1761+
Listed below are a few strategies for using `proxy.py` in your private/production/corporate projects.
1762+
1763+
### What not to do?
1764+
1765+
> You MUST `avoid forking` the repository *"just"* to put your plugin code in `proxy/plugin` directory. Forking is recommended workflow for project contributors, NOT for project users.
1766+
1767+
Instead, use one of the suggested approaches from below. Then load your plugins using `--plugin`, `--plugins` flags or `plugin` kwargs.
1768+
1769+
### Via Requirements
1770+
1771+
It is *highly* recommended that you use `proxy.py` via `requirements.txt` or similar dependency management setups. This will allow you to take advantages of regular performance updates, bug fixes, security patches and other improvements happening in the `proxy.py` ecosystem. Example:
1772+
1773+
1. Use `--pre` option to depend upon last `pre-release`
1774+
1775+
```console
1776+
❯ pip install proxy.py --pre
1777+
```
1778+
1779+
Pre-releases are similar to depending upon `develop` branch code, just that pre-releases may not point to the `HEAD`. This could happen because pre-releases are NOT made available on `PyPi` after every PR merge.
1780+
1781+
2. Use `TestPyPi` with `--pre` option to depend upon `develop` branch code
1782+
1783+
```console
1784+
❯ pip install -i https://test.pypi.org/simple/ proxy.py --pre
1785+
```
1786+
1787+
A pre-release is made available on `TestPyPi` after every PR merge.
1788+
1789+
3. Use last `stable` release code
1790+
1791+
As usual, simply use:
1792+
1793+
```console
1794+
❯ pip install proxy.py
1795+
```
1796+
1797+
### Via Docker Container
1798+
1799+
If you are into deploying containers, then simply build your image from base `proxy.py` container images.
1800+
1801+
1. Use `GHCR` to build from `develop` branch code:
1802+
1803+
```console
1804+
FROM ghcr.io/abhinavsingh/proxy.py:latest as base
1805+
```
1806+
1807+
*PS: I use GHCR latest for several production level projects*
1808+
1809+
2. Use `DockerHub` to build from last `stable` release code:
1810+
1811+
```console
1812+
FROM abhinavsingh/proxy.py:latest as base
1813+
```
1814+
1815+
PS: IMHO, container based strategy is *the best approach* and the only strategy that *I use myself*.
1816+
1817+
### Integrate your CI/CD with proxy.py
1818+
1819+
*Hey, but you keep making breaking changes in the develop branch.*
1820+
1821+
I hear you. And hence, for your production grade applications, you *MUST* integrate application CI/CD with `proxy.py`. You must make sure that your application builds and passes its tests for every PR merge into the `proxy.py` upstream repo.
1822+
1823+
If your application repository is public, in certain scenarios, PR authors may send patch PRs for all dependents to maintain backward incompatibility and green CI/CD.
1824+
1825+
CI/CD integration ensure your app continues to build with latest `proxy.py` code. Depending upon where you host your code, use the strategy listed below:
1826+
1827+
- GitHub
1828+
1829+
TBD
1830+
1831+
- Google Cloud Build
1832+
1833+
TBD
1834+
1835+
- AWS
1836+
1837+
TBD
1838+
1839+
- Azure
1840+
1841+
TBD
1842+
1843+
- Others
1844+
1845+
TBD
1846+
1847+
> At some stage, we'll deprecate `master` branch segregation and simply maintain a `develop` branch. As dependents can maintain stability via CI/CD integrations. Currently, it's hard for a production grade project to blindly depend upon `develop` branch.
1848+
17411849
## Stable vs Develop
17421850

17431851
- `master` branch contains latest `stable` code and is available via `PyPi` repository and `Docker` containers via `docker.io` and `ghcr.io` registries.
@@ -2123,7 +2231,7 @@ usage: -m [-h] [--enable-events] [--enable-conn-pool] [--threadless]
21232231
[--filtered-url-regex-config FILTERED_URL_REGEX_CONFIG]
21242232
[--cloudflare-dns-mode CLOUDFLARE_DNS_MODE]
21252233

2126-
proxy.py v2.4.0b4.dev12+g19e6881.d20211221
2234+
proxy.py v2.4.0rc5.dev11+ga872675.d20211225
21272235

21282236
options:
21292237
-h, --help show this help message and exit
@@ -2140,7 +2248,7 @@ options:
21402248
handle each client connection.
21412249
--num-workers NUM_WORKERS
21422250
Defaults to number of CPU cores.
2143-
--local-executor Default: False. Disabled by default. When enabled
2251+
--local-executor Default: True. Disabled by default. When enabled
21442252
acceptors will make use of local (same process)
21452253
executor instead of distributing load across remote
21462254
(other process) executors. Enable this option to
@@ -2149,7 +2257,7 @@ options:
21492257
algorithm.
21502258
--backlog BACKLOG Default: 100. Maximum number of pending connections to
21512259
proxy server
2152-
--hostname HOSTNAME Default: ::1. Server IP address.
2260+
--hostname HOSTNAME Default: 127.0.0.1. Server IP address.
21532261
--port PORT Default: 8899. Server port.
21542262
--unix-socket-path UNIX_SOCKET_PATH
21552263
Default: None. Unix socket path to use. When provided

docs/spelling_wordlist.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ faq
1313
html
1414
http
1515
https
16+
integrations
1617
iterable
18+
pre
1719
readables
1820
scm
1921
sexualized

proxy/common/constants.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ def _env_threadless_compliant() -> bool:
120120
DEFAULT_STATIC_SERVER_DIR = os.path.join(PROXY_PY_DIR, "public")
121121
DEFAULT_MIN_COMPRESSION_LIMIT = 20 # In bytes
122122
DEFAULT_THREADLESS = _env_threadless_compliant()
123-
DEFAULT_LOCAL_EXECUTOR = False
123+
DEFAULT_LOCAL_EXECUTOR = True
124124
DEFAULT_TIMEOUT = 10.0
125125
DEFAULT_VERSION = False
126126
DEFAULT_HTTP_PORT = 80

0 commit comments

Comments
 (0)