development setup using docker
This commit is contained in:
parent
c4c49931a4
commit
f8dacef309
17 changed files with 414 additions and 1 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -130,4 +130,5 @@ dmypy.json
|
|||
|
||||
staticfiles/
|
||||
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
|
||||
extra_css:
|
||||
- toolshed.css
|
||||
site_url: https://localhost:8080/wiki/
|
||||
|
|
Loading…
Reference in a new issue