development setup using docker
This commit is contained in:
parent
c4c49931a4
commit
f8dacef309
17 changed files with 414 additions and 1 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -131,3 +131,4 @@ dmypy.json
|
||||||
staticfiles/
|
staticfiles/
|
||||||
userfiles/
|
userfiles/
|
||||||
testdata.py
|
testdata.py
|
||||||
|
*.sqlite3
|
||||||
|
|
16
deploy/dev/Dockerfile.backend
Normal file
16
deploy/dev/Dockerfile.backend
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
# Use an official Python runtime as instance_a parent image
|
||||||
|
FROM python:3.9
|
||||||
|
|
||||||
|
# Set environment variables
|
||||||
|
ENV PYTHONDONTWRITEBYTECODE 1
|
||||||
|
ENV PYTHONUNBUFFERED 1
|
||||||
|
|
||||||
|
# Set work directory
|
||||||
|
WORKDIR /code
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
COPY requirements.txt /code/
|
||||||
|
RUN pip install --no-cache-dir -r requirements.txt
|
||||||
|
|
||||||
|
# Run the application
|
||||||
|
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000", "--insecure"]
|
16
deploy/dev/Dockerfile.dns
Normal file
16
deploy/dev/Dockerfile.dns
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
# Use an official Python runtime as instance_a parent image
|
||||||
|
FROM python:3.9
|
||||||
|
|
||||||
|
# Set environment variables
|
||||||
|
ENV PYTHONDONTWRITEBYTECODE 1
|
||||||
|
ENV PYTHONUNBUFFERED 1
|
||||||
|
|
||||||
|
# Set work directory
|
||||||
|
WORKDIR /dns
|
||||||
|
|
||||||
|
COPY dns_server.py /dns/
|
||||||
|
|
||||||
|
RUN pip install dnslib
|
||||||
|
|
||||||
|
# Run the application
|
||||||
|
CMD ["python", "dns_server.py"]
|
13
deploy/dev/Dockerfile.frontend
Normal file
13
deploy/dev/Dockerfile.frontend
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
# Use an official Node.js runtime as instance_a parent image
|
||||||
|
FROM node:14
|
||||||
|
|
||||||
|
# Set work directory
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Install app dependencies
|
||||||
|
# A wildcard is used to ensure both package.json AND package-lock.json are copied
|
||||||
|
COPY package.json ./
|
||||||
|
|
||||||
|
RUN npm install
|
||||||
|
|
||||||
|
CMD [ "npm", "run", "dev", "--", "--host"]
|
14
deploy/dev/Dockerfile.proxy
Normal file
14
deploy/dev/Dockerfile.proxy
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
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 \
|
15
deploy/dev/Dockerfile.wiki
Normal file
15
deploy/dev/Dockerfile.wiki
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
# Use an official Python runtime as instance_a parent image
|
||||||
|
FROM python:3.9
|
||||||
|
|
||||||
|
# Set environment variables
|
||||||
|
ENV PYTHONDONTWRITEBYTECODE 1
|
||||||
|
ENV PYTHONUNBUFFERED 1
|
||||||
|
|
||||||
|
# Set work directory
|
||||||
|
WORKDIR /wiki
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
RUN pip install --no-cache-dir mkdocs
|
||||||
|
|
||||||
|
# Run the application
|
||||||
|
CMD ["mkdocs", "serve", "--dev-addr=0.0.0.0:8001"]
|
72
deploy/dev/dns_server.py
Normal file
72
deploy/dev/dns_server.py
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
import http.server
|
||||||
|
import socketserver
|
||||||
|
import urllib.parse
|
||||||
|
import dnslib
|
||||||
|
import base64
|
||||||
|
|
||||||
|
try:
|
||||||
|
|
||||||
|
def resolve(zone, qname, qtype):
|
||||||
|
for record in zone:
|
||||||
|
if record["name"] == qname and record["type"] == qtype and "value" in record:
|
||||||
|
return record["value"]
|
||||||
|
|
||||||
|
|
||||||
|
class DnsHttpRequestHandler(http.server.BaseHTTPRequestHandler):
|
||||||
|
def do_GET(self):
|
||||||
|
try:
|
||||||
|
with open("/dns/zone.json", "r") as f:
|
||||||
|
import json
|
||||||
|
zone = json.load(f)
|
||||||
|
|
||||||
|
url = urllib.parse.urlparse(self.path)
|
||||||
|
if url.path != "/dns-query":
|
||||||
|
self.send_response(404)
|
||||||
|
return
|
||||||
|
query = urllib.parse.parse_qs(url.query)
|
||||||
|
if "dns" not in query:
|
||||||
|
self.send_response(400)
|
||||||
|
return
|
||||||
|
query_base64 = query["dns"][0]
|
||||||
|
padded = query_base64 + "=" * (4 - len(query_base64) % 4)
|
||||||
|
raw = base64.b64decode(padded)
|
||||||
|
dns = dnslib.DNSRecord.parse(raw)
|
||||||
|
|
||||||
|
response = dnslib.DNSRecord(dnslib.DNSHeader(id=dns.header.id, qr=1, aa=1, ra=1), q=dns.q)
|
||||||
|
|
||||||
|
record = resolve(zone, dns.q.qname, dnslib.QTYPE[dns.q.qtype])
|
||||||
|
if record:
|
||||||
|
if dns.q.qtype == dnslib.QTYPE.SRV:
|
||||||
|
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))
|
||||||
|
else:
|
||||||
|
response.header.rcode = dnslib.RCODE.NXDOMAIN
|
||||||
|
|
||||||
|
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:
|
||||||
|
print(f"Error: {e}")
|
||||||
|
self.send_response(500)
|
||||||
|
self.send_header("Content-type", "text/html")
|
||||||
|
self.end_headers()
|
||||||
|
self.wfile.write(b"Internal Server Error")
|
||||||
|
|
||||||
|
|
||||||
|
handler_object = DnsHttpRequestHandler
|
||||||
|
|
||||||
|
PORT = 8053
|
||||||
|
my_server = socketserver.TCPServer(("", PORT), handler_object)
|
||||||
|
|
||||||
|
# Start the server
|
||||||
|
print(f"Starting server on port {PORT}")
|
||||||
|
my_server.serve_forever()
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error: {e}")
|
8
deploy/dev/instance_a/a.env
Normal file
8
deploy/dev/instance_a/a.env
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
|
||||||
|
# SECURITY WARNING: don't run with debug turned on in production!
|
||||||
|
DEBUG=True
|
||||||
|
|
||||||
|
# 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'
|
||||||
|
|
||||||
|
ALLOWED_HOSTS="*"
|
3
deploy/dev/instance_a/dns.json
Normal file
3
deploy/dev/instance_a/dns.json
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
[
|
||||||
|
"127.0.0.3:5353"
|
||||||
|
]
|
3
deploy/dev/instance_a/domains.json
Normal file
3
deploy/dev/instance_a/domains.json
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
[
|
||||||
|
"a.localhost"
|
||||||
|
]
|
96
deploy/dev/instance_a/nginx-a.dev.conf
Normal file
96
deploy/dev/instance_a/nginx-a.dev.conf
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
events {}
|
||||||
|
|
||||||
|
http {
|
||||||
|
upstream backend {
|
||||||
|
server backend-a:8000;
|
||||||
|
}
|
||||||
|
|
||||||
|
upstream frontend {
|
||||||
|
server frontend:5173;
|
||||||
|
}
|
||||||
|
|
||||||
|
upstream wiki {
|
||||||
|
server wiki:8001;
|
||||||
|
}
|
||||||
|
|
||||||
|
upstream dns {
|
||||||
|
server dns:8053;
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
|
||||||
|
listen 8080 ssl;
|
||||||
|
server_name localhost;
|
||||||
|
|
||||||
|
ssl_certificate /etc/nginx/nginx.crt;
|
||||||
|
ssl_certificate_key /etc/nginx/nginx.key;
|
||||||
|
|
||||||
|
location /api {
|
||||||
|
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 /auth {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /static {
|
||||||
|
proxy_pass http://backend/static;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /wiki {
|
||||||
|
proxy_pass http://wiki/wiki;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /livereload {
|
||||||
|
proxy_pass http://wiki/livereload;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /local/ {
|
||||||
|
alias /var/www/;
|
||||||
|
try_files $uri.json =404;
|
||||||
|
add_header Content-Type application/json;
|
||||||
|
}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "Upgrade";
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_pass http://frontend;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
# DoH server
|
||||||
|
server {
|
||||||
|
listen 5353 ssl;
|
||||||
|
server_name localhost;
|
||||||
|
|
||||||
|
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';
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
7
deploy/dev/instance_b/b.env
Normal file
7
deploy/dev/instance_b/b.env
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
# SECURITY WARNING: don't run with debug turned on in production!
|
||||||
|
DEBUG=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'
|
||||||
|
|
||||||
|
ALLOWED_HOSTS="*"
|
46
deploy/dev/instance_b/nginx-b.dev.conf
Normal file
46
deploy/dev/instance_b/nginx-b.dev.conf
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
events {}
|
||||||
|
|
||||||
|
http {
|
||||||
|
upstream backend {
|
||||||
|
server backend-b:8000;
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
|
||||||
|
listen 8080 ssl;
|
||||||
|
server_name localhost;
|
||||||
|
|
||||||
|
ssl_certificate /etc/nginx/nginx.crt;
|
||||||
|
ssl_certificate_key /etc/nginx/nginx.key;
|
||||||
|
|
||||||
|
location /api {
|
||||||
|
#proxy_set_header X-Forwarded-For "$http_x_forwarded_for, $realip_remote_addr";
|
||||||
|
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 /auth {
|
||||||
|
#proxy_set_header X-Forwarded-For "$http_x_forwarded_for, $realip_remote_addr";
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /static {
|
||||||
|
proxy_pass http://backend/static;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
24
deploy/dev/zone.json
Normal file
24
deploy/dev/zone.json
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "_toolshed-server._tcp.a.localhost.",
|
||||||
|
"type": "SRV",
|
||||||
|
"ttl": 60,
|
||||||
|
"value": {
|
||||||
|
"priority": 0,
|
||||||
|
"weight": 5,
|
||||||
|
"port": 8080,
|
||||||
|
"target": "127.0.0.1."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "_toolshed-server._tcp.b.localhost.",
|
||||||
|
"type": "SRV",
|
||||||
|
"ttl": 60,
|
||||||
|
"value": {
|
||||||
|
"priority": 0,
|
||||||
|
"weight": 5,
|
||||||
|
"port": 8080,
|
||||||
|
"target": "127.0.0.2."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
78
deploy/docker-compose.override.yml
Normal file
78
deploy/docker-compose.override.yml
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
backend-a:
|
||||||
|
build:
|
||||||
|
context: ../backend/
|
||||||
|
dockerfile: ../deploy/dev/Dockerfile.backend
|
||||||
|
volumes:
|
||||||
|
- ../backend:/code
|
||||||
|
- ../deploy/dev/instance_a/a.env:/code/.env
|
||||||
|
- ../deploy/dev/instance_a/a.sqlite3:/code/db.sqlite3
|
||||||
|
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
|
||||||
|
volumes:
|
||||||
|
- ../backend:/code
|
||||||
|
- ../deploy/dev/instance_b/b.env:/code/.env
|
||||||
|
- ../deploy/dev/instance_b/b.sqlite3:/code/db.sqlite3
|
||||||
|
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:ro
|
||||||
|
- /app/node_modules
|
||||||
|
expose:
|
||||||
|
- 5173
|
||||||
|
command: 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: dev/Dockerfile.proxy
|
||||||
|
volumes:
|
||||||
|
- ./dev/instance_a/nginx-a.dev.conf:/etc/nginx/nginx.conf:ro
|
||||||
|
- ./dev/instance_a/dns.json:/var/www/dns.json:ro
|
||||||
|
- ./dev/instance_a/domains.json:/var/www/domains.json:ro
|
||||||
|
ports:
|
||||||
|
- "127.0.0.1:8080:8080"
|
||||||
|
- "127.0.0.3:5353:5353"
|
||||||
|
|
||||||
|
proxy-b:
|
||||||
|
build:
|
||||||
|
context: ./
|
||||||
|
dockerfile: dev/Dockerfile.proxy
|
||||||
|
volumes:
|
||||||
|
- ./dev/instance_b/nginx-b.dev.conf:/etc/nginx/nginx.conf:ro
|
||||||
|
ports:
|
||||||
|
- "127.0.0.2:8080:8080"
|
||||||
|
|
||||||
|
dns:
|
||||||
|
build:
|
||||||
|
context: ./dev/
|
||||||
|
dockerfile: Dockerfile.dns
|
||||||
|
volumes:
|
||||||
|
- ./dev/zone.json:/dns/zone.json
|
||||||
|
expose:
|
||||||
|
- 8053
|
0
frontend/node_modules/.forgit
generated
vendored
Normal file
0
frontend/node_modules/.forgit
generated
vendored
Normal file
|
@ -24,3 +24,4 @@ extra_javascript:
|
||||||
- https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.js
|
- https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.js
|
||||||
extra_css:
|
extra_css:
|
||||||
- toolshed.css
|
- toolshed.css
|
||||||
|
site_url: https://localhost:8080/wiki/
|
||||||
|
|
Loading…
Reference in a new issue