diff --git a/.config/containers/systemd/nginx.container b/.config/containers/systemd/nginx.container new file mode 100644 index 0000000..84ee7d0 --- /dev/null +++ b/.config/containers/systemd/nginx.container @@ -0,0 +1,27 @@ +[Unit] +Description=Hackspace web proxy +After=website.container +Requires=website.container + +[Container] +ContainerName=HSNginx +Image=nginx:alpine + +# 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 + +[Install] +WantedBy=default.target + 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 new file mode 100644 index 0000000..10fdd7e --- /dev/null +++ b/.config/containers/systemd/website.container @@ -0,0 +1,16 @@ +[Unit] +Description=Hackspace Website + +[Container] +ContainerName=website +Image=localhost/website +UserNS=keep-id +# PublishPort=5000:5000 +Network=nginx.network + +[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 new file mode 100644 index 0000000..afa1836 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,14 @@ +# syntax=docker/dockerfile:1 + +FROM python:slim +# 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", "--host=0.0.0.0"] + 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 new file mode 100644 index 0000000..79b4137 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,18 @@ +version: "3" +services: + website: + build: + context: . + ports: + - "5000:5000" + nginx: + image: nginx:alpine + volumes: + - ./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/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", 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 new file mode 100644 index 0000000..8f91750 --- /dev/null +++ b/nginx/nginx.conf @@ -0,0 +1,29 @@ +events { + worker_connections 1024; +} +worker_processes auto; +http{ + 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://website:5000; + # proxy_pass http://localhost:5000; + } + keepalive_timeout 70; + } +} \ No newline at end of file