├── LICENSE ├── README.md ├── containers.graffle ├── containers.png ├── standalone ├── nginx-vhost.conf └── request_certificate.sh └── webroot ├── nginx-multiple-vhost.conf ├── nginx-vhost.conf └── request_certificate.sh /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Martin Brugger 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # letsencrypt-nginx-docker 2 | Samples configs and documentation for configuring letsencrypt using nginx and the dockerized client 3 | 4 | In this little guide I want to show an easy setup on how to integrate let's encrypt with an nginx/docker setup using a shared volume and the webroot plugin. 5 | I previously used the "standalone" webserver plugin but a letsencrypt update did break the renewal process for me, so I tried the webroot plugin. 6 | 7 | Therefore I did take the following approach to create a setup which is capable of automatic updates. 8 | 9 | The frontend nginx as reverse proxy is in my case redirecting requests to different docker applications 10 | ![container setup](containers.png) 11 | 12 | The letsencrypt client writes the files used for webroot authentication into a shared folder which is served by the nginx to the letsencrypt server performing the authentication. 13 | ## Setup 14 | Always find&replace my.example.com with your hostname. 15 | 16 | 1. I added a location in the relevant server block redirecting the letsencrypt requests to the shared volume of the letsencrypt container. 17 | (See `nginx-vhost.conf`) 18 | 19 | location /.well-known/acme-challenge { 20 | root /tmp/letsencrypt/www; 21 | } 22 | The application continues normal operation without any configuration changes which I think is the best way of integrating letsencrypt certificates. 23 | 24 | 2. The script to run the docker container for requesting a certificate now only needs to be executed with the correct ports mapped. (See `request_certificate.sh`) 25 | 26 | #!/bin/bash 27 | mkdir -p /tmp/letsencrypt/www 28 | docker run -it --rm --name letsencrypt \ 29 | -v "/etc/letsencrypt:/etc/letsencrypt" \ 30 | -v "/var/lib/letsencrypt:/var/lib/letsencrypt" \ 31 | -v "/tmp/letsencrypt/www:/var/www" \ 32 | quay.io/letsencrypt/letsencrypt:latest auth --authenticator webroot --webroot-path /var/www --renew-by-default --server \ 33 | https://acme-v01.api.letsencrypt.org/directory -d my.example.com 34 | 35 | Issuing the certificate and also renewal work this way without a problem. 36 | -------------------------------------------------------------------------------- /containers.graffle: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ActiveLayerIndex 6 | 0 7 | ApplicationVersion 8 | 9 | com.omnigroup.OmniGrafflePro 10 | 139.18.0.187838 11 | 12 | AutoAdjust 13 | 14 | BackgroundGraphic 15 | 16 | Bounds 17 | {{0, 0}, {559, 783}} 18 | Class 19 | SolidGraphic 20 | ID 21 | 2 22 | Style 23 | 24 | shadow 25 | 26 | Draws 27 | NO 28 | 29 | stroke 30 | 31 | Draws 32 | NO 33 | 34 | 35 | 36 | BaseZoom 37 | 0 38 | CanvasOrigin 39 | {0, 0} 40 | ColumnAlign 41 | 1 42 | ColumnSpacing 43 | 36 44 | CreationDate 45 | 2015-10-31 19:22:22 +0000 46 | Creator 47 | Martin Brugger 48 | DisplayScale 49 | 1.000 cm = 1.000 cm 50 | GraphDocumentVersion 51 | 8 52 | GraphicsList 53 | 54 | 55 | Bounds 56 | {{100.13593508243147, 137.26250859434185}, {47, 24}} 57 | Class 58 | ShapedGraphic 59 | FitText 60 | YES 61 | Flow 62 | Resize 63 | FontInfo 64 | 65 | Color 66 | 67 | w 68 | 0 69 | 70 | Font 71 | Helvetica 72 | Size 73 | 12 74 | 75 | ID 76 | 16 77 | Line 78 | 79 | ID 80 | 15 81 | Position 82 | 0.51816225051879883 83 | RotationType 84 | 0 85 | 86 | Shape 87 | Rectangle 88 | Style 89 | 90 | shadow 91 | 92 | Draws 93 | NO 94 | 95 | stroke 96 | 97 | Draws 98 | NO 99 | 100 | 101 | Text 102 | 103 | Text 104 | {\rtf1\ansi\ansicpg1252\cocoartf1404\cocoasubrtf340 105 | \cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} 106 | {\colortbl;\red255\green255\blue255;} 107 | \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc 108 | 109 | \f0\fs24 \cf0 80/443} 110 | 111 | Wrap 112 | NO 113 | 114 | 115 | Class 116 | LineGraphic 117 | Head 118 | 119 | ID 120 | 1 121 | 122 | ID 123 | 15 124 | Points 125 | 126 | {79.61954022818405, 149.16519897152958} 127 | {164.56666790909279, 149.35299656333569} 128 | 129 | Style 130 | 131 | stroke 132 | 133 | HeadArrow 134 | 0 135 | Legacy 136 | 137 | TailArrow 138 | 0 139 | 140 | 141 | Tail 142 | 143 | ID 144 | 9 145 | 146 | 147 | 148 | Bounds 149 | {{0, 121}, {84, 56.1640625}} 150 | Class 151 | ShapedGraphic 152 | ID 153 | 9 154 | Shape 155 | Cloud 156 | Style 157 | 158 | Text 159 | 160 | VerticalPad 161 | 0 162 | 163 | 164 | 165 | Bounds 166 | {{309.13003972371416, 60.5}, {74, 14}} 167 | Class 168 | ShapedGraphic 169 | FitText 170 | YES 171 | Flow 172 | Resize 173 | ID 174 | 14 175 | Shape 176 | Rectangle 177 | Style 178 | 179 | fill 180 | 181 | Draws 182 | NO 183 | 184 | shadow 185 | 186 | Draws 187 | NO 188 | 189 | stroke 190 | 191 | Draws 192 | NO 193 | 194 | 195 | Text 196 | 197 | Pad 198 | 0 199 | Text 200 | {\rtf1\ansi\ansicpg1252\cocoartf1404\cocoasubrtf340 201 | \cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} 202 | {\colortbl;\red255\green255\blue255;} 203 | \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc 204 | 205 | \f0\fs24 \cf0 Mapped ports} 206 | VerticalPad 207 | 0 208 | 209 | Wrap 210 | NO 211 | 212 | 213 | Bounds 214 | {{265.69666708796939, 185.18757463901827}, {165, 24}} 215 | Class 216 | ShapedGraphic 217 | FitText 218 | YES 219 | Flow 220 | Resize 221 | FontInfo 222 | 223 | Color 224 | 225 | w 226 | 0 227 | 228 | Font 229 | Helvetica 230 | Size 231 | 12 232 | 233 | ID 234 | 13 235 | Line 236 | 237 | ID 238 | 4 239 | Offset 240 | -1 241 | Position 242 | 0.48316580057144165 243 | RotationType 244 | 0 245 | 246 | Shape 247 | Rectangle 248 | Style 249 | 250 | shadow 251 | 252 | Draws 253 | NO 254 | 255 | stroke 256 | 257 | Draws 258 | NO 259 | 260 | 261 | Text 262 | 263 | Text 264 | {\rtf1\ansi\ansicpg1252\cocoartf1404\cocoasubrtf340 265 | \cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} 266 | {\colortbl;\red255\green255\blue255;} 267 | \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc 268 | 269 | \f0\fs24 \cf0 /.well-known/acme-challenge} 270 | 271 | Wrap 272 | NO 273 | 274 | 275 | Bounds 276 | {{322.36880409963766, 137.49998658132387}, {54, 24}} 277 | Class 278 | ShapedGraphic 279 | FitText 280 | YES 281 | Flow 282 | Resize 283 | FontInfo 284 | 285 | Color 286 | 287 | w 288 | 0 289 | 290 | Font 291 | Helvetica 292 | Size 293 | 12 294 | 295 | ID 296 | 12 297 | Line 298 | 299 | ID 300 | 10 301 | Position 302 | 0.50924193859100342 303 | RotationType 304 | 0 305 | 306 | Shape 307 | Rectangle 308 | Style 309 | 310 | shadow 311 | 312 | Draws 313 | NO 314 | 315 | stroke 316 | 317 | Draws 318 | NO 319 | 320 | 321 | Text 322 | 323 | Text 324 | {\rtf1\ansi\ansicpg1252\cocoartf1404\cocoasubrtf340 325 | \cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} 326 | {\colortbl;\red255\green255\blue255;} 327 | \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc 328 | 329 | \f0\fs24 \cf0 1082:80} 330 | 331 | Wrap 332 | NO 333 | 334 | 335 | Bounds 336 | {{323.80755162794691, 96.339538623442891}, {54, 24}} 337 | Class 338 | ShapedGraphic 339 | FitText 340 | YES 341 | Flow 342 | Resize 343 | FontInfo 344 | 345 | Color 346 | 347 | w 348 | 0 349 | 350 | Font 351 | Helvetica 352 | Size 353 | 12 354 | 355 | ID 356 | 11 357 | Line 358 | 359 | ID 360 | 7 361 | Position 362 | 0.49561390280723572 363 | RotationType 364 | 0 365 | 366 | Shape 367 | Rectangle 368 | Style 369 | 370 | shadow 371 | 372 | Draws 373 | NO 374 | 375 | stroke 376 | 377 | Draws 378 | NO 379 | 380 | 381 | Text 382 | 383 | Text 384 | {\rtf1\ansi\ansicpg1252\cocoartf1404\cocoasubrtf340 385 | \cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} 386 | {\colortbl;\red255\green255\blue255;} 387 | \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc 388 | 389 | \f0\fs24 \cf0 1081:80} 390 | 391 | Wrap 392 | NO 393 | 394 | 395 | Class 396 | LineGraphic 397 | Head 398 | 399 | ID 400 | 1 401 | 402 | ID 403 | 10 404 | Points 405 | 406 | {403.12201358515387, 149.49998658132387} 407 | {297.56666668218014, 149.49998658132387} 408 | 409 | Style 410 | 411 | stroke 412 | 413 | HeadArrow 414 | 0 415 | Legacy 416 | 417 | TailArrow 418 | 0 419 | 420 | 421 | Tail 422 | 423 | ID 424 | 8 425 | 426 | 427 | 428 | Bounds 429 | {{403.62201360066729, 121}, {131.99999999999997, 57}} 430 | Class 431 | ShapedGraphic 432 | ID 433 | 8 434 | Shape 435 | Rectangle 436 | Text 437 | 438 | Text 439 | {\rtf1\ansi\ansicpg1252\cocoartf1404\cocoasubrtf340 440 | \cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} 441 | {\colortbl;\red255\green255\blue255;} 442 | \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc 443 | 444 | \f0\fs24 \cf0 Container B\ 445 | vhost: b.example.com} 446 | 447 | 448 | 449 | Class 450 | LineGraphic 451 | Head 452 | 453 | ID 454 | 1 455 | 456 | ID 457 | 7 458 | Points 459 | 460 | {403.14916669862379, 90.348400383191631} 461 | {297.53950810308066, 126.64911377792612} 462 | 463 | Style 464 | 465 | stroke 466 | 467 | HeadArrow 468 | 0 469 | Legacy 470 | 471 | TailArrow 472 | 0 473 | 474 | 475 | Tail 476 | 477 | ID 478 | 5 479 | 480 | 481 | 482 | Bounds 483 | {{403.62201360066729, 39}, {131.99999999999997, 57}} 484 | Class 485 | ShapedGraphic 486 | ID 487 | 5 488 | Shape 489 | Rectangle 490 | Text 491 | 492 | Text 493 | {\rtf1\ansi\ansicpg1252\cocoartf1404\cocoasubrtf340 494 | \cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} 495 | {\colortbl;\red255\green255\blue255;} 496 | \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc 497 | 498 | \f0\fs24 \cf0 Container A\ 499 | vhost: a.example.com} 500 | 501 | 502 | 503 | Class 504 | LineGraphic 505 | Head 506 | 507 | ID 508 | 3 509 | 510 | ID 511 | 4 512 | Points 513 | 514 | {297.5312334891662, 175.94924497230426} 515 | {403.15786860744441, 217.98284093787373} 516 | 517 | Style 518 | 519 | stroke 520 | 521 | HeadArrow 522 | 0 523 | Legacy 524 | 525 | TailArrow 526 | 0 527 | 528 | 529 | Tail 530 | 531 | ID 532 | 1 533 | 534 | 535 | 536 | Bounds 537 | {{403.62201360066729, 216.10723519325256}, {131.99999999999997, 57}} 538 | Class 539 | ShapedGraphic 540 | ID 541 | 3 542 | Shape 543 | Rectangle 544 | Text 545 | 546 | Text 547 | {\rtf1\ansi\ansicpg1252\cocoartf1404\cocoasubrtf340 548 | \cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} 549 | {\colortbl;\red255\green255\blue255;} 550 | \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc 551 | 552 | \f0\fs24 \cf0 letsencrypt-docker shared volume \ 553 | /tmp/letsencrypt/www} 554 | 555 | 556 | 557 | Bounds 558 | {{165.06666666666666, 121.41796875}, {131.99999999999997, 56.1640625}} 559 | Class 560 | ShapedGraphic 561 | ID 562 | 1 563 | Shape 564 | Rectangle 565 | Text 566 | 567 | Text 568 | {\rtf1\ansi\ansicpg1252\cocoartf1404\cocoasubrtf340 569 | \cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} 570 | {\colortbl;\red255\green255\blue255;} 571 | \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc 572 | 573 | \f0\fs24 \cf0 Frontend nginx} 574 | 575 | 576 | 577 | GridInfo 578 | 579 | GuidesLocked 580 | NO 581 | GuidesVisible 582 | YES 583 | HPages 584 | 1 585 | ImageCounter 586 | 1 587 | KeepToScale 588 | 589 | Layers 590 | 591 | 592 | Lock 593 | NO 594 | Name 595 | Layer 1 596 | Print 597 | YES 598 | View 599 | YES 600 | 601 | 602 | LayoutInfo 603 | 604 | Animate 605 | NO 606 | circoMinDist 607 | 18 608 | circoSeparation 609 | 0.0 610 | layoutEngine 611 | dot 612 | neatoSeparation 613 | 0.0 614 | twopiSeparation 615 | 0.0 616 | 617 | LinksVisible 618 | NO 619 | MagnetsVisible 620 | NO 621 | MasterSheets 622 | 623 | ModificationDate 624 | 2015-12-27 16:20:36 +0000 625 | Modifier 626 | Martin Brugger 627 | NotesVisible 628 | NO 629 | Orientation 630 | 2 631 | OriginVisible 632 | NO 633 | PageBreaks 634 | YES 635 | PrintInfo 636 | 637 | NSBottomMargin 638 | 639 | float 640 | 41 641 | 642 | NSHorizonalPagination 643 | 644 | coded 645 | BAtzdHJlYW10eXBlZIHoA4QBQISEhAhOU051bWJlcgCEhAdOU1ZhbHVlAISECE5TT2JqZWN0AIWEASqEhAFxlwCG 646 | 647 | NSLeftMargin 648 | 649 | float 650 | 18 651 | 652 | NSPaperSize 653 | 654 | size 655 | {595, 842} 656 | 657 | NSPrintReverseOrientation 658 | 659 | int 660 | 0 661 | 662 | NSRightMargin 663 | 664 | float 665 | 18 666 | 667 | NSTopMargin 668 | 669 | float 670 | 18 671 | 672 | 673 | PrintOnePage 674 | 675 | ReadOnly 676 | NO 677 | RowAlign 678 | 1 679 | RowSpacing 680 | 36 681 | SheetTitle 682 | Canvas 1 683 | SmartAlignmentGuidesActive 684 | YES 685 | SmartDistanceGuidesActive 686 | YES 687 | UniqueID 688 | 1 689 | UseEntirePage 690 | 691 | VPages 692 | 1 693 | WindowInfo 694 | 695 | CurrentSheet 696 | 0 697 | ExpandedCanvases 698 | 699 | 700 | name 701 | Canvas 1 702 | 703 | 704 | Frame 705 | {{373, 55}, {693, 822}} 706 | ListView 707 | 708 | OutlineWidth 709 | 142 710 | RightSidebar 711 | 712 | ShowRuler 713 | 714 | Sidebar 715 | 716 | SidebarWidth 717 | 120 718 | VisibleRegion 719 | {{13, 0}, {544, 665}} 720 | Zoom 721 | 1 722 | ZoomValues 723 | 724 | 725 | Canvas 1 726 | 1 727 | 1 728 | 729 | 730 | 731 | 732 | 733 | -------------------------------------------------------------------------------- /containers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mbrugger/letsencrypt-nginx-docker/4197cbb2aa26dd6bc3e0dabc63c5d28e92f1b730/containers.png -------------------------------------------------------------------------------- /standalone/nginx-vhost.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80; 3 | server_name my.example.com; 4 | 5 | location /.well-known/acme-challenge { 6 | proxy_pass http://127.0.0.1:1086; 7 | } 8 | location / { 9 | return 301 https://$server_name$request_uri; 10 | } 11 | } 12 | 13 | server { 14 | listen 443; 15 | server_name my.example.com; 16 | 17 | ssl on; 18 | ssl_certificate /etc/letsencrypt/live/my.example.com/fullchain.pem; 19 | ssl_certificate_key /etc/letsencrypt/live/my.example.com/privkey.pem; 20 | ssl_session_timeout 5m; 21 | ssl_protocols TLSv1 TLSv1.1 TLSv1.2; 22 | ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH'; 23 | ssl_prefer_server_ciphers on; 24 | 25 | ssl_session_cache shared:SSL:10m; 26 | # generate dhparams.pem: openssl dhparam -out dhparam.pem 4096 27 | ssl_dhparam /etc/ssl/private/dhparams.pem; 28 | 29 | location / { 30 | proxy_pass http://localhost:1080; 31 | proxy_set_header Host $host; 32 | proxy_set_header X-Forwarded-For $remote_addr; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /standalone/request_certificate.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | docker run -it --rm -p 1086:80 --name letsencrypt \ 3 | -v "/etc/letsencrypt:/etc/letsencrypt" \ 4 | -v "/var/lib/letsencrypt:/var/lib/letsencrypt" \ 5 | quay.io/letsencrypt/letsencrypt:latest auth --server https://acme-staging.api.letsencrypt.org/directory \ 6 | --debug --renew-by-default --standalone-supported-challenges http-01 \ 7 | --verbose -d my.example.com 8 | -------------------------------------------------------------------------------- /webroot/nginx-multiple-vhost.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80; 3 | server_name *.example.com; 4 | 5 | location /.well-known/acme-challenge { 6 | root /tmp/letsencrypt/www; 7 | } 8 | location / { 9 | return 301 https://$http_host$request_uri; 10 | } 11 | } 12 | 13 | map $http_host $proxy_port_number { 14 | hostnames; 15 | 16 | default 1080; 17 | a.example.com 1080; 18 | b.example.com 1081; 19 | c.example.com 1082; 20 | } 21 | 22 | server { 23 | listen 443; 24 | server_name *.example.com; 25 | 26 | ssl on; 27 | ssl_certificate /etc/letsencrypt/live/my.example.com/fullchain.pem; 28 | ssl_certificate_key /etc/letsencrypt/live/my.example.com/privkey.pem; 29 | ssl_session_timeout 5m; 30 | ssl_protocols TLSv1 TLSv1.1 TLSv1.2; 31 | ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH'; 32 | ssl_prefer_server_ciphers on; 33 | 34 | ssl_session_cache shared:SSL:10m; 35 | # generate dhparams.pem: openssl dhparam -out dhparam.pem 4096 36 | ssl_dhparam /etc/ssl/private/dhparams.pem; 37 | 38 | location / { 39 | proxy_pass http://127.0.0.1:$proxy_port_number; 40 | proxy_set_header Host $host; 41 | proxy_set_header X-Forwarded-For $remote_addr; 42 | proxy_set_header X-Forwarded-Proto https; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /webroot/nginx-vhost.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80; 3 | server_name my.example.com; 4 | 5 | location /.well-known/acme-challenge { 6 | root /tmp/letsencrypt/www; 7 | } 8 | location / { 9 | return 301 https://$server_name$request_uri; 10 | } 11 | } 12 | 13 | server { 14 | listen 443; 15 | server_name my.example.com; 16 | 17 | ssl on; 18 | ssl_certificate /etc/letsencrypt/live/my.example.com/fullchain.pem; 19 | ssl_certificate_key /etc/letsencrypt/live/my.example.com/privkey.pem; 20 | ssl_session_timeout 5m; 21 | ssl_protocols TLSv1 TLSv1.1 TLSv1.2; 22 | ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH'; 23 | ssl_prefer_server_ciphers on; 24 | 25 | ssl_session_cache shared:SSL:10m; 26 | # generate dhparams.pem: openssl dhparam -out dhparam.pem 4096 27 | ssl_dhparam /etc/ssl/private/dhparams.pem; 28 | 29 | location / { 30 | proxy_pass http://localhost:1080; 31 | proxy_set_header Host $host; 32 | proxy_set_header X-Forwarded-For $remote_addr; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /webroot/request_certificate.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | mkdir -p /tmp/letsencrypt/www 3 | docker run -it --rm --name letsencrypt \ 4 | -v "/etc/letsencrypt:/etc/letsencrypt" \ 5 | -v "/var/lib/letsencrypt:/var/lib/letsencrypt" \ 6 | -v "/tmp/letsencrypt/www:/var/www" \ 7 | quay.io/letsencrypt/letsencrypt:latest auth --authenticator webroot --webroot-path /var/www --renew-by-default --server \ 8 | https://acme-v01.api.letsencrypt.org/directory -d my.example.com 9 | --------------------------------------------------------------------------------