Version 0.6.0 (2026-04-01)
Changes:
- add config validation option via Makefile
- add `default-http{,s}-port` commands to add_servers.py
- update add_servers.py to pass generic parameters to servers in templates
- add nginx_conf.d directory usage for more than one custom nginx configurations
- rename `port` and `ssl_port` to `http{,s}_port` for templates
- add `http{,s}_custom_params` to templates
This commit is contained in:
1
.dockerignore
Normal file
1
.dockerignore
Normal file
@@ -0,0 +1 @@
|
|||||||
|
/.venv
|
||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -5,3 +5,4 @@
|
|||||||
*.env
|
*.env
|
||||||
/.venv
|
/.venv
|
||||||
/docker-compose.y*ml
|
/docker-compose.y*ml
|
||||||
|
/data
|
||||||
|
|||||||
8
Makefile
Normal file
8
Makefile
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
up:
|
||||||
|
# this script only starts nginx, make sure that certbot is launched as well
|
||||||
|
docker compose build
|
||||||
|
docker compose run --rm --name validate-config --entrypoint "/usr/sbin/nginx" nginx -t
|
||||||
|
docker compose up -d nginx
|
||||||
|
|
||||||
|
down:
|
||||||
|
docker compose down
|
||||||
20
README.md
20
README.md
@@ -1,9 +1,13 @@
|
|||||||
# ssl_nginx hosting
|
# ssl_nginx hosting
|
||||||
|
|
||||||
|
Version 0.6.0 (2026-03-25)
|
||||||
|
|
||||||
## Preparation
|
## Preparation
|
||||||
|
|
||||||
1. Copy and edit (if needed) [nginx/nginx.conf.j2](nginx/nginx.conf.j2.example) file.
|
1. Create and fill `nginx/nginx.conf.j2` jinja template file ([example for global nginx](./nginx/examples/nginx.conf.j2)
|
||||||
2. Add your certified domains to nginx/domains.txt file ([example](nginx/domains.txt.example)).
|
and for [nginx between other nginx and backends](./nginx/examples/nginx.middle.conf.j2)). For most cases you would
|
||||||
|
not need to change the tempalte, but for sure it is not included by default.
|
||||||
|
2. Add your certified domains to `nginx/domains.txt` file ([example](nginx/examples/domains.txt)).
|
||||||
|
|
||||||
These domains will be used by _certbot_ to monitor and update (if possible) certificates. _Nginx_ will also setup
|
These domains will be used by _certbot_ to monitor and update (if possible) certificates. _Nginx_ will also setup
|
||||||
http server for the given entries.
|
http server for the given entries.
|
||||||
@@ -12,7 +16,10 @@
|
|||||||
use https with certificates at the given path. That will fail nginx startup if the certificate
|
use https with certificates at the given path. That will fail nginx startup if the certificate
|
||||||
to at least one domain is missing (--http-only option will skip domains.txt check).
|
to at least one domain is missing (--http-only option will skip domains.txt check).
|
||||||
|
|
||||||
3. Add your servers section configuration to nginx/servers.yaml ([example](nginx/servers.yaml.example)).
|
3. Add your servers section configuration to `nginx/servers.yaml` ([example](nginx/examples/servers.yaml)).
|
||||||
|
4. Set `EMAIL` value to .env file for certbot configuration
|
||||||
|
5. Copy and tune [docker-compose.yaml example](./docker-compose.yaml.example)
|
||||||
|
6. Optionally, if additional nginx configurations are used, they can be placed to `nginx/nginx_conf.d` directory
|
||||||
|
|
||||||
User email used for certbot can be set as environment variable at build process or in .env file.
|
User email used for certbot can be set as environment variable at build process or in .env file.
|
||||||
|
|
||||||
@@ -22,8 +29,11 @@ For the first time you should run (run_once.d-c.yml)[run_once.d-c.yml] docker-co
|
|||||||
|
|
||||||
You can use (run_once.sh)[run_once.sh] script for this.
|
You can use (run_once.sh)[run_once.sh] script for this.
|
||||||
|
|
||||||
After it, `docker compose up` should do the trick. Certificates update attempt will be performed automatically at 02:15
|
After it, `docker compose up` (or `make up` to also remove validation container) should do the trick.
|
||||||
on each seventh day of month. (set in Dockerfile of _certbot_ and _nginx_).
|
Certificates update attempt will be performed automatically at 02:15 on each seventh day of month. (set in Dockerfile of _certbot_ and _nginx_).
|
||||||
|
|
||||||
|
On launch config is validated with correct certificates and environment in `validate-config` step, so there should not be a case when incorrect
|
||||||
|
config replaces correct one on update attempt.
|
||||||
|
|
||||||
## certbot_manual.sh
|
## certbot_manual.sh
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ services:
|
|||||||
context: ./certbot
|
context: ./certbot
|
||||||
args:
|
args:
|
||||||
EMAIL: ${EMAIL}
|
EMAIL: ${EMAIL}
|
||||||
volumes:
|
volumes: &volumes-config
|
||||||
- ssl:/ssl
|
- ssl:/ssl
|
||||||
- letsencrypt:/etc/letsencrypt
|
- letsencrypt:/etc/letsencrypt
|
||||||
depends_on:
|
depends_on:
|
||||||
@@ -15,18 +15,31 @@ services:
|
|||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
||||||
nginx:
|
nginx:
|
||||||
container_name: 'global-nginx'
|
container_name: "global-nginx"
|
||||||
build: ./nginx
|
build: ./nginx
|
||||||
volumes:
|
volumes: *volumes-config
|
||||||
- ssl:/ssl
|
|
||||||
- letsencrypt:/etc/letsencrypt
|
|
||||||
ports:
|
ports:
|
||||||
- 80:80
|
- 80:80
|
||||||
- 443:443
|
- 443:443
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
logging:
|
||||||
|
driver: "json-file"
|
||||||
|
options:
|
||||||
|
max-size: "50m"
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
ssl:
|
ssl:
|
||||||
name: ssl_nginx_ssl
|
name: ssl_nginx_ssl
|
||||||
|
driver: local
|
||||||
|
driver_opts:
|
||||||
|
type: "none"
|
||||||
|
o: "bind"
|
||||||
|
device: "./data/ssl"
|
||||||
|
|
||||||
letsencrypt:
|
letsencrypt:
|
||||||
name: ssl_nginx_letsencrypt
|
name: ssl_nginx_letsencrypt
|
||||||
|
driver: local
|
||||||
|
driver_opts:
|
||||||
|
type: "none"
|
||||||
|
o: "bind"
|
||||||
|
device: "./data/letsencrypt"
|
||||||
|
|||||||
@@ -7,13 +7,17 @@ COPY servers.yaml /servers.yaml
|
|||||||
COPY domains.txt /domains.txt
|
COPY domains.txt /domains.txt
|
||||||
COPY nginx.conf.j2 /nginx.conf.j2
|
COPY nginx.conf.j2 /nginx.conf.j2
|
||||||
|
|
||||||
RUN python /add_servers.py --nginx-template /nginx.conf.j2 -o /nginx.conf --domains_list_txt /domains.txt --servers-config servers.yaml --certificates-path /ssl
|
RUN python /add_servers.py --nginx-template /nginx.conf.j2 -o /nginx.conf --domains-list-txt /domains.txt --servers-config servers.yaml --certificates-path /ssl
|
||||||
|
|
||||||
# service
|
# service
|
||||||
|
|
||||||
FROM nginx:alpine
|
FROM nginx:alpine
|
||||||
|
|
||||||
|
RUN apk add curl bash
|
||||||
|
|
||||||
COPY --from=builder /nginx.conf /etc/nginx/nginx.conf
|
COPY --from=builder /nginx.conf /etc/nginx/nginx.conf
|
||||||
|
RUN rm -rf /etc/nginx/conf.d
|
||||||
|
COPY nginx_conf.d /etc/nginx/conf.d
|
||||||
COPY domains.txt /domains.txt
|
COPY domains.txt /domains.txt
|
||||||
|
|
||||||
RUN echo "20 2 */7 * * nginx -s reload" > /etc/crontabs/root && \
|
RUN echo "20 2 */7 * * nginx -s reload" > /etc/crontabs/root && \
|
||||||
|
|||||||
@@ -4,52 +4,43 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
import os
|
||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
import jinja2
|
import jinja2
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class Server:
|
class Server:
|
||||||
"""Server entry for nginx.conf file."""
|
"""Server entry for nginx.conf file."""
|
||||||
|
|
||||||
name: str
|
DEFAULT_HTTP_PORT = 80
|
||||||
all_names: str | None = None
|
DEFAULT_HTTPS_PORT = 443
|
||||||
proxy_pass: str | None = None
|
|
||||||
certificate_dir: str | None = None
|
|
||||||
port: int = None
|
|
||||||
ssl_port: int = None
|
|
||||||
server_options: list[str] = field(default_factory=list)
|
|
||||||
location_options: list[str] = field(default_factory=list)
|
|
||||||
|
|
||||||
certificates_path: str = "/etc/letsencrypt/live"
|
def __init__(
|
||||||
|
self,
|
||||||
|
http_port: int = ...,
|
||||||
|
https_port: int = ...,
|
||||||
|
**kwargs: dict[str, Any],
|
||||||
|
):
|
||||||
|
if http_port is ...:
|
||||||
|
http_port = Server.DEFAULT_HTTP_PORT
|
||||||
|
if https_port is ...:
|
||||||
|
https_port = Server.DEFAULT_HTTPS_PORT
|
||||||
|
self._params = dict(kwargs)
|
||||||
|
for additional_name, additional_value in zip(
|
||||||
|
["http_port", "https_port"],
|
||||||
|
[http_port, https_port],
|
||||||
|
):
|
||||||
|
self._params[additional_name] = additional_value
|
||||||
|
|
||||||
def __post_init__(self) -> None:
|
def __getattr__(self, name) -> Any:
|
||||||
if self.server_options is None:
|
return self._params.get(name)
|
||||||
self.server_options = []
|
|
||||||
if self.location_options is None:
|
|
||||||
self.location_options = []
|
|
||||||
if self.all_names is None:
|
|
||||||
self.all_names = self.name
|
|
||||||
if self.port is None:
|
|
||||||
self.port = 80
|
|
||||||
if self.ssl_port is None:
|
|
||||||
self.ssl_port = 443
|
|
||||||
|
|
||||||
def to_dict(self) -> dict:
|
def to_dict(self) -> dict:
|
||||||
"""Convert server class to dict for nginx.conf.j2 jinja2-template"""
|
"""Convert server class to dict for nginx.conf.j2 jinja2-template"""
|
||||||
return {
|
return dict(self._params)
|
||||||
"name": self.name,
|
|
||||||
"all_names": self.all_names,
|
|
||||||
"proxy_pass": self.proxy_pass,
|
|
||||||
"server_options": self.server_options,
|
|
||||||
"location_options": self.location_options,
|
|
||||||
"certificate_dir": self.certificate_dir,
|
|
||||||
"port": self.port,
|
|
||||||
"ssl_port": self.ssl_port,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
@@ -59,6 +50,8 @@ class CLIParams:
|
|||||||
nginx_template: str
|
nginx_template: str
|
||||||
domains_list_txt: str
|
domains_list_txt: str
|
||||||
servers_config: str
|
servers_config: str
|
||||||
|
default_http_port: str
|
||||||
|
default_https_port: str
|
||||||
certificates_path: str
|
certificates_path: str
|
||||||
http_only: bool
|
http_only: bool
|
||||||
output: str | None
|
output: str | None
|
||||||
@@ -69,7 +62,7 @@ def main() -> None:
|
|||||||
parser = argparse.ArgumentParser("add-servers", description="Add domain servers to a given nginx.conf file")
|
parser = argparse.ArgumentParser("add-servers", description="Add domain servers to a given nginx.conf file")
|
||||||
parser.add_argument("--nginx-template", "-f", required=True, help="Path to nginx.conf.j2 template file")
|
parser.add_argument("--nginx-template", "-f", required=True, help="Path to nginx.conf.j2 template file")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--domains_list_txt",
|
"--domains-list-txt",
|
||||||
"-d",
|
"-d",
|
||||||
required=True,
|
required=True,
|
||||||
help="Path to file with domains which have ssl certificates",
|
help="Path to file with domains which have ssl certificates",
|
||||||
@@ -81,6 +74,18 @@ def main() -> None:
|
|||||||
default=None,
|
default=None,
|
||||||
help="Path to servers configuration yaml file",
|
help="Path to servers configuration yaml file",
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--default-http-port",
|
||||||
|
required=False,
|
||||||
|
default=80,
|
||||||
|
help="Default port for https protocol",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--default-https-port",
|
||||||
|
required=False,
|
||||||
|
default=443,
|
||||||
|
help="Default port for https protocol",
|
||||||
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--certificates-path",
|
"--certificates-path",
|
||||||
"-c",
|
"-c",
|
||||||
@@ -97,6 +102,9 @@ def main() -> None:
|
|||||||
|
|
||||||
args: CLIParams = parser.parse_args()
|
args: CLIParams = parser.parse_args()
|
||||||
|
|
||||||
|
Server.DEFAULT_HTTP_PORT = args.default_http_port
|
||||||
|
Server.DEFAULT_HTTPS_PORT = args.default_https_port
|
||||||
|
|
||||||
if args.domains_list_txt is not None:
|
if args.domains_list_txt is not None:
|
||||||
with open(args.domains_list_txt, "r", encoding="utf-8") as file:
|
with open(args.domains_list_txt, "r", encoding="utf-8") as file:
|
||||||
domains_with_certs = [
|
domains_with_certs = [
|
||||||
@@ -117,22 +125,21 @@ def main() -> None:
|
|||||||
servers: dict[str, dict[str, Any]] = data["servers"]
|
servers: dict[str, dict[str, Any]] = data["servers"]
|
||||||
|
|
||||||
for server_name, params in servers.items():
|
for server_name, params in servers.items():
|
||||||
nginx_servers.append(
|
params_part = dict(params)
|
||||||
Server(
|
|
||||||
name=server_name,
|
|
||||||
all_names = params.get(
|
all_names = params.get(
|
||||||
"all_names",
|
"all_names",
|
||||||
None if "*" not in server_name else f"{server_name} {server_name.replace('*.', '', 1)}",
|
None if "*" not in server_name else f"{server_name} {server_name.replace('*.', '', 1)}",
|
||||||
),
|
|
||||||
proxy_pass=params.get("proxy_pass"),
|
|
||||||
certificate_dir=_get_certificate_path(
|
|
||||||
args.http_only, domains_with_certs, args.certificates_path, params.get("certificate_name") or server_name
|
|
||||||
),
|
|
||||||
port=params.get("port"),
|
|
||||||
ssl_port=params.get("ssl_port"),
|
|
||||||
server_options=params.get("server_options"),
|
|
||||||
location_options=params.get("location_options"),
|
|
||||||
)
|
)
|
||||||
|
certificate_dir = _get_certificate_path(
|
||||||
|
http_only=args.http_only,
|
||||||
|
domains_with_certs=domains_with_certs,
|
||||||
|
base_certs_path=args.certificates_path,
|
||||||
|
server_name=params.get("certificate_name") or server_name,
|
||||||
|
)
|
||||||
|
params_part.pop("all_names", None)
|
||||||
|
params_part.pop("certificate_name", None)
|
||||||
|
nginx_servers.append(
|
||||||
|
Server(name=server_name, all_names=all_names, certificate_dir=certificate_dir, **params_part)
|
||||||
)
|
)
|
||||||
for domain in domains_with_certs:
|
for domain in domains_with_certs:
|
||||||
if not any(
|
if not any(
|
||||||
@@ -140,8 +147,7 @@ def main() -> None:
|
|||||||
(server.all_names is None and domain == server.name)
|
(server.all_names is None and domain == server.name)
|
||||||
or (
|
or (
|
||||||
server.all_names is not None
|
server.all_names is not None
|
||||||
and f" {domain}" in server.all_names
|
and (f" {domain}" in server.all_names or server.all_names.startswith(domain))
|
||||||
or server.all_names.startswith(domain)
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
for server in nginx_servers
|
for server in nginx_servers
|
||||||
|
|||||||
@@ -1,8 +1,24 @@
|
|||||||
{#- variables ~ examples: #}
|
{# input variables ~ examples:
|
||||||
{#- acme_challenge_location ~ /ssl/: #}
|
- acme_challenge_location ~ /ssl/:
|
||||||
{#- resolver ~ 127.0.0.11: #}
|
- resolver ~ 127.0.0.11:
|
||||||
{#- servers ~ ["name": ..., ("proxy_pass": ..., "server_options": ..., "location_options": ..., "all_names": ..., "port": ..., "ssl_port": ...)]: #}
|
- servers
|
||||||
{#- #}user nginx;
|
- name ~ doma.in,
|
||||||
|
- all_names ~ doma.in testing.doma.in
|
||||||
|
- proxy_pass ~ http://localhost:3333
|
||||||
|
- certificate_dir ~ /ssl/other.doma.in (configured by certificate_name)
|
||||||
|
- server_options
|
||||||
|
- opt_1;
|
||||||
|
...
|
||||||
|
- location_options
|
||||||
|
- opt_1;
|
||||||
|
...
|
||||||
|
- http_port ~ 80
|
||||||
|
- https_port ~ 443
|
||||||
|
- http_custom_params ~ proxy_protocol
|
||||||
|
- https_custom_params ~ proxy_protocol
|
||||||
|
-#}
|
||||||
|
|
||||||
|
user nginx;
|
||||||
worker_processes auto;
|
worker_processes auto;
|
||||||
|
|
||||||
error_log /var/log/nginx/error.log notice;
|
error_log /var/log/nginx/error.log notice;
|
||||||
@@ -31,9 +47,12 @@ http {
|
|||||||
{%- for server in servers %}
|
{%- for server in servers %}
|
||||||
{# #}
|
{# #}
|
||||||
server {
|
server {
|
||||||
listen {{ server["port"] or 80 }};
|
{%- if server["http_port"] %}
|
||||||
{%- if server["certificate_dir"] is not none %}
|
listen {{ server["http_port"] }} {{- " " + server["http_custom_params"] if server["http_custom_params"] else ""}};
|
||||||
listen {{ server["ssl_port"] or 443 }} ssl;
|
{%- endif %}
|
||||||
|
|
||||||
|
{%- if server["certificate_dir"] %}
|
||||||
|
listen {{ server["https_port"] }} ssl {{- " " + server["https_custom_params"] if server["https_custom_params"] else ""}};
|
||||||
ssl_certificate {{ server["certificate_dir"] }}/fullchain.pem;
|
ssl_certificate {{ server["certificate_dir"] }}/fullchain.pem;
|
||||||
ssl_certificate_key {{ server["certificate_dir"] }}/privkey.pem;
|
ssl_certificate_key {{ server["certificate_dir"] }}/privkey.pem;
|
||||||
|
|
||||||
@@ -45,21 +64,21 @@ http {
|
|||||||
|
|
||||||
server_name {{ server["all_names"] or server["name"] }};
|
server_name {{ server["all_names"] or server["name"] }};
|
||||||
|
|
||||||
{%- if acme_challenge_location is not none %}
|
{%- if acme_challenge_location %}
|
||||||
{# #}
|
{# #}
|
||||||
location /.well-known/acme-challenge {
|
location /.well-known/acme-challenge {
|
||||||
root {{ acme_challenge_location }};
|
root {{ acme_challenge_location }};
|
||||||
}
|
}
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
|
||||||
{%- if server["server_options"]|length > 0 %}
|
{%- if server["server_options"] %}
|
||||||
{# #}
|
{# #}
|
||||||
{%- for server_option in server["server_options"] %}
|
{%- for server_option in server["server_options"] %}
|
||||||
{{ server_option }}
|
{{ server_option }}
|
||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
|
||||||
{%- if server["proxy_pass"] is not none %}
|
{%- if server["proxy_pass"] %}
|
||||||
{# #}
|
{# #}
|
||||||
location / {
|
location / {
|
||||||
resolver {{ resolver }};
|
resolver {{ resolver }};
|
||||||
@@ -68,9 +87,12 @@ http {
|
|||||||
|
|
||||||
proxy_set_header Host $host:$server_port;
|
proxy_set_header Host $host:$server_port;
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
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;
|
||||||
|
proxy_set_header X-Forwarded-Port $server_port;
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
|
||||||
{%- if server["location_options"]|length > 0 %}
|
{%- if server["location_options"] %}
|
||||||
{# #}
|
{# #}
|
||||||
{%- for location_option in server["location_options"] %}
|
{%- for location_option in server["location_options"] %}
|
||||||
{{ location_option }}
|
{{ location_option }}
|
||||||
@@ -81,3 +103,5 @@ http {
|
|||||||
}
|
}
|
||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
include /etc/nginx/conf.d/*.conf;
|
||||||
131
nginx/examples/nginx.middle.conf.j2
Normal file
131
nginx/examples/nginx.middle.conf.j2
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
{# input variables ~ examples:
|
||||||
|
- acme_challenge_location ~ /ssl/:
|
||||||
|
- resolver ~ 127.0.0.11:
|
||||||
|
- servers
|
||||||
|
- name ~ doma.in,
|
||||||
|
- all_names ~ doma.in testing.doma.in
|
||||||
|
- proxy_pass ~ http://localhost:3333
|
||||||
|
- certificate_dir ~ /ssl/other.doma.in (configured by certificate_name parameter)
|
||||||
|
- server_options
|
||||||
|
- opt_1;
|
||||||
|
...
|
||||||
|
- location_options
|
||||||
|
- opt_1;
|
||||||
|
...
|
||||||
|
- http_port ~ 80
|
||||||
|
- https_port ~ 443
|
||||||
|
- http_custom_params ~ proxy_protocol
|
||||||
|
- https_custom_params ~ proxy_protocol
|
||||||
|
-#}
|
||||||
|
|
||||||
|
user nginx;
|
||||||
|
worker_processes auto;
|
||||||
|
|
||||||
|
error_log /var/log/nginx/error.log notice;
|
||||||
|
pid /var/run/nginx.pid;
|
||||||
|
|
||||||
|
events {
|
||||||
|
worker_connections 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
http {
|
||||||
|
ssl_session_cache shared:SSL:10m;
|
||||||
|
ssl_session_timeout 10m;
|
||||||
|
server_tokens off;
|
||||||
|
gzip on;
|
||||||
|
|
||||||
|
proxy_connect_timeout 300;
|
||||||
|
proxy_send_timeout 600;
|
||||||
|
proxy_read_timeout 600;
|
||||||
|
send_timeout 600;
|
||||||
|
client_max_body_size 500M;
|
||||||
|
|
||||||
|
server {
|
||||||
|
return 404;
|
||||||
|
}
|
||||||
|
|
||||||
|
map $http_host $proxied_host {
|
||||||
|
"" $host;
|
||||||
|
default $http_host;
|
||||||
|
}
|
||||||
|
map $http_x_forwarded_port $proxied_port {
|
||||||
|
"" $server_port;
|
||||||
|
default $http_x_forwarded_port;
|
||||||
|
}
|
||||||
|
map $http_x_forwarded_host $proxied_x_host {
|
||||||
|
"" $host:$proxied_port;
|
||||||
|
default $http_x_forwarded_host;
|
||||||
|
}
|
||||||
|
map $http_x_forwarded_proto $proxied_proto {
|
||||||
|
"" $scheme;
|
||||||
|
default $http_x_forwarded_proto;
|
||||||
|
}
|
||||||
|
map $http_x_real_ip $proxied_remote_addr {
|
||||||
|
"" $remote_addr;
|
||||||
|
default $http_x_real_ip;
|
||||||
|
}
|
||||||
|
map $http_x_forwarded_for $proxied_forwarded_for {
|
||||||
|
"" $proxy_add_x_forwarded_for;
|
||||||
|
default $http_x_forwarded_for;
|
||||||
|
}
|
||||||
|
{%- for server in servers %}
|
||||||
|
{# #}
|
||||||
|
server {
|
||||||
|
{%- if server["http_port"] is not none %}
|
||||||
|
listen {{ server["http_port"] }} {{- "" if server["http_custom_params"] is none or server["http_custom_params"]|length == 0 else " " + server["http_custom_params"]}};
|
||||||
|
{%- endif %}
|
||||||
|
|
||||||
|
{%- if server["certificate_dir"] is not none %}
|
||||||
|
listen {{ server["https_port"] }} ssl {{- "" if server["https_custom_params"] is none or server["https_custom_params"]|length == 0 else " " + server["https_custom_params"]}};
|
||||||
|
ssl_certificate {{ server["certificate_dir"] }}/fullchain.pem;
|
||||||
|
ssl_certificate_key {{ server["certificate_dir"] }}/privkey.pem;
|
||||||
|
|
||||||
|
if ($scheme = 'http') {
|
||||||
|
return 302 https://$host$request_uri;
|
||||||
|
}
|
||||||
|
{%- endif %}
|
||||||
|
keepalive_timeout 70;
|
||||||
|
|
||||||
|
server_name {{ server["all_names"] or server["name"] }};
|
||||||
|
|
||||||
|
{%- if acme_challenge_location is not none %}
|
||||||
|
{# #}
|
||||||
|
location /.well-known/acme-challenge {
|
||||||
|
root {{ acme_challenge_location }};
|
||||||
|
}
|
||||||
|
{%- endif %}
|
||||||
|
|
||||||
|
{%- if server["server_options"]|length > 0 %}
|
||||||
|
{# #}
|
||||||
|
{%- for server_option in server["server_options"] %}
|
||||||
|
{{ server_option }}
|
||||||
|
{%- endfor %}
|
||||||
|
{%- endif %}
|
||||||
|
|
||||||
|
{%- if server["proxy_pass"] is not none %}
|
||||||
|
{# #}
|
||||||
|
location / {
|
||||||
|
resolver {{ resolver }};
|
||||||
|
set $host_{{ loop.index }} {{ server["proxy_pass"] }};
|
||||||
|
proxy_pass $host_{{ loop.index }};
|
||||||
|
|
||||||
|
proxy_set_header HOST $proxied_host;
|
||||||
|
proxy_set_header X-Forwarded-Host $proxied_x_host;
|
||||||
|
proxy_set_header X-Forwarded-Port $proxied_port;
|
||||||
|
proxy_set_header X-Forwarded-Proto $proxied_proto;
|
||||||
|
proxy_set_header X-Forwarded-For $proxied_forwarded_for;
|
||||||
|
proxy_set_header X-Real-IP $proxied_remote_addr;
|
||||||
|
|
||||||
|
{%- if server["location_options"]|length > 0 %}
|
||||||
|
{# #}
|
||||||
|
{%- for location_option in server["location_options"] %}
|
||||||
|
{{ location_option }}
|
||||||
|
{%- endfor %}
|
||||||
|
{%- endif %}
|
||||||
|
}
|
||||||
|
{%- endif %}
|
||||||
|
}
|
||||||
|
{%- endfor %}
|
||||||
|
}
|
||||||
|
|
||||||
|
include /etc/nginx/conf.d/*.conf;
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
resolver: 127.0.0.1
|
resolver: 127.0.0.1 # 127.0.0.11 for docker
|
||||||
acme_challenge_location: /etc/nginx/acme/
|
acme_challenge_location: /etc/nginx/acme/ # /ssl for docker volume
|
||||||
|
|
||||||
|
|
||||||
servers:
|
servers:
|
||||||
@@ -23,3 +23,9 @@ servers:
|
|||||||
- "proxy_buffering off;"
|
- "proxy_buffering off;"
|
||||||
- "proxy_request_buffering off;"
|
- "proxy_request_buffering off;"
|
||||||
- "client_max_body_size 0;"
|
- "client_max_body_size 0;"
|
||||||
|
- "http2 on;"
|
||||||
|
"custom.doma.in":
|
||||||
|
proxy_pass: "http://custom"
|
||||||
|
http_port: 4480
|
||||||
|
https_port: 4443
|
||||||
|
https_custom_params: "http2 proxy_protocol"
|
||||||
2
nginx/nginx_conf.d/.dockerignore
Normal file
2
nginx/nginx_conf.d/.dockerignore
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
/.gitignore
|
||||||
|
/.dockerignore
|
||||||
3
nginx/nginx_conf.d/.gitignore
vendored
Normal file
3
nginx/nginx_conf.d/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
*
|
||||||
|
!/.gitignore
|
||||||
|
!/.dockerignore
|
||||||
Reference in New Issue
Block a user