diff options
| author | user@node5.net <user@node5.net> | 2025-12-07 17:23:21 +0100 |
|---|---|---|
| committer | user@node5.net <user@node5.net> | 2025-12-07 17:23:21 +0100 |
| commit | f92874002dfe8477c97bce5c7c1564a707f09075 (patch) | |
| tree | 99f9a8408e8963d97ce78cfd533f6d78210301fc /web_interface | |
| parent | b00da901a46b0710ad8bd29522e33bed2c4a1c77 (diff) | |
Prod setup works
Diffstat (limited to 'web_interface')
| -rw-r--r-- | web_interface/README.md | 15 | ||||
| -rw-r--r-- | web_interface/drinks_machine/settings.py | 37 | ||||
| -rw-r--r-- | web_interface/misc/prod_configs/drinks-machine.service | 13 | ||||
| -rw-r--r-- | web_interface/misc/prod_configs/drinks_machine_nginx.conf | 42 | ||||
| -rw-r--r-- | web_interface/pyproject.toml | 11 | ||||
| -rw-r--r-- | web_interface/uv.lock | 42 |
6 files changed, 142 insertions, 18 deletions
diff --git a/web_interface/README.md b/web_interface/README.md index 418ba3b..5342e4d 100644 --- a/web_interface/README.md +++ b/web_interface/README.md @@ -2,11 +2,24 @@ ## Setup & running -### Dev setup & running +### Setup dev 1. [Download nix](https://nixos.org/download/) 2. Run: `nix-shell --command make` + +### Setup prod + +```bash +python3 -m venv venv +source venv/bin/activate +pip install .[prod] +./manage.py collectstatic +sudo ln -sr misc/prod_configs/drinks_machine_nginx.conf /etc/nginx/sites-enabled/ +sudo ln -sr misc/prod_configs/drinks-machine.service /etc/systemd/system/ +sudo systemctl daemon-reload +``` +  ## TODO diff --git a/web_interface/drinks_machine/settings.py b/web_interface/drinks_machine/settings.py index 098254d..738e5ba 100644 --- a/web_interface/drinks_machine/settings.py +++ b/web_interface/drinks_machine/settings.py @@ -13,6 +13,8 @@ https://docs.djangoproject.com/en/6.0/ref/settings/ from pathlib import Path import os +from django.core.management.utils import get_random_secret_key + # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent @@ -24,13 +26,33 @@ MEDIA_ROOT = os.path.join(BASE_DIR, 'media') # See https://docs.djangoproject.com/en/6.0/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = 'django-insecure-m(z7kz1$nf)4r^uu^0t#o4&5kxvvotpw0#!e(^=womt&4e=@^8' -# SECURITY WARNING: don't run with debug turned on in production! -DEBUG = True +# Define the path to your secret key file inside the .secrets folder +secret_key_file = os.path.join(BASE_DIR, '.secrets', 'secret_key.txt') + +# Ensure the .secrets directory exists +os.makedirs(os.path.dirname(secret_key_file), exist_ok=True) -ALLOWED_HOSTS = [] +# Check if the file exists +if not os.path.exists(secret_key_file): + # Generate a new secret key + secret_key = get_random_secret_key() + # Save the secret key to the file + with open(secret_key_file, 'w') as f: + f.write(secret_key) +else: + # Read the secret key from the file + with open(secret_key_file, 'r') as f: + secret_key = f.read().strip() + +# Set the SECRET_KEY setting +SECRET_KEY = secret_key + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = "DEBUG" in os.environ and os.environ["DEBUG"] == "INSECURE" + +ALLOWED_HOSTS = ['drinks-machine.node5.net'] # Application definition @@ -120,9 +142,6 @@ USE_TZ = True # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/6.0/howto/static-files/ -STATIC_URL = 'static/' - -STATICFILES_DIRS = [ - BASE_DIR / "static", -] +STATIC_URL = '/static/' +STATIC_ROOT = os.path.join(BASE_DIR, "static") diff --git a/web_interface/misc/prod_configs/drinks-machine.service b/web_interface/misc/prod_configs/drinks-machine.service new file mode 100644 index 0000000..a13ce0c --- /dev/null +++ b/web_interface/misc/prod_configs/drinks-machine.service @@ -0,0 +1,13 @@ +[Unit] +Description=uWSGI instance to serve drinks machine web interface +After=network.target + +[Service] +User=drinks +Group=www-data +WorkingDirectory=/opt/drinks_machine/web_interface +Environment="PATH=/opt/drinks_machine/web_interface/venv/bin" +ExecStart=/opt/drinks_machine/web_interface/venv/bin/gunicorn --bind unix:/tmp/drinks-machine.sock drinks_machine.wsgi --log-level debug + +[Install] +WantedBy=multi-user.target diff --git a/web_interface/misc/prod_configs/drinks_machine_nginx.conf b/web_interface/misc/prod_configs/drinks_machine_nginx.conf new file mode 100644 index 0000000..959a5f3 --- /dev/null +++ b/web_interface/misc/prod_configs/drinks_machine_nginx.conf @@ -0,0 +1,42 @@ +server { + listen 443 ssl; + listen [::]:443 ssl; + ssl_certificate /etc/letsencrypt/live/node5.net-0001/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/node5.net-0001/privkey.pem; + server_name drinks-machine.node5.net; + + location /static/ { + root /opt/drinks_machine/web_interface; + } + + location /media/ { + root /opt/drinks_machine/web_interface; + } + + location / { + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Host $host; + proxy_pass_request_headers on; + + proxy_pass http://unix:/tmp/drinks-machine.sock; + } + + charset UTF-8; + + error_page 404 /404.html; +} + +server { + listen 80; + listen [::]:80; + server_name drinks-machine.node5.net www.drinks-machine.node5.net; + + return 301 https://$host$request_uri; + + return 404; + + +} diff --git a/web_interface/pyproject.toml b/web_interface/pyproject.toml index cf7cc36..90b92ec 100644 --- a/web_interface/pyproject.toml +++ b/web_interface/pyproject.toml @@ -2,10 +2,10 @@ name = "drinks-machine" version = "0.1.0" dependencies = [ - "Django==6.0", + "Django==5.2.9", "django-colorfield==0.14.0" ] -requires-python = ">=3.12" +requires-python = ">=3.11.2" authors = [ ] maintainers = [ @@ -13,7 +13,14 @@ maintainers = [ description = "Webinterface for the drinks machine" readme = "README.md" +[tool.setuptools] +py-modules = [] + [project.optional-dependencies] dev = [ ] +prod = [ + "gunicorn==23.0.0" +] + diff --git a/web_interface/uv.lock b/web_interface/uv.lock index e6bd3a6..ebc283f 100644 --- a/web_interface/uv.lock +++ b/web_interface/uv.lock @@ -1,6 +1,6 @@ version = 1 revision = 2 -requires-python = ">=3.12" +requires-python = ">=3.11.2" [[package]] name = "asgiref" @@ -13,16 +13,16 @@ wheels = [ [[package]] name = "django" -version = "6.0" +version = "5.2.9" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "asgiref" }, { name = "sqlparse" }, { name = "tzdata", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/15/75/19762bfc4ea556c303d9af8e36f0cd910ab17dff6c8774644314427a2120/django-6.0.tar.gz", hash = "sha256:7b0c1f50c0759bbe6331c6a39c89ae022a84672674aeda908784617ef47d8e26", size = 10932418, upload-time = "2025-12-03T16:26:21.878Z" } +sdist = { url = "https://files.pythonhosted.org/packages/eb/1c/188ce85ee380f714b704283013434976df8d3a2df8e735221a02605b6794/django-5.2.9.tar.gz", hash = "sha256:16b5ccfc5e8c27e6c0561af551d2ea32852d7352c67d452ae3e76b4f6b2ca495", size = 10848762, upload-time = "2025-12-02T14:01:08.418Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d7/ae/f19e24789a5ad852670d6885f5480f5e5895576945fcc01817dfd9bc002a/django-6.0-py3-none-any.whl", hash = "sha256:1cc2c7344303bbfb7ba5070487c17f7fc0b7174bbb0a38cebf03c675f5f19b6d", size = 8339181, upload-time = "2025-12-03T16:26:16.231Z" }, + { url = "https://files.pythonhosted.org/packages/17/b0/7f42bfc38b8f19b78546d47147e083ed06e12fc29c42da95655e0962c6c2/django-5.2.9-py3-none-any.whl", hash = "sha256:3a4ea88a70370557ab1930b332fd2887a9f48654261cdffda663fef5976bb00a", size = 8290652, upload-time = "2025-12-02T14:01:03.485Z" }, ] [[package]] @@ -46,12 +46,18 @@ dependencies = [ { name = "django-colorfield" }, ] +[package.optional-dependencies] +prod = [ + { name = "uwsgi" }, +] + [package.metadata] requires-dist = [ - { name = "django", specifier = "==6.0" }, + { name = "django", specifier = "==5.2.9" }, { name = "django-colorfield", specifier = "==0.14.0" }, + { name = "uwsgi", marker = "extra == 'prod'", specifier = "==2.0.31" }, ] -provides-extras = ["dev"] +provides-extras = ["dev", "prod"] [[package]] name = "pillow" @@ -59,6 +65,17 @@ version = "12.0.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/5a/b0/cace85a1b0c9775a9f8f5d5423c8261c858760e2466c79b2dd184638b056/pillow-12.0.0.tar.gz", hash = "sha256:87d4f8125c9988bfbed67af47dd7a953e2fc7b0cc1e7800ec6d2080d490bb353", size = 47008828, upload-time = "2025-10-15T18:24:14.008Z" } wheels = [ + { url = "https://files.pythonhosted.org/packages/0e/5a/a2f6773b64edb921a756eb0729068acad9fc5208a53f4a349396e9436721/pillow-12.0.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:0fd00cac9c03256c8b2ff58f162ebcd2587ad3e1f2e397eab718c47e24d231cc", size = 5289798, upload-time = "2025-10-15T18:21:47.763Z" }, + { url = "https://files.pythonhosted.org/packages/2e/05/069b1f8a2e4b5a37493da6c5868531c3f77b85e716ad7a590ef87d58730d/pillow-12.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a3475b96f5908b3b16c47533daaa87380c491357d197564e0ba34ae75c0f3257", size = 4650589, upload-time = "2025-10-15T18:21:49.515Z" }, + { url = "https://files.pythonhosted.org/packages/61/e3/2c820d6e9a36432503ead175ae294f96861b07600a7156154a086ba7111a/pillow-12.0.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:110486b79f2d112cf6add83b28b627e369219388f64ef2f960fef9ebaf54c642", size = 6230472, upload-time = "2025-10-15T18:21:51.052Z" }, + { url = "https://files.pythonhosted.org/packages/4f/89/63427f51c64209c5e23d4d52071c8d0f21024d3a8a487737caaf614a5795/pillow-12.0.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5269cc1caeedb67e6f7269a42014f381f45e2e7cd42d834ede3c703a1d915fe3", size = 8033887, upload-time = "2025-10-15T18:21:52.604Z" }, + { url = "https://files.pythonhosted.org/packages/f6/1b/c9711318d4901093c15840f268ad649459cd81984c9ec9887756cca049a5/pillow-12.0.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:aa5129de4e174daccbc59d0a3b6d20eaf24417d59851c07ebb37aeb02947987c", size = 6343964, upload-time = "2025-10-15T18:21:54.619Z" }, + { url = "https://files.pythonhosted.org/packages/41/1e/db9470f2d030b4995083044cd8738cdd1bf773106819f6d8ba12597d5352/pillow-12.0.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bee2a6db3a7242ea309aa7ee8e2780726fed67ff4e5b40169f2c940e7eb09227", size = 7034756, upload-time = "2025-10-15T18:21:56.151Z" }, + { url = "https://files.pythonhosted.org/packages/cc/b0/6177a8bdd5ee4ed87cba2de5a3cc1db55ffbbec6176784ce5bb75aa96798/pillow-12.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:90387104ee8400a7b4598253b4c406f8958f59fcf983a6cea2b50d59f7d63d0b", size = 6458075, upload-time = "2025-10-15T18:21:57.759Z" }, + { url = "https://files.pythonhosted.org/packages/bc/5e/61537aa6fa977922c6a03253a0e727e6e4a72381a80d63ad8eec350684f2/pillow-12.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bc91a56697869546d1b8f0a3ff35224557ae7f881050e99f615e0119bf934b4e", size = 7125955, upload-time = "2025-10-15T18:21:59.372Z" }, + { url = "https://files.pythonhosted.org/packages/1f/3d/d5033539344ee3cbd9a4d69e12e63ca3a44a739eb2d4c8da350a3d38edd7/pillow-12.0.0-cp311-cp311-win32.whl", hash = "sha256:27f95b12453d165099c84f8a8bfdfd46b9e4bda9e0e4b65f0635430027f55739", size = 6298440, upload-time = "2025-10-15T18:22:00.982Z" }, + { url = "https://files.pythonhosted.org/packages/4d/42/aaca386de5cc8bd8a0254516957c1f265e3521c91515b16e286c662854c4/pillow-12.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:b583dc9070312190192631373c6c8ed277254aa6e6084b74bdd0a6d3b221608e", size = 6999256, upload-time = "2025-10-15T18:22:02.617Z" }, + { url = "https://files.pythonhosted.org/packages/ba/f1/9197c9c2d5708b785f631a6dfbfa8eb3fb9672837cb92ae9af812c13b4ed/pillow-12.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:759de84a33be3b178a64c8ba28ad5c135900359e85fb662bc6e403ad4407791d", size = 2436025, upload-time = "2025-10-15T18:22:04.598Z" }, { url = "https://files.pythonhosted.org/packages/2c/90/4fcce2c22caf044e660a198d740e7fbc14395619e3cb1abad12192c0826c/pillow-12.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:53561a4ddc36facb432fae7a9d8afbfaf94795414f5cdc5fc52f28c1dca90371", size = 5249377, upload-time = "2025-10-15T18:22:05.993Z" }, { url = "https://files.pythonhosted.org/packages/fd/e0/ed960067543d080691d47d6938ebccbf3976a931c9567ab2fbfab983a5dd/pillow-12.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:71db6b4c1653045dacc1585c1b0d184004f0d7e694c7b34ac165ca70c0838082", size = 4650343, upload-time = "2025-10-15T18:22:07.718Z" }, { url = "https://files.pythonhosted.org/packages/e7/a1/f81fdeddcb99c044bf7d6faa47e12850f13cee0849537a7d27eeab5534d4/pillow-12.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2fa5f0b6716fc88f11380b88b31fe591a06c6315e955c096c35715788b339e3f", size = 6232981, upload-time = "2025-10-15T18:22:09.287Z" }, @@ -120,6 +137,13 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a2/2f/16cabcc6426c32218ace36bf0d55955e813f2958afddbf1d391849fee9d1/pillow-12.0.0-cp314-cp314t-win32.whl", hash = "sha256:3830c769decf88f1289680a59d4f4c46c72573446352e2befec9a8512104fa52", size = 6408045, upload-time = "2025-10-15T18:23:53.177Z" }, { url = "https://files.pythonhosted.org/packages/35/73/e29aa0c9c666cf787628d3f0dcf379f4791fba79f4936d02f8b37165bdf8/pillow-12.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:905b0365b210c73afb0ebe9101a32572152dfd1c144c7e28968a331b9217b94a", size = 7148282, upload-time = "2025-10-15T18:23:55.316Z" }, { url = "https://files.pythonhosted.org/packages/c1/70/6b41bdcddf541b437bbb9f47f94d2db5d9ddef6c37ccab8c9107743748a4/pillow-12.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:99353a06902c2e43b43e8ff74ee65a7d90307d82370604746738a1e0661ccca7", size = 2525630, upload-time = "2025-10-15T18:23:57.149Z" }, + { url = "https://files.pythonhosted.org/packages/1d/b3/582327e6c9f86d037b63beebe981425d6811104cb443e8193824ef1a2f27/pillow-12.0.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b22bd8c974942477156be55a768f7aa37c46904c175be4e158b6a86e3a6b7ca8", size = 5215068, upload-time = "2025-10-15T18:23:59.594Z" }, + { url = "https://files.pythonhosted.org/packages/fd/d6/67748211d119f3b6540baf90f92fae73ae51d5217b171b0e8b5f7e5d558f/pillow-12.0.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:805ebf596939e48dbb2e4922a1d3852cfc25c38160751ce02da93058b48d252a", size = 4614994, upload-time = "2025-10-15T18:24:01.669Z" }, + { url = "https://files.pythonhosted.org/packages/2d/e1/f8281e5d844c41872b273b9f2c34a4bf64ca08905668c8ae730eedc7c9fa/pillow-12.0.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cae81479f77420d217def5f54b5b9d279804d17e982e0f2fa19b1d1e14ab5197", size = 5246639, upload-time = "2025-10-15T18:24:03.403Z" }, + { url = "https://files.pythonhosted.org/packages/94/5a/0d8ab8ffe8a102ff5df60d0de5af309015163bf710c7bb3e8311dd3b3ad0/pillow-12.0.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:aeaefa96c768fc66818730b952a862235d68825c178f1b3ffd4efd7ad2edcb7c", size = 6986839, upload-time = "2025-10-15T18:24:05.344Z" }, + { url = "https://files.pythonhosted.org/packages/20/2e/3434380e8110b76cd9eb00a363c484b050f949b4bbe84ba770bb8508a02c/pillow-12.0.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:09f2d0abef9e4e2f349305a4f8cc784a8a6c2f58a8c4892eea13b10a943bd26e", size = 5313505, upload-time = "2025-10-15T18:24:07.137Z" }, + { url = "https://files.pythonhosted.org/packages/57/ca/5a9d38900d9d74785141d6580950fe705de68af735ff6e727cb911b64740/pillow-12.0.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bdee52571a343d721fb2eb3b090a82d959ff37fc631e3f70422e0c2e029f3e76", size = 5963654, upload-time = "2025-10-15T18:24:09.579Z" }, + { url = "https://files.pythonhosted.org/packages/95/7e/f896623c3c635a90537ac093c6a618ebe1a90d87206e42309cb5d98a1b9e/pillow-12.0.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:b290fd8aa38422444d4b50d579de197557f182ef1068b75f5aa8558638b8d0a5", size = 6997850, upload-time = "2025-10-15T18:24:11.495Z" }, ] [[package]] @@ -139,3 +163,9 @@ sdist = { url = "https://files.pythonhosted.org/packages/95/32/1a225d6164441be76 wheels = [ { url = "https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8", size = 347839, upload-time = "2025-03-23T13:54:41.845Z" }, ] + +[[package]] +name = "uwsgi" +version = "2.0.31" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9f/49/2f57640e889ba509fd1fae10cccec1b58972a07c2724486efba94c5ea448/uwsgi-2.0.31.tar.gz", hash = "sha256:e8f8b350ccc106ff93a65247b9136f529c14bf96b936ac5b264c6ff9d0c76257", size = 822796, upload-time = "2025-10-11T19:17:28.794Z" } |
