Some update
This commit is contained in:
parent
c43a11fdd2
commit
e92a7e2e62
13 changed files with 94 additions and 128 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -1,2 +1,2 @@
|
|||
run/
|
||||
control-server/build/
|
||||
/run/
|
||||
/control-server/build/
|
76
.vscode/settings.json
vendored
76
.vscode/settings.json
vendored
|
@ -1,76 +0,0 @@
|
|||
{
|
||||
"files.associations": {
|
||||
"ostream": "cpp",
|
||||
"array": "cpp",
|
||||
"atomic": "cpp",
|
||||
"bit": "cpp",
|
||||
"cctype": "cpp",
|
||||
"charconv": "cpp",
|
||||
"chrono": "cpp",
|
||||
"clocale": "cpp",
|
||||
"cmath": "cpp",
|
||||
"codecvt": "cpp",
|
||||
"compare": "cpp",
|
||||
"concepts": "cpp",
|
||||
"csignal": "cpp",
|
||||
"cstdarg": "cpp",
|
||||
"cstddef": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"cstdio": "cpp",
|
||||
"cstdlib": "cpp",
|
||||
"cstring": "cpp",
|
||||
"ctime": "cpp",
|
||||
"cwchar": "cpp",
|
||||
"cwctype": "cpp",
|
||||
"deque": "cpp",
|
||||
"string": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"vector": "cpp",
|
||||
"exception": "cpp",
|
||||
"algorithm": "cpp",
|
||||
"functional": "cpp",
|
||||
"iterator": "cpp",
|
||||
"memory": "cpp",
|
||||
"memory_resource": "cpp",
|
||||
"numeric": "cpp",
|
||||
"optional": "cpp",
|
||||
"random": "cpp",
|
||||
"ratio": "cpp",
|
||||
"string_view": "cpp",
|
||||
"system_error": "cpp",
|
||||
"tuple": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"utility": "cpp",
|
||||
"format": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"iomanip": "cpp",
|
||||
"iosfwd": "cpp",
|
||||
"iostream": "cpp",
|
||||
"istream": "cpp",
|
||||
"limits": "cpp",
|
||||
"new": "cpp",
|
||||
"numbers": "cpp",
|
||||
"ranges": "cpp",
|
||||
"span": "cpp",
|
||||
"sstream": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"typeinfo": "cpp",
|
||||
"variant": "cpp",
|
||||
"text_encoding": "cpp",
|
||||
"queue": "cpp",
|
||||
"filesystem": "cpp",
|
||||
"any": "cpp",
|
||||
"condition_variable": "cpp",
|
||||
"coroutine": "cpp",
|
||||
"source_location": "cpp",
|
||||
"future": "cpp",
|
||||
"mutex": "cpp",
|
||||
"stop_token": "cpp",
|
||||
"thread": "cpp",
|
||||
"list": "cpp",
|
||||
"semaphore": "cpp",
|
||||
"stdfloat": "cpp",
|
||||
"fstream": "cpp"
|
||||
}
|
||||
}
|
|
@ -24,12 +24,11 @@ RUN mkdir -p build \
|
|||
|
||||
FROM docker.io/nginx:${NGINX_TAG}
|
||||
|
||||
ENV DOMAIN="example.localhost"
|
||||
#ENV DOMAIN="example.localhost"
|
||||
ENV SERVER_ID="server"
|
||||
ENV RELOAD_FILE="/var/run/nginx-reload"
|
||||
ENV ACME_CHALLENGE_URL="http://acme-challenge.${DOMAIN}/.well-known/acme-challenge/"
|
||||
ENV CONTROL_DOMAIN="control.localhost"
|
||||
ENV CONTROL_TOKEN="Tr0ub4dor&3"
|
||||
ENV ACME_CHALLENGE_URL='http://acme-challenge.${DOMAIN}/.well-known/acme-challenge'
|
||||
#ENV CONTROL_DOMAIN="control.localhost"
|
||||
#ENV CONTROL_TOKEN="Tr0ub4dor&3"
|
||||
|
||||
COPY nginx /etc/nginx/
|
||||
COPY certificates /etc/ssl/
|
||||
|
|
28
README.md
28
README.md
|
@ -1,30 +1,30 @@
|
|||
This is a container that helps host a static website.
|
||||
This is a container that helps host a website.
|
||||
|
||||
## Configuration
|
||||
|
||||
**Requires** the following mounts:
|
||||
- `/etc/ssl/certs/$DOMAIN`: For certificates (`fullchain.pem` and `privkey.pem`)
|
||||
- `/var/www/html/$DOMAIN`: Website files, `index.html` goes right here
|
||||
- `/etc/ssl/certs/<domain>`: For certificates, `fullchain.pem` and `privkey.pem`. Also includes the control domain. Can be read-only if you don't use the built-in (control server) certificate management.
|
||||
- `/var/www/html/<domain>`: Website files, `index.html` goes right here, mount this read-only
|
||||
|
||||
**Requires** the following environment variables:
|
||||
- `DOMAIN`: The domain
|
||||
- `ACME_CHALLENGE_HOST`: The source of `.well-known/acme-challenge`
|
||||
- `DOMAINS`: One or more domains to handle, separated with `,`s or spaces
|
||||
- `ACME_CHALLENGE_HOST`: The source of `.well-known/acme-challenge`. Proxied, may be internal. Don't forget to add
|
||||
- `CONTROL_DOMAIN`: Domain to access the control server
|
||||
- `CONTROL_TOKEN`: Token to access the control server
|
||||
|
||||
You're also encouraged to provide your own:
|
||||
- `/etc/ssl/dhparam.pem`, generated with:
|
||||
- `/etc/ssl/dhparam.pem` (read-only), generated with:
|
||||
```bash
|
||||
openssl dhparam -out dhparam.pem 4096
|
||||
```
|
||||
- `/etc/ssl/snakeoil.key` & `/etc/ssl/snakeoil.pem`, generated with:
|
||||
- `/etc/ssl/snakeoil.key` (read-only) & `/etc/ssl/snakeoil.pem` (read-only), generated with:
|
||||
```bash
|
||||
openssl req -new -x509 -days 398 -noenc -out snakeoil.pem -keyout snakeoil.key -subj "/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd"
|
||||
```
|
||||
- `SERVER_ID`: How to call this server (for info)
|
||||
- **Mount** `/var/run/nginx-reload`: modify this file to reload nginx
|
||||
- `SERVER_ID`: Label this server (informational, not used currently)
|
||||
|
||||
## Control server
|
||||
Authorize as you normally would with a Bearer token.
|
||||
Authorize as you normally do with a Bearer token.
|
||||
|
||||
If you get an empty response, watch the status code!
|
||||
|
||||
|
@ -41,5 +41,13 @@ Endpoints:
|
|||
- `/reload`: Reloads nginx
|
||||
- `/certificate/<domain>`: Uploads a certificate (POST, upload like a form with field names `certificate` and `private_key`)
|
||||
|
||||
## Custom nginx configs
|
||||
Put custom configuration templates in the `/templates/` directory
|
||||
|
||||
Stock config files, mount (read-only) to replace:
|
||||
- Control: `control.conf.template` ([default](nginx/templates/control.conf.template))
|
||||
- Website: `website.conf.btemplate` ([default](nginx/templates/website.conf.template)) (not used hence diff extension)
|
||||
- Specific website: `website-$DOMAIN.conf.template` (generated)
|
||||
|
||||
## TODO
|
||||
- support for multiple domains
|
|
@ -4,7 +4,7 @@ services:
|
|||
context: .
|
||||
dockerfile: Containerfile
|
||||
environment:
|
||||
DOMAIN: example.localhost
|
||||
DOMAINS: example.localhost
|
||||
SERVER_ID: development
|
||||
ACME_CHALLENGE_URL: https://files.catbox.moe/xpfyfh
|
||||
CONTROL_DOMAIN: control.localhost
|
||||
|
@ -16,4 +16,5 @@ services:
|
|||
volumes:
|
||||
- ./run/html:/var/www/html
|
||||
- ./run/certs:/etc/ssl/certs
|
||||
- ./run/reload:/var/run/nginx-reload
|
||||
|
||||
|
17
docker-entrypoint.d/1-check-environment.sh
Normal file
17
docker-entrypoint.d/1-check-environment.sh
Normal file
|
@ -0,0 +1,17 @@
|
|||
#!/bin/sh
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
: "${DOMAINS?Error: DOMAINS environment variable is not set.}"
|
||||
: "${CONTROL_DOMAIN?Error: CONTROL_DOMAIN environment variable is not set.}"
|
||||
: "${CONTROL_TOKEN?Error: CONTROL_TOKEN environment variable is not set.}"
|
||||
|
||||
for domain in ${DOMAINS//,/ }; do
|
||||
echo "Detected domain: $domain"
|
||||
|
||||
if [ "$domain" = "$CONTROL_DOMAIN" ]; then
|
||||
echo "Domain must not equal control domain"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
14
docker-entrypoint.d/10-generate-templates.sh
Normal file
14
docker-entrypoint.d/10-generate-templates.sh
Normal file
|
@ -0,0 +1,14 @@
|
|||
#!/bin/sh
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
if [ -e "/templates" ]; then
|
||||
cp -r templates/. /etc/nginx/templates/
|
||||
fi
|
||||
|
||||
for domain in ${DOMAINS//,/ }; do
|
||||
cp -n /etc/nginx/templates/website.conf.btemplate /etc/nginx/templates/website-$domain.conf.template
|
||||
|
||||
sed -i "s/\$DOMAIN/$domain/g" /etc/nginx/templates/website-$domain.conf.template
|
||||
sed -i "s/\${DOMAIN}/$domain/g" /etc/nginx/templates/website-$domain.conf.template
|
||||
done
|
|
@ -1,29 +0,0 @@
|
|||
|
||||
#!/bin/sh
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
: "${DOMAIN?Error: DOMAIN environment variable is not set.}"
|
||||
: "${CONTROL_DOMAIN?Error: CONTROL_DOMAIN environment variable is not set.}"
|
||||
|
||||
CERTIFICATE_ROOT="/etc/ssl"
|
||||
|
||||
setup_snakeoil_cert() {
|
||||
local domain="$1"
|
||||
local cert_dir="$CERTIFICATE_ROOT/certs/$domain"
|
||||
|
||||
mkdir -p "$cert_dir"
|
||||
|
||||
cp -n "$CERTIFICATE_ROOT/snakeoil.pem" "$cert_dir/fullchain.pem"
|
||||
cp -n "$CERTIFICATE_ROOT/snakeoil.key" "$cert_dir/privkey.pem"
|
||||
|
||||
chmod 644 "$cert_dir/fullchain.pem"
|
||||
chmod 600 "$cert_dir/privkey.pem"
|
||||
}
|
||||
|
||||
for domain_to_setup in "$DOMAIN" "$CONTROL_DOMAIN"; do
|
||||
echo "Ensuring certificate for domain: $domain_to_setup"
|
||||
setup_snakeoil_cert "$domain_to_setup"
|
||||
done
|
||||
|
||||
echo "Placeholder certificate setup complete."
|
23
docker-entrypoint.d/5-initialize-certificates.sh
Executable file
23
docker-entrypoint.d/5-initialize-certificates.sh
Executable file
|
@ -0,0 +1,23 @@
|
|||
#!/bin/sh
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
CERTIFICATE_ROOT="/etc/ssl"
|
||||
|
||||
setup_snakeoil_cert() {
|
||||
local domain="$1"
|
||||
local cert_dir="$CERTIFICATE_ROOT/certs/$domain"
|
||||
|
||||
mkdir -p "$cert_dir"
|
||||
|
||||
cp -n "$CERTIFICATE_ROOT/snakeoil.key" "$cert_dir/privkey.pem"
|
||||
cp -n "$CERTIFICATE_ROOT/snakeoil.pem" "$cert_dir/fullchain.pem"
|
||||
|
||||
chmod 600 "$cert_dir/privkey.pem" || true
|
||||
chmod 600 "$cert_dir/fullchain.pem" || true
|
||||
}
|
||||
|
||||
for domain in ${DOMAINS//,/ } $CONTROL_DOMAIN; do
|
||||
echo "Ensuring certificate for domain: $domain"
|
||||
setup_snakeoil_cert "$domain"
|
||||
done
|
|
@ -6,4 +6,6 @@ CONTROL_SERVER_SOCKET="/var/run/control-server.sock"
|
|||
NGINX_PID_FILE="/var/run/nginx.pid"
|
||||
CERTIFICATE_PATH="/etc/ssl/certs"
|
||||
|
||||
# TODO run this as user
|
||||
|
||||
control_server $CONTROL_SERVER_SOCKET $NGINX_PID_FILE $CERTIFICATE_PATH &
|
|
@ -13,9 +13,9 @@ http {
|
|||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
# looking for $remote_addr and $http_user_agent?
|
||||
log_format main '$remote_user [$time_local] "$request" '
|
||||
'$status $body_bytes_sent bytes "$http_referer" '
|
||||
'"$http_x_forwarded_for"';
|
||||
'$status $body_bytes_sent bytes "$http_referer" ';
|
||||
|
||||
access_log /var/log/nginx/access.log main; # /dev/null to disable
|
||||
|
||||
|
@ -57,7 +57,7 @@ http {
|
|||
ssl_stapling_verify on;
|
||||
|
||||
# async 'resolver' is important for proper operation of OCSP stapling
|
||||
resolver [2001:4860:4860::8888] 8.8.8.8;
|
||||
# resolver [2001:4860:4860::8888] 8.8.8.8;
|
||||
|
||||
# If certificates are marked OCSP Must-Staple, consider managing the
|
||||
# OCSP stapling cache with an external script, e.g. certbot-ocsp-fetcher
|
||||
|
|
|
@ -18,4 +18,10 @@ server {
|
|||
|
||||
proxy_pass http://unix:/var/run/control-server.sock;
|
||||
}
|
||||
|
||||
location /.well-known/acme-challenge {
|
||||
set $target ${ACME_CHALLENGE_URL};
|
||||
proxy_buffering off;
|
||||
proxy_pass $target;
|
||||
}
|
||||
}
|
|
@ -13,7 +13,8 @@ server {
|
|||
index index.html;
|
||||
|
||||
location /.well-known/acme-challenge {
|
||||
set $target ${ACME_CHALLENGE_URL};
|
||||
proxy_buffering off;
|
||||
proxy_pass ${ACME_CHALLENGE_URL};
|
||||
proxy_pass $target;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue