From 1423a432838a6612764ccad0f2262379bdd5c994 Mon Sep 17 00:00:00 2001 From: Sascha Cowley <16543535+SaschaCowley@users.noreply.github.com> Date: Wed, 23 Jul 2025 12:02:17 +1000 Subject: [PATCH 01/10] Standardise name of .dockerignore --- .Dockerignore => .dockerignore | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .Dockerignore => .dockerignore (100%) diff --git a/.Dockerignore b/.dockerignore similarity index 100% rename from .Dockerignore rename to .dockerignore From 061ae065f8c05d4baf70df3fc94fd4eabc1b5b1e Mon Sep 17 00:00:00 2001 From: Sascha Cowley <16543535+SaschaCowley@users.noreply.github.com> Date: Wed, 23 Jul 2025 12:03:06 +1000 Subject: [PATCH 02/10] Flesh out docker ignore file --- .dockerignore | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/.dockerignore b/.dockerignore index 6b8710a..03c719b 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1 +1,16 @@ +# Git .git +.gitignore +# Python +.venv/ +__pycache__/ +# Temporary unit testing artefacts +_trial_temp/ +.coverage +*.py,cover +# Docker +.Dockerignore +Dockerfile +compose.yml +# Documentation +readme.md From 1483f5f06642a967a161f5e40c9681ee61f029a0 Mon Sep 17 00:00:00 2001 From: Sascha Cowley <16543535+SaschaCowley@users.noreply.github.com> Date: Wed, 23 Jul 2025 12:56:38 +1000 Subject: [PATCH 03/10] Basic docker config --- Dockerfile | 33 ++++++--------------------------- compose.yml | 5 +++++ docker-compose.yml | 10 ---------- 3 files changed, 11 insertions(+), 37 deletions(-) create mode 100644 compose.yml delete mode 100644 docker-compose.yml diff --git a/Dockerfile b/Dockerfile index f02049c..f93fc6f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,27 +1,6 @@ -FROM ubuntu:focal - -ENV DEBIAN_FRONTEND=noninteractive - -RUN apt-get -y update && apt-get -y upgrade - -RUN apt-get install -y -q tini curl python3 python3-pip - -ENV PYTHONDONTWRITEBYTECODE 1 - -ENV PYTHONUNBUFFERED 1 - -WORKDIR /usr/src/app - -ADD requirements.txt /usr/src/app - -RUN pip3 install --no-cache-dir -r requirements.txt - -ADD . /usr/src/app - -RUN useradd remote - -USER remote - -EXPOSE 6837 - -ENTRYPOINT ["tini", "--", "python3", "server.py", "--certificate=certificate/cert", "--privkey=certificate/key", "--chain=certificate/chain"] +FROM ghcr.io/astral-sh/uv:0.8.2-python3.13-bookworm + +ADD . /app +WORKDIR /app +RUN uv sync --locked +CMD ["uv", "run", "server.py"] diff --git a/compose.yml b/compose.yml new file mode 100644 index 0000000..3887428 --- /dev/null +++ b/compose.yml @@ -0,0 +1,5 @@ +services: + remote_server: + build: . + ports: + - "6837:6837" diff --git a/docker-compose.yml b/docker-compose.yml deleted file mode 100644 index 66f2932..0000000 --- a/docker-compose.yml +++ /dev/null @@ -1,10 +0,0 @@ -version: "3.9" - -services: - remote_server: - build: "." - image: "remote_server:latest" - volumes: - - ./certificate:/usr/src/app/certificate - ports: - - "6837:6837" From 06deaeeb75e47ab9205ef407c753385fd73def26 Mon Sep 17 00:00:00 2001 From: Sascha Cowley <16543535+SaschaCowley@users.noreply.github.com> Date: Wed, 23 Jul 2025 14:48:48 +1000 Subject: [PATCH 04/10] Fix python version pinning --- pyproject.toml | 2 +- uv.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 72883e4..2df927c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ name = "remote-server" version = "0.1.0" description = "NVDA Remote Access remote relay server." readme = "README.md" -requires-python = "~=3.13" +requires-python = "~=3.13.0" dependencies = [ "pyopenssl~=25.1", "service-identity~=24.2", diff --git a/uv.lock b/uv.lock index 4bdfa8a..709b895 100644 --- a/uv.lock +++ b/uv.lock @@ -1,6 +1,6 @@ version = 1 revision = 2 -requires-python = ">=3.13, <4" +requires-python = "==3.13.*" [[package]] name = "attrs" From bfdf409f395440c27ece64a4984c076d0f97fbdf Mon Sep 17 00:00:00 2001 From: Sascha Cowley <16543535+SaschaCowley@users.noreply.github.com> Date: Wed, 23 Jul 2025 14:49:17 +1000 Subject: [PATCH 05/10] Performance improvements to dockerfile --- Dockerfile | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index f93fc6f..a130bf5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,25 @@ FROM ghcr.io/astral-sh/uv:0.8.2-python3.13-bookworm -ADD . /app +# Increases performance, but slows down start-up time +ENV UV_COMPILE_BYTECODE=1 +# Keeps Python from buffering stdout and stderr +# to avoid situations where the application crashes without emitting any logs due to buffering. +ENV PYTHONUNBUFFERED=1 + WORKDIR /app -RUN uv sync --locked + +# Install dependencies +RUN --mount=type=cache,target=/root/.cache/uv \ + --mount=type=bind,source=uv.lock,target=uv.lock \ + --mount=type=bind,source=pyproject.toml,target=pyproject.toml \ + uv sync --locked --no-install-project + +# Copy over the server +COPY . /app + +# Make sure everything is synched +RUN --mount=type=cache,target=/root/.cache/uv \ + uv sync --locked + +# Run the server CMD ["uv", "run", "server.py"] From b6cd1006c16d43720e0cf9bbd811b6c2baa16fc4 Mon Sep 17 00:00:00 2001 From: Sascha Cowley <16543535+SaschaCowley@users.noreply.github.com> Date: Wed, 23 Jul 2025 15:04:04 +1000 Subject: [PATCH 06/10] Switch to alpine --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index a130bf5..d4f3531 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/astral-sh/uv:0.8.2-python3.13-bookworm +FROM ghcr.io/astral-sh/uv:0.8.2-python3.13-alpine # Increases performance, but slows down start-up time ENV UV_COMPILE_BYTECODE=1 From 1a8d1d116fb1eb8e7835097515f87539c3bf25ba Mon Sep 17 00:00:00 2001 From: Sascha Cowley <16543535+SaschaCowley@users.noreply.github.com> Date: Wed, 23 Jul 2025 15:21:58 +1000 Subject: [PATCH 07/10] Add watch support --- compose.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/compose.yml b/compose.yml index 3887428..c7202ae 100644 --- a/compose.yml +++ b/compose.yml @@ -3,3 +3,13 @@ services: build: . ports: - "6837:6837" + develop: + watch: + # Restart whenever code changes are detected + - action: sync+restart + path: . + target: /app + ignore: + - .venv + - action: rebuild + path: ./pyproject.toml From bfcd040ac12f8c8fd1857c23e460b1c5d3308583 Mon Sep 17 00:00:00 2001 From: Sascha Cowley <16543535+SaschaCowley@users.noreply.github.com> Date: Wed, 23 Jul 2025 16:07:29 +1000 Subject: [PATCH 08/10] Don't run as root in docker --- Dockerfile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Dockerfile b/Dockerfile index d4f3531..4283b04 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,8 @@ FROM ghcr.io/astral-sh/uv:0.8.2-python3.13-alpine +RUN addgroup -S remotegroup && adduser -S remoteuser -G remotegroup +USER remoteuser + # Increases performance, but slows down start-up time ENV UV_COMPILE_BYTECODE=1 # Keeps Python from buffering stdout and stderr From 0f4da1d8c5af43390951185872408127c921e25b Mon Sep 17 00:00:00 2001 From: Sascha Cowley <16543535+SaschaCowley@users.noreply.github.com> Date: Wed, 23 Jul 2025 16:32:34 +1000 Subject: [PATCH 09/10] Fixes to watch --- Dockerfile | 13 ++++++++++--- compose.yml | 2 +- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index 4283b04..d69113b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,13 +1,17 @@ FROM ghcr.io/astral-sh/uv:0.8.2-python3.13-alpine -RUN addgroup -S remotegroup && adduser -S remoteuser -G remotegroup -USER remoteuser +# We need to set this here even though it is default, +# because if watch is enabled, this part of the Dockerfile may be re-run as remoteUser +# which doesn't have the necessary permissions to update bind mounts. +USER root # Increases performance, but slows down start-up time ENV UV_COMPILE_BYTECODE=1 # Keeps Python from buffering stdout and stderr # to avoid situations where the application crashes without emitting any logs due to buffering. ENV PYTHONUNBUFFERED=1 +# Copy from the cache instead of linking since it's a mounted volume +ENV UV_LINK_MODE=copy WORKDIR /app @@ -15,7 +19,7 @@ WORKDIR /app RUN --mount=type=cache,target=/root/.cache/uv \ --mount=type=bind,source=uv.lock,target=uv.lock \ --mount=type=bind,source=pyproject.toml,target=pyproject.toml \ - uv sync --locked --no-install-project + uv sync --locked --no-install-project --no-dev # Copy over the server COPY . /app @@ -24,5 +28,8 @@ COPY . /app RUN --mount=type=cache,target=/root/.cache/uv \ uv sync --locked +RUN addgroup -S remotegroup && adduser -S remoteuser -G remotegroup +USER remoteuser +EXPOSE 6837 # Run the server CMD ["uv", "run", "server.py"] diff --git a/compose.yml b/compose.yml index c7202ae..1bd59db 100644 --- a/compose.yml +++ b/compose.yml @@ -12,4 +12,4 @@ services: ignore: - .venv - action: rebuild - path: ./pyproject.toml + path: ./uv.lock From d8836baaaab0e27c157a909cc8a24961a8039f83 Mon Sep 17 00:00:00 2001 From: Sascha Cowley <16543535+SaschaCowley@users.noreply.github.com> Date: Wed, 23 Jul 2025 16:38:52 +1000 Subject: [PATCH 10/10] Update readme --- readme.md | 71 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 38 insertions(+), 33 deletions(-) diff --git a/readme.md b/readme.md index dce6fe1..9920ea1 100644 --- a/readme.md +++ b/readme.md @@ -1,33 +1,38 @@ -# NVDA Remote Server Relay - -This is a simple server used to relay connections for [NVDA Remote](https://nvdaremote.com) - -## Basic Usage - -This is currently only tested on Linux. - -1. [Install uv](https://docs.astral.sh/uv/getting-started/installation/) -2. Obtain your TLS certificates. - - By default, the server looks for the certificate at `./cert`, the private key at `./privkey`, and the chain of trust at `./chain`. - - TBD - update documentation on this/remove this feature in favour of using the web server to handle TLS -3. run the server with `uv run server.py`. - -## Development - -This project uses [pre-commit](https://pre-commit.com/) hooks to help ensure code quality. -These run automatically on pull requests, however it is still recommended to set them up locally. - - -```sh -uvx pre-commit install -``` - -## Docker - -```sh -docker-compose up --build -``` - - -This will expose the server on port 6837, the default. -You must create a folder called certificate along-side the docker-compose.yml which contains the certificate, private key, and root chain named as cert, key, and chain respectively. +# NVDA Remote Server Relay + +This is a simple server used to relay connections for [NVDA Remote](https://nvdaremote.com) + +## Basic Usage + +This is currently only tested on Linux. + +1. [Install uv](https://docs.astral.sh/uv/getting-started/installation/) +2. Obtain your TLS certificates. + - By default, the server looks for the certificate at `./cert`, the private key at `./privkey`, and the chain of trust at `./chain`. + - TBD - update documentation on this/remove this feature in favour of using the web server to handle TLS +3. run the server with `uv run server.py`. + +## Development + +This project uses [pre-commit](https://pre-commit.com/) hooks to help ensure code quality. +These run automatically on pull requests, however it is still recommended to set them up locally. + +```sh +uvx pre-commit install +``` + +## Docker + +To run in Docker, use `docker compose`: + +```sh +docker compose up +``` + +This will expose the server on port 6837, the default. + +The project is pre-configured to support [Compose Watch](https://docs.docker.com/compose/how-tos/file-watch) to make developing in Docker easier. +To enable Watch, either press `w` when `docker compose up` has completed building and starting the container; or run `docker compose watch` to avoid mixing the application and Compose Watch logs. + +* Changes will be synchronised and the server restarted whenever the code changes. +* Changes will be synchronised and the image rebuilt whenever dependencies change.