Skip to content

Commit 7bb04c0

Browse files
Include openssl, cryptography and paramiko in default DockerHub image (#1409)
* Include `openssl` in docker images to let users try TLS interception using dockerhub images * Include `requirements-tunnel.txt` within docker image to let users try tunneling using docker images * Docker is always using py311+, hardcode for now * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Simply `apk add py-cryptography` * --prefer-binary * Build deps for cryptography * make required by pynacl * Prepare to use base image once it has been published * Prepare image from `ghcr.io/abhinavsingh/proxy.py:base` * --no-cache-dir to avoid pip cache bloating * Optimize base image size * Use find * `-y` * Cut final image `FROM python:3.11-alpine` * Remove global setuptools and local pip too * wheel it too * end and flush * Try `42.0.4` in next base * Full path cleanup * SSL in final copy --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent d124d4e commit 7bb04c0

File tree

5 files changed

+60
-27
lines changed

5 files changed

+60
-27
lines changed

.github/workflows/test-library.yml

-2
Original file line numberDiff line numberDiff line change
@@ -952,7 +952,6 @@ jobs:
952952
with:
953953
username: abhinavsingh
954954
password: ${{ secrets.DOCKER_ACCESS_TOKEN }}
955-
# TODO: openssl image is not published on DockerHub
956955
- name: Push to DockerHub
957956
run: >-
958957
REGISTRY_URL="abhinavsingh/proxy.py";
@@ -964,7 +963,6 @@ jobs:
964963
--platform ${{
965964
needs.pre-setup.outputs.container-platforms
966965
}}
967-
--build-arg SKIP_OPENSSL=1
968966
--build-arg PROXYPY_PKG_PATH='dist/${{
969967
needs.pre-setup.outputs.wheel-artifact-name
970968
}}'

Dockerfile

+32-11
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,54 @@
1-
FROM python:3.11-alpine as base
1+
FROM ghcr.io/abhinavsingh/proxy.py:base as builder
22

33
LABEL com.abhinavsingh.name="abhinavsingh/proxy.py" \
4-
com.abhinavsingh.description="⚡ Fast • 🪶 Lightweight • 0️⃣ Dependency • 🔌 Pluggable • \
4+
org.opencontainers.image.title="proxy.py" \
5+
org.opencontainers.image.description="⚡ Fast • 🪶 Lightweight • 0️⃣ Dependency • 🔌 Pluggable • \
56
😈 TLS interception • 🔒 DNS-over-HTTPS • 🔥 Poor Man's VPN • ⏪ Reverse & ⏩ Forward • \
67
👮🏿 \"Proxy Server\" framework • 🌐 \"Web Server\" framework • ➵ ➶ ➷ ➠ \"PubSub\" framework • \
78
👷 \"Work\" acceptor & executor framework" \
8-
com.abhinavsingh.url="https://github.com/abhinavsingh/proxy.py" \
9-
com.abhinavsingh.vcs-url="https://github.com/abhinavsingh/proxy.py" \
9+
org.opencontainers.url="https://github.com/abhinavsingh/proxy.py" \
10+
org.opencontainers.image.source="https://github.com/abhinavsingh/proxy.py" \
1011
com.abhinavsingh.docker.cmd="docker run -it --rm -p 8899:8899 abhinavsingh/proxy.py" \
11-
org.opencontainers.image.source="https://github.com/abhinavsingh/proxy.py"
12+
org.opencontainers.image.licenses="BSD-3-Clause" \
13+
org.opencontainers.image.authors="Abhinav Singh <mailsforabhinav@gmail.com>" \
14+
org.opencontainers.image.vendor="Abhinav Singh"
1215

1316
ENV PYTHONUNBUFFERED 1
17+
ENV PYTHONDONTWRITEBYTECODE 1
1418

1519
ARG SKIP_OPENSSL
1620
ARG PROXYPY_PKG_PATH
1721

1822
COPY README.md /
1923
COPY $PROXYPY_PKG_PATH /
2024

21-
RUN pip install --upgrade pip && \
22-
pip install \
25+
# proxy.py itself needs no external dependencies
26+
# Optionally, include openssl to allow
27+
# users to use TLS interception features using Docker
28+
# Use `--build-arg SKIP_OPENSSL=1` to disable openssl installation
29+
RUN /proxy/venv/bin/pip install --no-compile --no-cache-dir \
30+
-U pip && \
31+
/proxy/venv/bin/pip install --no-compile --no-cache-dir \
2332
--no-index \
2433
--find-links file:/// \
2534
proxy.py && \
26-
rm *.whl
27-
28-
# Use `--build-arg SKIP_OPENSSL=1` to disable openssl installation
29-
RUN if [[ -z "$SKIP_OPENSSL" ]]; then apk update && apk add openssl; fi
35+
rm *.whl && \
36+
find . -type d -name '__pycache__' | xargs rm -rf && \
37+
rm -rf /var/cache/apk/* && \
38+
rm -rf /root/.cache/ && \
39+
/proxy/venv/bin/pip uninstall -y wheel setuptools pip && \
40+
/usr/local/bin/pip uninstall -y wheel setuptools pip
3041

42+
FROM python:3.11-alpine
43+
COPY --from=builder /README.md /README.md
44+
COPY --from=builder /proxy /proxy
45+
RUN if [[ -z "$SKIP_OPENSSL" ]]; then \
46+
apk update && \
47+
apk --no-cache add openssl && \
48+
rm -rf /var/cache/apk/* && \
49+
rm -rf /root/.cache/; \
50+
fi
51+
ENV PATH="/proxy/venv/bin:${PATH}"
3152
EXPOSE 8899/tcp
3253
ENTRYPOINT [ "proxy" ]
3354
CMD [ \

DockerfileBase

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ RUN python -m venv /proxy/venv && \
3333
-U pip wheel && \
3434
/proxy/venv/bin/pip install --no-compile --no-cache-dir \
3535
paramiko==3.4.0 \
36-
cryptography==39.0.1 \
36+
cryptography==42.0.4 \
3737
--prefer-binary && \
3838
apk del .builddeps && \
3939
find . -type d -name '__pycache__' | xargs rm -rf && \

proxy/proxy.py

+26-13
Original file line numberDiff line numberDiff line change
@@ -402,18 +402,27 @@ def _clear_line() -> None:
402402
print('\r' + ' ' * 60, end='', flush=True)
403403

404404
def _env(scheme: bytes, host: bytes, port: int) -> Optional[Dict[str, Any]]:
405-
response = client(
406-
scheme=scheme,
407-
host=host,
408-
port=port,
409-
path=b'/env/',
410-
method=httpMethods.BIND,
411-
body='v={0}&u={1}&h={2}'.format(
412-
__version__,
413-
os.environ.get('USER', getpass.getuser()),
414-
socket.gethostname(),
415-
).encode(),
416-
)
405+
try:
406+
response = client(
407+
scheme=scheme,
408+
host=host,
409+
port=port,
410+
path=b'/env/',
411+
method=httpMethods.BIND,
412+
body='v={0}&u={1}&h={2}'.format(
413+
__version__,
414+
os.environ.get('USER', getpass.getuser()),
415+
socket.gethostname(),
416+
).encode(),
417+
)
418+
except socket.gaierror:
419+
_clear_line()
420+
print(
421+
'\r\033[91mUnable to resolve\033[0m',
422+
end='',
423+
flush=True,
424+
)
425+
return None
417426
if response:
418427
if (
419428
response.code is not None
@@ -445,7 +454,11 @@ def _env(scheme: bytes, host: bytes, port: int) -> Optional[Dict[str, Any]]:
445454
)
446455
else:
447456
_clear_line()
448-
print('\r\033[91mUnable to connect\033[0m')
457+
print(
458+
'\r\033[91mUnable to connect\033[0m',
459+
end='',
460+
flush=True,
461+
)
449462
return None
450463

451464
def _parse() -> Tuple[str, int]:

requirements-tunnel.txt

+1
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ paramiko==3.4.0; python_version >= '3.11'
33
types-paramiko==2.11.3; python_version < '3.11'
44
types-paramiko==3.4.0.20240311; python_version >= '3.11'
55
cryptography==36.0.2; python_version <= '3.6'
6+
cryptography==39.0.1; python_version > '3.6'

0 commit comments

Comments
 (0)