A tiny Java 17 + Maven project packaged as a Docker image. The image/app refuses to start after a configured expiry date.
- Expiry is enforced twice:
- In
entrypoint.shbefore the JVM starts - In the Java main method at runtime
- In
- Default expiry date is set via
APP_EXPIRY_DATE(ISOYYYY-MM-DD). The default in this repo is2025-12-31.- The Docker image also bakes the expiry into
/app/expiry.date. That baked value is authoritative at start time.
- The Docker image also bakes the expiry into
- Build the JAR:
mvn -q -e -B -DskipTests package- Build the Docker image:
docker build -t expiring-app:1.0.0 .Optionally override default expiry at build time (baked into image via build-arg and stored in /app/expiry.date):
docker build --build-arg APP_EXPIRY_DATE=2025-11-30 -t expiring-app:trial .Note: At runtime, setting
-e APP_EXPIRY_DATE=...cannot extend the baked expiry; the entrypoint prefers the baked/app/expiry.date. If the date format is invalid, the app exits with code 41. When the image is expired, it exits with 42.
If Docker Hub is rate-limiting or blocked for you, use the alternate Dockerfile that pulls from Microsoft Container Registry (MCR):
docker build -f Dockerfile.runtime -t expiring-app:1.0.0 .This uses mcr.microsoft.com/openjdk/jdk:17-ubuntu as the base image.
- Default expiry baked in image:
docker run --rm expiring-app:1.0.0- Override expiry at runtime:
docker run --rm -e APP_EXPIRY_DATE=2025-10-31 expiring-app:1.0.0- Inspect exit code when expired (should be 42):
set +e
docker run --rm -e APP_EXPIRY_DATE=2000-01-01 expiring-app:1.0.0
echo "Exit code: $?"Using Command Prompt (cmd):
docker run --rm expiring-app:1.0.0
docker run --rm -e APP_EXPIRY_DATE=2025-10-31 expiring-app:1.0.0Using PowerShell:
docker run --rm expiring-app:1.0.0
docker run --rm -e APP_EXPIRY_DATE=2025-10-31 expiring-app:1.0.0If expired, container will exit with code 42 and show an error message. Runtime APP_EXPIRY_DATE can only shorten life (e.g., 2000-01-01), not extend beyond the baked date in /app/expiry.date.
entrypoint.shchecksAPP_EXPIRY_DATEagainst current UTC date and exits 42 if past.App.javare-checks the same date at runtime as an additional safeguard.
This is a best-effort control. If a user rebuilds the image and removes the checks, or changes system time inside the container, they could bypass it. For typical distribution use-cases, combine with private registries, short-lived tags, or license servers for stronger controls.
.
├─ pom.xml
├─ Dockerfile
├─ entrypoint.sh
├─ src/main/java/com/example/App.java
└─ .dockerignore