From 5995f72a046da37df0d1bb482302fbd1db877d52 Mon Sep 17 00:00:00 2001 From: bytebraid Date: Wed, 8 Jan 2025 23:46:12 +0000 Subject: [PATCH] Notes, disclaimers and further lampshading in docs --- Dockerfile | 8 ++++---- run.sh | 15 +++++++++++++-- src/app.py | 5 ++++- src/docker-healthcheck.py | 8 ++++++++ src/tools/logs.py | 6 +++++- 5 files changed, 34 insertions(+), 8 deletions(-) diff --git a/Dockerfile b/Dockerfile index a869c65..d849509 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,19 +4,19 @@ WORKDIR /src COPY requirements.txt . -# Install the required Python packages +# Install python dependencies RUN pip install --no-cache-dir -r requirements.txt -# Copy the application code into the container +# Copy the app into the container COPY src . -# Expose the port the app runs on +# Expose the port EXPOSE 11000 # Custom monitoring script to check container health HEALTHCHECK --interval=3m CMD python /src/docker-healthcheck.py -# Command to run the application +# Command to run CMD ["python", "app.py"] # A production setup should use a production server, uvicorn or similar e.g. diff --git a/run.sh b/run.sh index 60c7927..56d9c08 100644 --- a/run.sh +++ b/run.sh @@ -3,6 +3,17 @@ docker stop simple-docker-webapp docker rm simple-docker-webapp docker build -t simple-docker-webapp . -# This is not production ready, Flask is a dev server -# Should use the -u flag to specify a user other than root +# DISCLAIMERS +# This app is not production fit, flask is only a dev server. +# In production the -u flag should specify an appropriate production user ID +# with scoped privileges. +# A restart policy is not specified here, but could be used. YMMV. +# Further considerations for web security / scalability, not exemplified here: +# - Load balancing (appliance or cloud), auto scaling +# - Reverse proxying / Defense-In-Depth / Application Firewalls +# - Container Limits (cgroups / disk quotas etc) +# - Automated container hygiene, log rotation, SIEM tools (splunk etc) +# - Credential vaults / Certificate provisioning / Auto-renewal +# - Caching / Edge services / Cloudflare / Fastly etc +# docker run -d -p 11000:11000 --name simple-docker-webapp simple-docker-webapp \ No newline at end of file diff --git a/src/app.py b/src/app.py index b9dcf1b..8d1422c 100644 --- a/src/app.py +++ b/src/app.py @@ -4,11 +4,14 @@ app = Flask(__name__) PORT = config("PORT", default="11000") -logging = get_logger() +logging = get_logger(Path(__file__).name) @app.route("/hello", methods=["GET"]) def hello_world(): + """Returns a hello string in JSON format. Ideally these docstrings + would be compiled with a documentation tool such as readthedocs.io... + """ logging.info("Hello world called") return jsonify( {"message": "hello world - visit https://github.com/bytebraid/simple-docker-webapp"} diff --git a/src/docker-healthcheck.py b/src/docker-healthcheck.py index 415815a..78c0aa8 100644 --- a/src/docker-healthcheck.py +++ b/src/docker-healthcheck.py @@ -1,3 +1,11 @@ +""" This class does a simple health check and returns a POSIX + status code, 0 if healthy, 1 if the app is not responding + correctly. Docker runs this healthcheck periodically to + ascertain if the container is behaving correctly. It can stop + the container if the healthcheck fails, and restart if + a policy is defined. +""" + import urllib.request import sys from tools.logs import get_logger diff --git a/src/tools/logs.py b/src/tools/logs.py index 04ee278..3921f8b 100644 --- a/src/tools/logs.py +++ b/src/tools/logs.py @@ -17,6 +17,10 @@ def get_logger( LOG_FILE_INFO=str(LOG_INFO), LOG_FILE_ERROR=str(LOG_ERROR), ): + """Returns a custom logger tailored for the calling context + providing precise details of line number and file along + with the message or exception and stack trace. + """ log = logging.getLogger(LOG_NAME) log_formatter = logging.Formatter(LOG_FORMAT) @@ -37,7 +41,7 @@ def get_logger( except Exception: print("Logging to console only") pass - # Dynamic debug switch? + log.setLevel(LOG_LEVEL) return log