diff --git a/Dockerfile b/Dockerfile
index 81ed93b..b3ed324 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,6 +1,6 @@
# syntax=docker/dockerfile:1
-FROM ghcr.io/linuxserver/baseimage-alpine:3.19
+FROM ghcr.io/linuxserver/baseimage-alpine:3.21
# set version label
ARG BUILD_DATE
@@ -17,7 +17,7 @@ ENV PYTHONIOENCODING=utf-8 \
VIRTUAL_ENV=/pyenv \
PATH="/pyenv/bin:$PATH"
-RUN \
+RUN --mount=type=bind,source=/patch,target=/patch \
apk add --no-cache --update --virtual=build-dependencies \
build-base \
git \
@@ -34,7 +34,9 @@ RUN \
setuptools \
wheel && \
pip install -U --no-cache-dir pytz && \
- pip install -U --no-cache-dir --find-links https://wheel-index.linuxserver.io/alpine-3.19 -r /home/py-kms/requirements.txt && \
+ pip install -U --no-cache-dir --find-links https://wheel-index.linuxserver.io/alpine-3.21 -r /home/py-kms/requirements.txt && \
+ patch /home/py-kms/pykms_PidGenerator.py < /patch/pykms_PidGenerator.patch && \
+ patch /home/py-kms/KmsDataBase.xml < /patch/KmsDataBase.patch && \
printf "Version: ${VERSION}\nBuild-date: ${BUILD_DATE}" > /build_version && \
apk del --purge \
build-dependencies && \
diff --git a/README.md b/README.md
index 8e57bdb..dcc40d4 100644
--- a/README.md
+++ b/README.md
@@ -32,14 +32,22 @@ The architectures supported by this image are:
More info at [py-kms](https://github.com/Py-KMS-Organization/py-kms).
+## Read-Only Operation
+
+This image can be run with a read-only container filesystem.
+
+Running the container read-only requires mounting `/run` to tmpfs with the `exec` flag.
+
+## Non-Root Operation
+
+This image can be run with a non-root user.
+
## Usage
Here are some example snippets to help you get started creating a container.
### docker-compose ([recommended](https://docs.linuxserver.io/general/docker-compose))
-Compatible with docker-compose v2 schemas.
-
```yaml
---
services:
@@ -104,12 +112,55 @@ In this instance `PUID=1000` and `PGID=1000`, to find yours use `id user` as bel
* Shell access whilst the container is running: `docker exec -it py-kms /bin/bash`
* To monitor the logs of the container in realtime: `docker logs -f py-kms`
+## Updating Info
+
+Most of our images are static, versioned, and require an image update and container recreation to update the app inside. We do not recommend or support updating apps inside the container. Please consult the [Application Setup](#application-setup) section above to see if it is recommended for the image.
+
+Below are the instructions for updating containers:
+
+### Via Docker Compose
+
+* Update all images: `docker-compose pull`
+ * or update a single image: `docker-compose pull py-kms`
+* Let compose update all containers as necessary: `docker-compose up -d`
+ * or update a single container: `docker-compose up -d py-kms`
+* You can also remove the old dangling images: `docker image prune`
+
+### Via Docker Run
+
+* Update the image: `docker pull ghcr.io/thespad/py-kms`
+* Stop the running container: `docker stop py-kms`
+* Delete the container: `docker rm py-kms`
+* Recreate a new container with the same docker run parameters as instructed above (if mapped correctly to a host folder, your `/config` folder and settings will be preserved)
+* You can also remove the old dangling images: `docker image prune`
+
### Image Update Notifications - Diun (Docker Image Update Notifier)
-* We recommend [Diun](https://crazymax.dev/diun/) for update notifications. Other tools that automatically update containers unattended are not recommended or supported.
+>[!TIP]
+>We recommend [Diun](https://crazymax.dev/diun/) for update notifications. Other tools that automatically update containers unattended are not recommended or supported.
+
+## Building locally
+
+If you want to make local modifications to these images for development purposes or just to customize the logic:
+
+```shell
+git clone https://github.com/thespad/docker-py-kms.git
+cd docker-py-kms
+docker build \
+ --no-cache \
+ --pull \
+ -t ghcr.io/thespad/py-kms:latest .
+```
+
+The arm variants can be built on x86_64 hardware and vice versa using `lscr.io/linuxserver/qemu-static`
+
+```bash
+docker run --rm --privileged lscr.io/linuxserver/qemu-static --reset
+```
## Versions
+* **02.02.25:** - Rebase to Alpine 3.21. Patch support for Python 3.21.
* **13.11.24:** - Revert to Alpine 3.19 & Python 3.11 to fix bug with Win 11 and Office activations.
* **26.05.24:** - Rebase to Alpine 3.20.
* **30.12.23:** - Rebase to Alpine 3.19.
diff --git a/patch/KmsDataBase.patch b/patch/KmsDataBase.patch
new file mode 100644
index 0000000..6b5dfeb
--- /dev/null
+++ b/patch/KmsDataBase.patch
@@ -0,0 +1,47 @@
+--- KmsDataBase.xml 2025-02-02 14:24:00.000000000 +0000
++++ KmsDataBase.xml_new.xml 2025-02-02 14:31:01.359088569 +0000
+@@ -103,10 +103,22 @@
+
+
+
+-
++
++
++
++
++
++
++
++
++
+
+
+
++
++
++
++
+
+
+
+@@ -568,8 +580,19 @@
+
+
+
+-
++
++
++
++
++
++
++
++
++
+
++
++
++
+
+
+
diff --git a/patch/pykms_PidGenerator.patch b/patch/pykms_PidGenerator.patch
new file mode 100644
index 0000000..75fe192
--- /dev/null
+++ b/patch/pykms_PidGenerator.patch
@@ -0,0 +1,10 @@
+--- /home/py-kms/pykms_PidGenerator.py
++++ /home/py-kms/pykms_PidGenerator_patched.py
+@@ -59,7 +59,7 @@
+ minTime = datetime.date(d.year, d.month, d.day)
+
+ # Generate Year and Day Number
+- randomDate = datetime.date.fromtimestamp(random.randint(time.mktime(minTime.timetuple()), time.mktime(datetime.datetime.now().timetuple())))
++ randomDate = datetime.date.fromtimestamp(random.randint(int(time.mktime(minTime.timetuple())), int(time.mktime(datetime.datetime.now().timetuple()))))
+ firstOfYear = datetime.date(randomDate.year, 1, 1)
+ randomDayNumber = int((time.mktime(randomDate.timetuple()) - time.mktime(firstOfYear.timetuple())) / 86400 + 0.5)