From a29057c6a0b5a4fa7ac7399c1e1b09b274cebecd Mon Sep 17 00:00:00 2001 From: Nat Hough Date: Sat, 20 Dec 2025 16:49:34 +0000 Subject: [PATCH 1/5] first "working" container - it runs and doesn't immediately fall over, but the website doesn't load yet. --- Dockerfile | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 Dockerfile diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..286df81 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,14 @@ +# syntax=docker/dockerfile:1 + +FROM python:latest +# WORKDIR /app +COPY . . +# RUN apt-get update && apt-get install -y python3.11 python3-pip +ENV PIP_ROOT_USER_ACTION=ignore +RUN pip install -r requirements.txt +ENV FLASK_APP hackspace_website:create_app +ENV FLASK_ENV development +EXPOSE 5000 +CMD ["flask"] +#ENTRYPOINT ["flask run"] + From 23c81ee898f57bcd359afee19e47f0be93bd71ad Mon Sep 17 00:00:00 2001 From: Nat Hough Date: Sun, 21 Dec 2025 09:53:49 +0000 Subject: [PATCH 2/5] various changes --- Dockerfile | 4 ++-- docker-compose.yml | 16 ++++++++++++++++ nginx/nginx.conf | 13 +++++++++++++ 3 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 docker-compose.yml create mode 100644 nginx/nginx.conf diff --git a/Dockerfile b/Dockerfile index 286df81..cb5668c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,6 +9,6 @@ RUN pip install -r requirements.txt ENV FLASK_APP hackspace_website:create_app ENV FLASK_ENV development EXPOSE 5000 -CMD ["flask"] -#ENTRYPOINT ["flask run"] +#CMD ["flask"] +ENTRYPOINT ["flask", "run", "--host=0.0.0.0"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..c6ed971 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,16 @@ +version: "3" +services: + website: + build: + context: . + ports: + - "5000:5000" + nginx: + image: nginx:alpine + volumes: + - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro + depends_on: + - website + ports: + - "9000:80" + diff --git a/nginx/nginx.conf b/nginx/nginx.conf new file mode 100644 index 0000000..de37656 --- /dev/null +++ b/nginx/nginx.conf @@ -0,0 +1,13 @@ +events { + worker_connections 1024; +} +http{ + server{ + server_name website; + listen 80; + location / { + proxy_pass http://website:5000; + + } + } +} From eeb27b43df95ae251aac279a1e0d173cafe7407f Mon Sep 17 00:00:00 2001 From: Nat Hough Date: Wed, 24 Dec 2025 17:06:01 +0000 Subject: [PATCH 3/5] quick change to init.py in case we need postgresql instance attached. --- hackspace_website/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/hackspace_website/__init__.py b/hackspace_website/__init__.py index 6849b81..fd44365 100644 --- a/hackspace_website/__init__.py +++ b/hackspace_website/__init__.py @@ -136,6 +136,7 @@ def create_app(test_config=None): app = Flask(__name__, instance_relative_config=True) app.config.from_mapping( SQLALCHEMY_DATABASE_URI="postgresql+psycopg2://postgres:postgres@localhost:5432/website", + # Does the website rely on our internal postgresql instance? if so, change from localhost MESSAGE_RATELIMIT_WINDOW=timedelta(minutes=10).total_seconds(), MESSAGE_RATELIMIT_COUNT=3, RECOMMENDED_PAYMENT_URL="http://example.com/recommended", From f4857833ea51dd339976eeaf46f7a2e52f0935c5 Mon Sep 17 00:00:00 2001 From: Nat Hough Date: Thu, 1 Jan 2026 18:32:55 +0000 Subject: [PATCH 4/5] add ssl, gitignore, draft quadlets --- .config/containers/systemd/nginx.container | 19 ++++++++++++++ .config/containers/systemd/website.container | 15 +++++++++++ .gitignore | 5 ++++ Dockerfile | 2 +- README.md | 15 +++++++++++ docker-compose.yml | 4 ++- nginx/.ssl/.gitkeep | 1 + nginx/nginx.conf | 27 +++++++++++++++----- 8 files changed, 80 insertions(+), 8 deletions(-) create mode 100644 .config/containers/systemd/nginx.container create mode 100644 .config/containers/systemd/website.container create mode 100644 nginx/.ssl/.gitkeep diff --git a/.config/containers/systemd/nginx.container b/.config/containers/systemd/nginx.container new file mode 100644 index 0000000..8cf6fdf --- /dev/null +++ b/.config/containers/systemd/nginx.container @@ -0,0 +1,19 @@ +[Unit] +Description=Hackspace web proxy +#After=website.container +#Requires=website.container + +[Container] +ContainerName=HSNginx +Image=nginx:alpine +Volume=/srv/nginx/nginx.conf:/etc/nginx/nginx.conf +Volume=./nginx/.ssl:/etc/nginx/.ssl:ro +PublishPort=8080:80 +PublishPort=8443:443 + +[Service] +Restart=always + +[Install] +WantedBy=default.target + diff --git a/.config/containers/systemd/website.container b/.config/containers/systemd/website.container new file mode 100644 index 0000000..2d5d146 --- /dev/null +++ b/.config/containers/systemd/website.container @@ -0,0 +1,15 @@ +[Unit] +Description=Hackspace Website + +[Container] +ContainerName=HSWeb +Image=localhost/website +UserNS=keep-id +PublishPort=5000:5000 + +[Service] +Restart=always + +[Install] +WantedBy=default.target + diff --git a/.gitignore b/.gitignore index fdbd8f9..5739fa9 100644 --- a/.gitignore +++ b/.gitignore @@ -162,3 +162,8 @@ cython_debug/ #.idea/ .bash_history .python_history + +# Certificates count as secrets so shouldn't go on Git. +*.key +*.crt +*.pem \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index cb5668c..afa1836 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ # syntax=docker/dockerfile:1 -FROM python:latest +FROM python:slim # WORKDIR /app COPY . . # RUN apt-get update && apt-get install -y python3.11 python3-pip diff --git a/README.md b/README.md index 1571402..4b9bc3c 100644 --- a/README.md +++ b/README.md @@ -116,3 +116,18 @@ WARNING: This is a development server. Do not use it in a production deployment. ``` With the server running, in a browser navigate to: http://127.0.0.1:5000 + + +# Container! + +You can stand up the container with `podman-compose up --build` + +you'll need ssl certs if you want to use ssl (and don't have them set up for your dev environment yet). I do NOT recommend using this in production - HS already has a working certificate process. +``` +# Interactive +openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 365 -subj '/CN=localhost' -nodes + +# Non-interactive and 10 years expiration +openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 3650 -nodes -subj "/C=XX/ST=StateName/L=CityName/O=CompanyName/OU=CompanySectionName/CN=CommonNameOrHostname" +``` +https://stackoverflow.com/questions/10175812/how-can-i-generate-a-self-signed-ssl-certificate-using-openssl \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index c6ed971..79b4137 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -8,9 +8,11 @@ services: nginx: image: nginx:alpine volumes: - - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro + - ./nginx/nginx.conf:/etc/nginx/nginx.conf # :ro + - ./nginx/.ssl:/etc/nginx/.ssl:ro depends_on: - website ports: - "9000:80" + - "9443:443" diff --git a/nginx/.ssl/.gitkeep b/nginx/.ssl/.gitkeep new file mode 100644 index 0000000..3ad96b4 --- /dev/null +++ b/nginx/.ssl/.gitkeep @@ -0,0 +1 @@ +The .gitignore removes any certs you put in this folder, but this is where the docker-compose will look for them. \ No newline at end of file diff --git a/nginx/nginx.conf b/nginx/nginx.conf index de37656..1cbc5c9 100644 --- a/nginx/nginx.conf +++ b/nginx/nginx.conf @@ -1,13 +1,28 @@ events { worker_connections 1024; } +worker_processes auto; http{ - server{ - server_name website; - listen 80; - location / { - proxy_pass http://website:5000; + ssl_session_cache shared:SSL:10m; + ssl_session_timeout 10m; + + # server{ + # server_name website; + # listen 80; + # location / { + # proxy_pass http://website:5000; + # } + # } + server { + server_name website; + listen 80; + listen 443 ssl; + ssl_certificate .ssl/cert.pem; + ssl_certificate_key .ssl/key.pem; + location / { + proxy_pass http://localhost:5000; } + keepalive_timeout 70; } -} +} \ No newline at end of file From 01894a42070e6a0a20a422cdfee33deec23c0f00 Mon Sep 17 00:00:00 2001 From: Nat Hough Date: Thu, 1 Jan 2026 20:10:50 +0000 Subject: [PATCH 5/5] got quadlet working for website with a https nginx proxy in front of it. --- .config/containers/systemd/nginx.container | 16 ++++++++++++---- .config/containers/systemd/nginx.network | 2 ++ .config/containers/systemd/website.container | 5 +++-- nginx/nginx.conf | 3 ++- 4 files changed, 19 insertions(+), 7 deletions(-) create mode 100644 .config/containers/systemd/nginx.network diff --git a/.config/containers/systemd/nginx.container b/.config/containers/systemd/nginx.container index 8cf6fdf..84ee7d0 100644 --- a/.config/containers/systemd/nginx.container +++ b/.config/containers/systemd/nginx.container @@ -1,15 +1,23 @@ [Unit] Description=Hackspace web proxy -#After=website.container -#Requires=website.container +After=website.container +Requires=website.container [Container] ContainerName=HSNginx Image=nginx:alpine -Volume=/srv/nginx/nginx.conf:/etc/nginx/nginx.conf -Volume=./nginx/.ssl:/etc/nginx/.ssl:ro + +# Intended location +#Volume=/srv/nginx/nginx.conf:/etc/nginx/nginx.conf +#Volume=./nginx/.ssl:/etc/nginx/.ssl:ro + +# if you have it on a dev box +Volume=/home//Projects/website/nginx/nginx.conf:/etc/nginx/nginx.conf +Volume=/home//Projects/website/nginx/.ssl:/etc/nginx/.ssl:ro + PublishPort=8080:80 PublishPort=8443:443 +Network=nginx.network [Service] Restart=always diff --git a/.config/containers/systemd/nginx.network b/.config/containers/systemd/nginx.network new file mode 100644 index 0000000..895ce01 --- /dev/null +++ b/.config/containers/systemd/nginx.network @@ -0,0 +1,2 @@ +[Network] +# This creates a bridge network where containers can resolve each other by name diff --git a/.config/containers/systemd/website.container b/.config/containers/systemd/website.container index 2d5d146..10fdd7e 100644 --- a/.config/containers/systemd/website.container +++ b/.config/containers/systemd/website.container @@ -2,10 +2,11 @@ Description=Hackspace Website [Container] -ContainerName=HSWeb +ContainerName=website Image=localhost/website UserNS=keep-id -PublishPort=5000:5000 +# PublishPort=5000:5000 +Network=nginx.network [Service] Restart=always diff --git a/nginx/nginx.conf b/nginx/nginx.conf index 1cbc5c9..8f91750 100644 --- a/nginx/nginx.conf +++ b/nginx/nginx.conf @@ -21,7 +21,8 @@ http{ ssl_certificate .ssl/cert.pem; ssl_certificate_key .ssl/key.pem; location / { - proxy_pass http://localhost:5000; + proxy_pass http://website:5000; + # proxy_pass http://localhost:5000; } keepalive_timeout 70; }