Skip to content

Commit c7309c9

Browse files
committed
add new server
1 parent b956d63 commit c7309c9

File tree

10 files changed

+453
-0
lines changed

10 files changed

+453
-0
lines changed

tarsh/certs.sh

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#!/bin/bash -e
2+
3+
##
4+
# Usage:
5+
# ./certs.sh ./nginx/certs foo.com www.foo.com,api.foo.com
6+
##
7+
8+
set -x
9+
10+
CERT_PATH=$1
11+
DOMAIN=$2
12+
test -n "$3" && DOMAINS=$DOMAIN,$3 || DOMAINS=$DOMAIN
13+
14+
docker stop nginx
15+
16+
sudo certbot certonly --standalone -d $DOMAINS
17+
18+
LIVE_PATH=/etc/letsencrypt/live/$DOMAIN
19+
CERT_FILE=$CERT_PATH/$DOMAIN
20+
21+
sudo cat $LIVE_PATH/fullchain.pem > $CERT_FILE.crt
22+
sudo cat $LIVE_PATH/privkey.pem > $CERT_FILE.key
23+
24+
test -f $CERT_FILE.dhparam.pem || openssl dhparam -out $CERT_FILE.dhparam.pem 2048
25+
26+
docker start nginx

tarsh/docker-compose.yml

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
nginx:
2+
image: nginx:alpine
3+
container_name: nginx
4+
restart: always
5+
volumes:
6+
- /etc/nginx/conf.d
7+
- ./nginx/proxy.conf:/etc/nginx/conf.d/proxy.conf
8+
- /opt/data/nginx_logs:/var/log/nginx
9+
- ./nginx/certs:/etc/nginx/certs
10+
ports:
11+
- "80:80"
12+
- "443:443"
13+
14+
dgen:
15+
#image: jwilder/docker-gen
16+
build: ./docker-gen
17+
volumes_from:
18+
- nginx
19+
volumes:
20+
- /var/run/docker.sock:/tmp/docker.sock:ro
21+
- ./nginx/nginx.tmpl:/etc/docker-gen/templates/nginx.tmpl
22+
command: "-notify-sighup nginx -watch /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf"
23+
24+
wordpress:
25+
#image: wordpress
26+
build: ./wordpress
27+
restart: always
28+
environment:
29+
WORDPRESS_DB_HOST: db
30+
WORDPRESS_DB_USER: wp-user
31+
WORDPRESS_DB_PASSWORD:
32+
WORDPRESS_DB_NAME: wpdb
33+
VIRTUAL_HOST: tarshari.in
34+
links:
35+
- db:db
36+
volumes:
37+
- ./wordpress/msmtprc:/etc/msmtprc
38+
- /opt/data/wp:/var/www/html
39+
40+
db:
41+
image: mysql:5.7
42+
restart: always
43+
environment:
44+
MYSQL_DATABASE: wpdb
45+
MYSQL_USER: wp-user
46+
MYSQL_PASSWORD:
47+
MYSQL_RANDOM_ROOT_PASSWORD: '1'
48+
volumes:
49+
- /opt/data/db:/var/lib/mysql
50+
51+
wg:
52+
build: ./wg
53+
volumes:
54+
- ./wg/wg0.conf:/etc/wireguard/wg0.conf
55+
ports:
56+
- 1194:1194/udp
57+
cap_add:
58+
- NET_ADMIN
59+
- SYS_MODULE

tarsh/docker-gen/Dockerfile

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
FROM alpine:latest
2+
3+
RUN apk -U add openssl
4+
5+
ENV VERSION 0.8.4
6+
ENV DOWNLOAD_URL https://github.com/bugficks/docker-gen/releases/download/$VERSION/docker-gen-alpine-linux-amd64-$VERSION.tar.gz
7+
ENV DOCKER_HOST unix:///tmp/docker.sock
8+
9+
RUN wget -qO- $DOWNLOAD_URL | tar xvz -C /usr/local/bin
10+
11+
ENTRYPOINT ["/usr/local/bin/docker-gen"]

tarsh/nginx/nginx.tmpl

Lines changed: 289 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,289 @@
1+
{{ $CurrentContainer := where $ "ID" .Docker.CurrentContainerID | first }}
2+
3+
{{ define "upstream" }}
4+
{{ if .Address }}
5+
{{/* If we got the containers from swarm and this container's port is published to host, use host IP:PORT */}}
6+
{{ if and .Container.Node.ID .Address.HostPort }}
7+
# {{ .Container.Node.Name }}/{{ .Container.Name }}
8+
server {{ .Container.Node.Address.IP }}:{{ .Address.HostPort }};
9+
{{/* If there is no swarm node or the port is not published on host, use container's IP:PORT */}}
10+
{{ else if .Network }}
11+
# {{ .Container.Name }}
12+
server {{ .Network.IP }}:{{ .Address.Port }};
13+
{{ end }}
14+
{{ else if .Network }}
15+
# {{ .Container.Name }}
16+
server {{ .Network.IP }} down;
17+
{{ end }}
18+
{{ end }}
19+
20+
# If we receive X-Forwarded-Proto, pass it through; otherwise, pass along the
21+
# scheme used to connect to this server
22+
map $http_x_forwarded_proto $proxy_x_forwarded_proto {
23+
default $http_x_forwarded_proto;
24+
'' $scheme;
25+
}
26+
27+
# If we receive X-Forwarded-Port, pass it through; otherwise, pass along the
28+
# server port the client connected to
29+
map $http_x_forwarded_port $proxy_x_forwarded_port {
30+
default $http_x_forwarded_port;
31+
'' $server_port;
32+
}
33+
34+
# If we receive Upgrade, set Connection to "upgrade"; otherwise, delete any
35+
# Connection header that may have been passed to this server
36+
map $http_upgrade $proxy_connection {
37+
default upgrade;
38+
'' close;
39+
}
40+
41+
# Set appropriate X-Forwarded-Ssl header
42+
map $scheme $proxy_x_forwarded_ssl {
43+
default off;
44+
https on;
45+
}
46+
47+
gzip_types text/plain text/css application/javascript application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
48+
49+
log_format vhost '$host $remote_addr - $remote_user [$time_local] '
50+
'"$request" $status $body_bytes_sent '
51+
'"$http_referer" "$http_user_agent"';
52+
53+
access_log off;
54+
55+
{{ if (exists "/etc/nginx/proxy.conf") }}
56+
include /etc/nginx/proxy.conf;
57+
{{ else }}
58+
# HTTP 1.1 support
59+
proxy_http_version 1.1;
60+
proxy_buffering off;
61+
proxy_set_header Host $http_host;
62+
proxy_set_header Upgrade $http_upgrade;
63+
proxy_set_header Connection $proxy_connection;
64+
proxy_set_header X-Real-IP $remote_addr;
65+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
66+
proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto;
67+
proxy_set_header X-Forwarded-Ssl $proxy_x_forwarded_ssl;
68+
proxy_set_header X-Forwarded-Port $proxy_x_forwarded_port;
69+
70+
# Mitigate httpoxy attack (see README for details)
71+
proxy_set_header Proxy "";
72+
{{ end }}
73+
74+
{{ $enable_ipv6 := eq (or ($.Env.ENABLE_IPV6) "") "true" }}
75+
server {
76+
server_name _; # This is just an invalid value which will never trigger on a real hostname.
77+
listen 80;
78+
{{ if $enable_ipv6 }}
79+
listen [::]:80;
80+
{{ end }}
81+
access_log /var/log/nginx/access.log vhost;
82+
return 503;
83+
}
84+
85+
{{ if (and (exists "/etc/nginx/certs/default.crt") (exists "/etc/nginx/certs/default.key")) }}
86+
server {
87+
server_name _; # This is just an invalid value which will never trigger on a real hostname.
88+
listen 443 ssl http2;
89+
{{ if $enable_ipv6 }}
90+
listen [::]:443 ssl http2;
91+
{{ end }}
92+
access_log /var/log/nginx/access.log vhost;
93+
return 503;
94+
95+
ssl_session_tickets off;
96+
ssl_certificate /etc/nginx/certs/default.crt;
97+
ssl_certificate_key /etc/nginx/certs/default.key;
98+
}
99+
{{ end }}
100+
101+
{{ range $host, $containers := groupByMulti $ "Env.VIRTUAL_HOST" "," }}
102+
{{ $vport := split $host ":" | last }}
103+
{{ $host := split $host ":" | first }}
104+
{{ $vport := when (eq $vport $host) nil $vport }}
105+
{{ $is_regexp := hasPrefix "~" $host }}
106+
{{ $upstream_name := when $is_regexp (sha1 $host) $host }}
107+
# {{ $host }}
108+
upstream {{ $upstream_name }} {
109+
{{ range $container := $containers }}
110+
{{ $containerNetworks := $container.Networks }}
111+
{{ $containerAddresses := $container.Addresses }}
112+
{{ if eq (len $container.Networks) 0 }}
113+
{{ $linkedContainers := where $ "Hostname" $container.Hostname }}
114+
{{ range $linkedContainer := $linkedContainers }}
115+
{{ if gt (len $linkedContainer.Networks) 0 }}
116+
# using {{ $linkedContainer.Name }}'s network
117+
{{ $containerNetworks = $linkedContainer.Networks }}
118+
{{ $containerAddresses = $linkedContainer.Addresses }}
119+
{{ end }}
120+
{{ end }}
121+
{{ end }}
122+
123+
{{ $addrLen := len $containerAddresses }}
124+
125+
{{ range $knownNetwork := $CurrentContainer.Networks }}
126+
{{ range $containerNetwork := $containerNetworks }}
127+
{{ if eq $knownNetwork.Name $containerNetwork.Name }}
128+
## Can be connect with "{{ $containerNetwork.Name }}" network
129+
130+
{{/* If only 1 port exposed, use that */}}
131+
{{ if eq $addrLen 1 }}
132+
{{ $address := index $containerAddresses 0 }}
133+
{{ template "upstream" (dict "Container" $container "Address" $address "Network" $containerNetwork) }}
134+
{{/* If more than one port exposed, use the one matching VIRTUAL_PORT env var, falling back to standard web port 80 */}}
135+
{{ else }}
136+
{{ $port := coalesce $vport $container.Env.VIRTUAL_PORT "80" }}
137+
{{ $address := coalesce (where $containerAddresses "Port" $port | first) (dict "Port" $port) }}
138+
{{ template "upstream" (dict "Container" $container "Address" $address "Network" $containerNetwork) }}
139+
{{ end }}
140+
{{ end }}
141+
{{ end }}
142+
{{ end }}
143+
{{ end }}
144+
}
145+
146+
{{ $default_host := or ($.Env.DEFAULT_HOST) "" }}
147+
{{ $default_server := index (dict $host "" $default_host "default_server") $host }}
148+
149+
{{/* Get the VIRTUAL_PROTO defined by containers w/ the same vhost, falling back to "http" */}}
150+
{{ $proto := or (first (groupByKeys $containers "Env.VIRTUAL_PROTO")) "http" }}
151+
152+
{{/* Get the HTTPS_METHOD defined by containers w/ the same vhost, falling back to "redirect" */}}
153+
{{ $https_method := or (first (groupByKeys $containers "Env.HTTPS_METHOD")) "redirect" }}
154+
155+
{{/* Get the first cert name defined by containers w/ the same vhost */}}
156+
{{ $certName := (first (groupByKeys $containers "Env.CERT_NAME")) }}
157+
158+
{{/* Get the best matching cert by name for the vhost. */}}
159+
{{ $vhostCert := (closest (dir "/etc/nginx/certs") (printf "%s.crt" $host))}}
160+
161+
{{/* vhostCert is actually a filename so remove any suffixes since they are added later */}}
162+
{{ $vhostCert := trimSuffix ".crt" $vhostCert }}
163+
{{ $vhostCert := trimSuffix ".key" $vhostCert }}
164+
165+
{{/* Use the cert specified on the container or fallback to the best vhost match */}}
166+
{{ $cert := (coalesce $certName $vhostCert) }}
167+
168+
{{ $is_https := (and (ne $https_method "nohttps") (ne $cert "") (exists (printf "/etc/nginx/certs/%s.crt" $cert)) (exists (printf "/etc/nginx/certs/%s.key" $cert))) }}
169+
170+
{{ if $is_https }}
171+
172+
{{ if eq $https_method "redirect" }}
173+
server {
174+
server_name {{ $host }};
175+
listen 80 {{ $default_server }};
176+
{{ if $enable_ipv6 }}
177+
listen [::]:80 {{ $default_server }};
178+
{{ end }}
179+
access_log /var/log/nginx/access.log vhost;
180+
return 301 https://$host$request_uri;
181+
}
182+
{{ end }}
183+
184+
server {
185+
server_name {{ $host }};
186+
listen 443 ssl http2 {{ $default_server }};
187+
{{ if $enable_ipv6 }}
188+
listen [::]:443 ssl http2 {{ $default_server }};
189+
{{ end }}
190+
access_log /var/log/nginx/access.log vhost;
191+
192+
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
193+
ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';
194+
195+
ssl_prefer_server_ciphers on;
196+
ssl_session_timeout 5m;
197+
ssl_session_cache shared:SSL:50m;
198+
ssl_session_tickets off;
199+
200+
ssl_certificate /etc/nginx/certs/{{ (printf "%s.crt" $cert) }};
201+
ssl_certificate_key /etc/nginx/certs/{{ (printf "%s.key" $cert) }};
202+
203+
{{ if (exists (printf "/etc/nginx/certs/%s.dhparam.pem" $cert)) }}
204+
ssl_dhparam {{ printf "/etc/nginx/certs/%s.dhparam.pem" $cert }};
205+
{{ end }}
206+
207+
{{ if (ne $https_method "noredirect") }}
208+
add_header Strict-Transport-Security "max-age=31536000";
209+
{{ end }}
210+
211+
{{ if (exists (printf "/etc/nginx/vhost.d/%s" $host)) }}
212+
include {{ printf "/etc/nginx/vhost.d/%s" $host }};
213+
{{ else if (exists "/etc/nginx/vhost.d/default") }}
214+
include /etc/nginx/vhost.d/default;
215+
{{ end }}
216+
217+
location / {
218+
{{ if eq $proto "uwsgi" }}
219+
include uwsgi_params;
220+
uwsgi_pass {{ trim $proto }}://{{ trim $upstream_name }};
221+
{{ else }}
222+
proxy_pass {{ trim $proto }}://{{ trim $upstream_name }};
223+
{{ end }}
224+
{{ if (exists (printf "/etc/nginx/htpasswd/%s" $host)) }}
225+
auth_basic "Restricted {{ $host }}";
226+
auth_basic_user_file {{ (printf "/etc/nginx/htpasswd/%s" $host) }};
227+
{{ end }}
228+
{{ if (exists (printf "/etc/nginx/vhost.d/%s_location" $host)) }}
229+
include {{ printf "/etc/nginx/vhost.d/%s_location" $host}};
230+
{{ else if (exists "/etc/nginx/vhost.d/default_location") }}
231+
include /etc/nginx/vhost.d/default_location;
232+
{{ end }}
233+
}
234+
}
235+
236+
{{ end }}
237+
238+
{{ if or (not $is_https) (eq $https_method "noredirect") }}
239+
240+
server {
241+
server_name {{ $host }};
242+
listen 80 {{ $default_server }};
243+
{{ if $enable_ipv6 }}
244+
listen [::]:80 {{ $default_server }};
245+
{{ end }}
246+
access_log /var/log/nginx/access.log vhost;
247+
248+
{{ if (exists (printf "/etc/nginx/vhost.d/%s" $host)) }}
249+
include {{ printf "/etc/nginx/vhost.d/%s" $host }};
250+
{{ else if (exists "/etc/nginx/vhost.d/default") }}
251+
include /etc/nginx/vhost.d/default;
252+
{{ end }}
253+
254+
location / {
255+
{{ if eq $proto "uwsgi" }}
256+
include uwsgi_params;
257+
uwsgi_pass {{ trim $proto }}://{{ trim $upstream_name }};
258+
{{ else }}
259+
proxy_pass {{ trim $proto }}://{{ trim $upstream_name }};
260+
{{ end }}
261+
{{ if (exists (printf "/etc/nginx/htpasswd/%s" $host)) }}
262+
auth_basic "Restricted {{ $host }}";
263+
auth_basic_user_file {{ (printf "/etc/nginx/htpasswd/%s" $host) }};
264+
{{ end }}
265+
{{ if (exists (printf "/etc/nginx/vhost.d/%s_location" $host)) }}
266+
include {{ printf "/etc/nginx/vhost.d/%s_location" $host}};
267+
{{ else if (exists "/etc/nginx/vhost.d/default_location") }}
268+
include /etc/nginx/vhost.d/default_location;
269+
{{ end }}
270+
}
271+
}
272+
273+
{{ if (and (not $is_https) (exists "/etc/nginx/certs/default.crt") (exists "/etc/nginx/certs/default.key")) }}
274+
server {
275+
server_name {{ $host }};
276+
listen 443 ssl http2 {{ $default_server }};
277+
{{ if $enable_ipv6 }}
278+
listen [::]:443 ssl http2 {{ $default_server }};
279+
{{ end }}
280+
access_log /var/log/nginx/access.log vhost;
281+
return 500;
282+
283+
ssl_certificate /etc/nginx/certs/default.crt;
284+
ssl_certificate_key /etc/nginx/certs/default.key;
285+
}
286+
{{ end }}
287+
288+
{{ end }}
289+
{{ end }}

0 commit comments

Comments
 (0)