Snapshot: alpha-2026-9
This commit is contained in:
parent
9acf5a97e2
commit
d00b5c7961
241 changed files with 85546 additions and 2409 deletions
|
|
@ -7,10 +7,11 @@ ENV PYTHONUNBUFFERED 1
|
|||
|
||||
# Set work directory
|
||||
WORKDIR /code
|
||||
|
||||
RUN mkdir /git
|
||||
# Install dependencies
|
||||
COPY requirements.txt /code/
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
RUN touch /mnt/db.sqlite3 && touch /mnt/testdata.py && mkdir /mnt/userfiles
|
||||
|
||||
# Run the application
|
||||
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000", "--insecure"]
|
||||
CMD ["sh", "-c", "python manage.py migrate && python manage.py runserver 0.0.0.0:8000 --insecure"]
|
||||
|
|
|
|||
|
|
@ -3,11 +3,13 @@ FROM node:14
|
|||
|
||||
# Set work directory
|
||||
WORKDIR /app
|
||||
RUN mkdir /git
|
||||
|
||||
# Install app dependencies
|
||||
# A wildcard is used to ensure both package.json AND package-lock.json are copied
|
||||
COPY package.json ./
|
||||
|
||||
COPY extras/ ./extras/
|
||||
RUN npm install
|
||||
|
||||
CMD [ "npm", "run", "dev", "--", "--host"]
|
||||
|
|
|
|||
|
|
@ -1,14 +1 @@
|
|||
FROM nginx:bookworm
|
||||
|
||||
# snakeoil for localhost
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -y openssl && \
|
||||
openssl genrsa -des3 -passout pass:x -out server.pass.key 2048 && \
|
||||
openssl rsa -passin pass:x -in server.pass.key -out server.key && \
|
||||
rm server.pass.key && \
|
||||
openssl req -new -key server.key -out server.csr \
|
||||
-subj "/C=US/ST=Denial/L=Springfield/O=Dis/CN=localhost" && \
|
||||
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt &&\
|
||||
mv server.crt /etc/nginx/nginx.crt && \
|
||||
mv server.key /etc/nginx/nginx.key \
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@ import socketserver
|
|||
import urllib.parse
|
||||
import dnslib
|
||||
import base64
|
||||
import socket
|
||||
|
||||
UPSTREAM_DNS = ("8.8.8.8", 53)
|
||||
|
||||
try:
|
||||
|
||||
|
|
@ -11,6 +14,13 @@ try:
|
|||
if record["name"] == qname and record["type"] == qtype and "value" in record:
|
||||
return record["value"]
|
||||
|
||||
def resolve_recursive(raw_query):
|
||||
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock:
|
||||
sock.settimeout(5)
|
||||
sock.sendto(raw_query, UPSTREAM_DNS)
|
||||
data, _ = sock.recvfrom(4096)
|
||||
return data
|
||||
|
||||
|
||||
class DnsHttpRequestHandler(http.server.BaseHTTPRequestHandler):
|
||||
def do_GET(self):
|
||||
|
|
@ -40,15 +50,16 @@ try:
|
|||
print("SRV record")
|
||||
reply = dnslib.SRV(record["priority"], record["weight"], record["port"], record["target"])
|
||||
response.add_answer(dnslib.RR(dns.q.qname, dns.q.qtype, rdata=reply))
|
||||
pack = response.pack()
|
||||
else:
|
||||
response.header.rcode = dnslib.RCODE.NXDOMAIN
|
||||
print(f"Recursively resolving {dns.q.qname}")
|
||||
pack = resolve_recursive(raw)
|
||||
|
||||
print(response)
|
||||
|
||||
self.send_response(200)
|
||||
self.send_header("Content-type", "application/dns-message")
|
||||
self.end_headers()
|
||||
pack = response.pack()
|
||||
self.wfile.write(pack)
|
||||
return
|
||||
except Exception as e:
|
||||
|
|
|
|||
110
deploy/dev/docker-compose.yml
Normal file
110
deploy/dev/docker-compose.yml
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
version: '3.8'
|
||||
name: dev
|
||||
|
||||
services:
|
||||
backend-a:
|
||||
build:
|
||||
context: ../../backend/
|
||||
dockerfile: ../deploy/dev/Dockerfile.backend
|
||||
environment:
|
||||
TOOLSHED_DB_PATH: /mnt/db.sqlite3
|
||||
TOOLSHED_USERFILES_PATH: /mnt/userfiles
|
||||
TOOLSHED_SETUP_PATH: /mnt/testdata.py
|
||||
volumes:
|
||||
- ../../backend:/code
|
||||
- ../../.git:/git:ro
|
||||
- ./instance_a/a.env:/code/.env
|
||||
- ./instance_a/testdata.py:/mnt/testdata.py
|
||||
- ./instance_a/a.sqlite3:/mnt/db.sqlite3
|
||||
- ./instance_a/userfiles:/mnt/userfiles
|
||||
expose:
|
||||
- 8000
|
||||
command: bash -c "python configure.py; python configure.py testdata; python manage.py runserver 0.0.0.0:8000 --insecure"
|
||||
|
||||
backend-b:
|
||||
build:
|
||||
context: ../../backend/
|
||||
dockerfile: ../deploy/dev/Dockerfile.backend
|
||||
environment:
|
||||
TOOLSHED_DB_PATH: /mnt/db.sqlite3
|
||||
TOOLSHED_USERFILES_PATH: /mnt/userfiles
|
||||
TOOLSHED_SETUP_PATH: /mnt/testdata.py
|
||||
volumes:
|
||||
- ../../backend:/code
|
||||
- ../../.git:/git:ro
|
||||
- ./instance_b/b.env:/code/.env
|
||||
- ./instance_b/testdata.py:/mnt/testdata.py
|
||||
- ./instance_b/b.sqlite3:/mnt/db.sqlite3
|
||||
- ./instance_b/userfiles:/mnt/userfiles
|
||||
expose:
|
||||
- 8000
|
||||
command: bash -c "python configure.py; python configure.py testdata; python manage.py runserver 0.0.0.0:8000 --insecure"
|
||||
|
||||
frontend:
|
||||
build:
|
||||
context: ../../frontend/
|
||||
dockerfile: ../deploy/dev/Dockerfile.frontend
|
||||
volumes:
|
||||
- ../../frontend:/app
|
||||
- ../../.git:/git:ro
|
||||
- /app/node_modules
|
||||
expose:
|
||||
- 5173
|
||||
command: bash -c "npm install && npm run dev -- --host"
|
||||
|
||||
wiki:
|
||||
build:
|
||||
context: ../../
|
||||
dockerfile: deploy/dev/Dockerfile.wiki
|
||||
volumes:
|
||||
- ../../mkdocs.yml:/wiki/mkdocs.yml
|
||||
- ../../docs:/wiki/docs
|
||||
expose:
|
||||
- 8001
|
||||
command: mkdocs serve --dev-addr=0.0.0.0:8001
|
||||
|
||||
proxy-a:
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: Dockerfile.proxy
|
||||
volumes:
|
||||
- ./instance_a/nginx-a.dev.conf:/etc/nginx/nginx.conf:ro
|
||||
- ./instance_a/dns.json:/var/www/dns.json:ro
|
||||
- ./instance_a/domains.json:/var/www/domains.json:ro
|
||||
- ./instance_a/userfiles:/var/www/userfiles:ro
|
||||
# A stable, CA-signed cert (see frontend/.local/make_localhost.sh) covering localhost plus
|
||||
# every loopback IP a dev proxy binds to below, instead of Dockerfile.proxy generating a
|
||||
# fresh throwaway self-signed one on every image build - that regenerated cert invalidated
|
||||
# any trust exception you'd added in your browser on the previous build. Trust
|
||||
# frontend/.local/RootCA.crt once (see docs/development.md) and it keeps working across
|
||||
# rebuilds.
|
||||
- ../../frontend/.local/localhost.crt:/etc/nginx/nginx.crt:ro
|
||||
- ../../frontend/.local/localhost.key:/etc/nginx/nginx.key:ro
|
||||
ports:
|
||||
- "127.0.0.1:8080:8080"
|
||||
- "127.0.0.3:5353:5353"
|
||||
|
||||
proxy-b:
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: Dockerfile.proxy
|
||||
volumes:
|
||||
- ./instance_b/nginx-b.dev.conf:/etc/nginx/nginx.conf:ro
|
||||
- ./instance_b/userfiles:/var/www/userfiles:ro
|
||||
- ../../frontend/.local/localhost.crt:/etc/nginx/nginx.crt:ro
|
||||
- ../../frontend/.local/localhost.key:/etc/nginx/nginx.key:ro
|
||||
ports:
|
||||
- "127.0.0.2:8080:8080"
|
||||
|
||||
dns:
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: Dockerfile.dns
|
||||
volumes:
|
||||
- ./zone.json:/dns/zone.json
|
||||
expose:
|
||||
- 8053
|
||||
networks:
|
||||
default:
|
||||
aliases:
|
||||
- toolshed-dns
|
||||
|
|
@ -2,6 +2,8 @@
|
|||
# SECURITY WARNING: don't run with debug turned on in production!
|
||||
DEBUG=True
|
||||
|
||||
SERVE_X_ACCEL_REDIRECT=False
|
||||
|
||||
# SECURITY WARNING: keep the secret key used in production secret!
|
||||
SECRET_KEY='e*lm&*!j0_stqaiod$1zob(vs@aq6+n-i$1%!rek)_v9n^ue$3'
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
events {}
|
||||
|
||||
http {
|
||||
client_max_body_size 128M;
|
||||
|
||||
upstream backend {
|
||||
server backend-a:8000;
|
||||
}
|
||||
|
|
@ -14,7 +16,7 @@ http {
|
|||
}
|
||||
|
||||
upstream dns {
|
||||
server dns:8053;
|
||||
server toolshed-dns:8053;
|
||||
}
|
||||
|
||||
server {
|
||||
|
|
@ -45,8 +47,34 @@ http {
|
|||
proxy_pass http://backend;
|
||||
}
|
||||
|
||||
location /media {
|
||||
proxy_set_header Host $host:$server_port;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-Host $host:$server_port;
|
||||
proxy_set_header X-Forwarded-Port $server_port;
|
||||
proxy_pass http://backend;
|
||||
}
|
||||
|
||||
location /djangoadmin {
|
||||
proxy_set_header Host $host:$server_port;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-Host $host:$server_port;
|
||||
proxy_set_header X-Forwarded-Port $server_port;
|
||||
proxy_pass http://backend;
|
||||
}
|
||||
|
||||
location /docs {
|
||||
proxy_pass http://backend/docs;
|
||||
proxy_set_header Host $host:$server_port;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-Host $host:$server_port;
|
||||
proxy_set_header X-Forwarded-Port $server_port;
|
||||
proxy_pass http://backend;
|
||||
}
|
||||
|
||||
location /static {
|
||||
|
|
@ -80,17 +108,35 @@ http {
|
|||
# DoH server
|
||||
server {
|
||||
listen 5353 ssl;
|
||||
server_name localhost;
|
||||
server_name localhost 127.0.0.3;
|
||||
|
||||
ssl_certificate /etc/nginx/nginx.crt;
|
||||
ssl_certificate_key /etc/nginx/nginx.key;
|
||||
|
||||
location /dns-query {
|
||||
proxy_pass http://dns;
|
||||
# allow any origin
|
||||
add_header 'Access-Control-Allow-Origin' '*';
|
||||
add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS';
|
||||
# Ensure CORS headers are present even when nginx generates 5xx responses.
|
||||
add_header 'Access-Control-Allow-Origin' '*' always;
|
||||
add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS' always;
|
||||
add_header 'Access-Control-Allow-Headers' 'Accept, Content-Type, Origin, User-Agent' always;
|
||||
add_header 'Access-Control-Expose-Headers' 'Content-Type' always;
|
||||
error_page 500 502 503 504 = @doh_error;
|
||||
|
||||
location /dns-query {
|
||||
if ($request_method = OPTIONS) {
|
||||
add_header 'Access-Control-Allow-Origin' '*' always;
|
||||
add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS' always;
|
||||
add_header 'Access-Control-Allow-Headers' 'Accept, Content-Type, Origin, User-Agent' always;
|
||||
add_header 'Access-Control-Max-Age' 86400 always;
|
||||
add_header 'Content-Length' 0;
|
||||
add_header 'Content-Type' 'text/plain; charset=utf-8';
|
||||
return 204;
|
||||
}
|
||||
|
||||
proxy_pass http://dns;
|
||||
}
|
||||
|
||||
location @doh_error {
|
||||
default_type text/plain;
|
||||
return 502 'DoH upstream unavailable';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
# SECURITY WARNING: don't run with debug turned on in production!
|
||||
DEBUG=True
|
||||
|
||||
SERVE_X_ACCEL_REDIRECT=True
|
||||
|
||||
# SECURITY WARNING: keep the secret key used in production secret!
|
||||
SECRET_KEY='7ccxjje%q@@0*z+r&-$fy3(rj9n)%$!sk-k++-&rb=_u(wpjbe'
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
events {}
|
||||
|
||||
http {
|
||||
client_max_body_size 128M;
|
||||
|
||||
upstream backend {
|
||||
server backend-b:8000;
|
||||
}
|
||||
|
|
@ -35,6 +37,28 @@ http {
|
|||
proxy_pass http://backend;
|
||||
}
|
||||
|
||||
location /media {
|
||||
proxy_set_header Host $host:$server_port;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-Host $host:$server_port;
|
||||
proxy_set_header X-Forwarded-Port $server_port;
|
||||
proxy_pass http://backend;
|
||||
}
|
||||
|
||||
location /redirect_media/ {
|
||||
internal;
|
||||
alias /var/www/userfiles/;
|
||||
# This location serves the file directly, bypassing Django (and therefore
|
||||
# django-cors-headers) entirely - it's the target of the X-Accel-Redirect
|
||||
# response from files/media_urls.py, used when SERVE_X_ACCEL_REDIRECT=True.
|
||||
# CORS headers must be added here explicitly since nothing else will.
|
||||
add_header 'Access-Control-Allow-Origin' '*' always;
|
||||
add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS' always;
|
||||
add_header 'Access-Control-Allow-Headers' 'Authorization, Accept, Content-Type, Origin, User-Agent' always;
|
||||
}
|
||||
|
||||
location /docs {
|
||||
proxy_pass http://backend/docs;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,4 +21,4 @@
|
|||
"target": "127.0.0.2."
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
Loading…
Add table
Add a link
Reference in a new issue