[
  {
    "path": "README.md",
    "content": "## How to Setup Free SSL Certificates from Let's Encrypt using Docker and Nginx\n\nThis is the source code for the guide located at https://www.humankode.com/ssl/how-to-set-up-free-ssl-certificates-from-lets-encrypt-using-docker-and-nginx\n"
  },
  {
    "path": "src/letsencrypt/docker-compose.yml",
    "content": "version: '3.1'\n\nservices:\n\n  letsencrypt-nginx-container:\n    container_name: 'letsencrypt-nginx-container'\n    image: nginx:1.14.0\n    ports:\n      - \"80:80\"\n    volumes:\n      - ./nginx.conf:/etc/nginx/conf.d/default.conf\n      - ./letsencrypt-site:/usr/share/nginx/html\n    networks:\n      - docker-network\n\nnetworks:\n  docker-network:\n    driver: bridge"
  },
  {
    "path": "src/letsencrypt/letsencrypt-site/index.html",
    "content": "<!DOCTYPE html>\n<html>\n\n<head>\n    <meta charset=\"utf-8\" />\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <title>Let's Encrypt First Time Cert Issue Site</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n    <link rel=\"stylesheet\" href=\"https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.3/css/bootstrap.min.css\" integrity=\"sha384-Zug+QiDoJOrZ5t4lssLdxGhVrurbmBWopoEl+M6BdEfwnCJZtKxi1KgxUyJq13dy\"\n        crossorigin=\"anonymous\">\n    <link rel=\"stylesheet\" href=\"styles/style.css\">\n    <script src=\"https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js\"></script>\n    <script src=\"https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.3/js/bootstrap.min.js\" integrity=\"sha384-a5N7Y/aK3qNeh15eJKGWxsqtnX/wWdSZSKp+81YjTmS15nvnvxKHuzaWwXHDli+4\"\n        crossorigin=\"anonymous\"></script>\n</head>\n\n<body>\n    <div class=\"site-wrapper\">\n        <h1>Oh, hai there!</h1>\n        <p>\n            This is the temporary site that will only be used for the very first time SSL certificates are issued by Let's Encrypt's\n            certbot.\n        </p>\n    </div>\n</body>\n\n</html>"
  },
  {
    "path": "src/letsencrypt/letsencrypt-site/styles/style.css",
    "content": "html, body {\n    height: 100%;\n    background-color: #333;\n    color: #fff;\n}\n\n.site-wrapper {\n    margin-top:100px;\n    text-align:center;\n}"
  },
  {
    "path": "src/letsencrypt/nginx.conf",
    "content": "server {\n    listen 80;\n    listen [::]:80;\n    server_name ohhaithere.com www.ohhaithere.com;\n\n    location ~ /.well-known/acme-challenge {\n        allow all;\n        root /usr/share/nginx/html;\n    }\n\n    root /usr/share/nginx/html;\n    index index.html;\n}\n"
  },
  {
    "path": "src/production/dh-param/dhparam-2048.pem",
    "content": "-----BEGIN DH PARAMETERS-----\nMIIBCAKCAQEArV0Pp7qt4VquZbPd9+ht6zmTVJ3TxW9xzIA7olaBOUcKpLFi6evF\npGTYtwlbBebuvdNFG3B+mF/1rzjkfdp+INShjWvnZLwFJ72i+0YnmQvlnXdTSGGs\n7RdtyFAxlU387Qcym6Cfx4jXYAtK3isHW613m5gqsK+DbmyWEv+PXuYzbBFYCQXM\nUKKnCuc2SosETm97AMphmpHyku4YF5zFEuoG/tE3YdP6GbadTIt5c4otENo0MyBf\nHQyMCCKQ8KGBhb3XWuE2MGlDycAjFhiw22EBPJ5VPyetY8VCvwoL+u/FUow8QvsA\nek0MLIttnVFmXMi6L0C9lC73eCXFiqd0UwIBAw==\n-----END DH PARAMETERS-----"
  },
  {
    "path": "src/production/docker-compose.yml",
    "content": "version: '3.1'\n\nservices:\n\n  production-nginx-container:\n    container_name: 'production-nginx-container'\n    image: nginx:1.14.0\n    ports:\n      - \"80:80\"\n      - \"443:443\"\n    volumes:\n      - ./production.conf:/etc/nginx/conf.d/default.conf\n      - ./production-site:/usr/share/nginx/html\n      - ./dh-param/dhparam-2048.pem:/etc/ssl/certs/dhparam-2048.pem\n      - /docker-volumes/etc/letsencrypt/live/ohhaithere.com/fullchain.pem:/etc/letsencrypt/live/ohhaithere.com/fullchain.pem\n      - /docker-volumes/etc/letsencrypt/live/ohhaithere.com/privkey.pem:/etc/letsencrypt/live/ohhaithere.com/privkey.pem\n      #for certbot challenges\n      - /docker-volumes/data/letsencrypt:/data/letsencrypt\n    networks:\n      - docker-network\n\nnetworks:\n  docker-network:\n    driver: bridge"
  },
  {
    "path": "src/production/production-site/index.html",
    "content": "<!DOCTYPE html>\n<html>\n\n<head>\n    <meta charset=\"utf-8\" />\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <title>Let's Encrypt : Production Site</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n    <link rel=\"stylesheet\" href=\"https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.3/css/bootstrap.min.css\" integrity=\"sha384-Zug+QiDoJOrZ5t4lssLdxGhVrurbmBWopoEl+M6BdEfwnCJZtKxi1KgxUyJq13dy\"\n        crossorigin=\"anonymous\">\n    <link rel=\"stylesheet\" href=\"styles/style.css\">\n    <script src=\"https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js\"></script>\n    <script src=\"https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.3/js/bootstrap.min.js\" integrity=\"sha384-a5N7Y/aK3qNeh15eJKGWxsqtnX/wWdSZSKp+81YjTmS15nvnvxKHuzaWwXHDli+4\"\n        crossorigin=\"anonymous\"></script>\n</head>\n\n<body>\n    <div class=\"site-wrapper\">\n        <h1>Oh, hai there!</h1>\n        <p>\n            This is the production site that runs in a Docker Nginx container and loads the SSL certificates from a mapped docker volume.\n        </p>\n        <br />\n        <p>\n            <img src=\"images/lets-encryptz-cat.jpg\" />\n        </p>\n    </div>\n</body>\n\n</html>"
  },
  {
    "path": "src/production/production-site/styles/style.css",
    "content": "html, body {\n    height: 100%;\n    background-color: #333;\n    color: #fff;\n}\n\n.site-wrapper {\n    margin-top:100px;\n    text-align:center;\n}"
  },
  {
    "path": "src/production/production.conf",
    "content": "server {\n    listen      80;\n    listen [::]:80;\n    server_name ohhaithere.com www.ohhaithere.com;\n\n    location / {\n        rewrite ^ https://$host$request_uri? permanent;\n    }\n\n    #for certbot challenges (renewal process)\n    location ~ /.well-known/acme-challenge {\n        allow all;\n        root /data/letsencrypt;\n    }\n}\n\n#https://ohhaithere.com\nserver {\n    listen 443 ssl http2;\n    listen [::]:443 ssl http2;\n    server_name ohhaithere.com;\n\n    server_tokens off;\n\n    ssl_certificate /etc/letsencrypt/live/ohhaithere.com/fullchain.pem;\n    ssl_certificate_key /etc/letsencrypt/live/ohhaithere.com/privkey.pem;\n\n    ssl_buffer_size 8k;\n\n    ssl_dhparam /etc/ssl/certs/dhparam-2048.pem;\n\n    ssl_protocols TLSv1.2 TLSv1.1 TLSv1;\n    ssl_prefer_server_ciphers on;\n\n    ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;\n\n    ssl_ecdh_curve secp384r1;\n    ssl_session_tickets off;\n\n    # OCSP stapling\n    ssl_stapling on;\n    ssl_stapling_verify on;\n    resolver 8.8.8.8;\n\n    return 301 https://www.ohhaithere.com$request_uri;\n}\n\n#https://www.ohhaithere.com\nserver {\n    server_name www.ohhaithere.com;\n    listen 443 ssl http2;\n    listen [::]:443 ssl http2;\n\n    server_tokens off;\n\n    ssl_buffer_size 8k;\n    ssl_dhparam /etc/ssl/certs/dhparam-2048.pem;\n\n    ssl_protocols TLSv1.2 TLSv1.1 TLSv1;\n    ssl_prefer_server_ciphers on;\n    ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;\n\n    ssl_ecdh_curve secp384r1;\n    ssl_session_tickets off;\n\n    # OCSP stapling\n    ssl_stapling on;\n    ssl_stapling_verify on;\n    resolver 8.8.8.8 8.8.4.4;\n\n    ssl_certificate /etc/letsencrypt/live/ohhaithere.com/fullchain.pem;\n    ssl_certificate_key /etc/letsencrypt/live/ohhaithere.com/privkey.pem;\n\n    location / {\n        #security headers\n        add_header Strict-Transport-Security \"max-age=31536000; includeSubDomains; preload\";\n        add_header X-XSS-Protection \"1; mode=block\" always;\n        add_header X-Content-Type-Options \"nosniff\" always;\n        add_header X-Frame-Options \"DENY\" always;\n        #CSP\n        add_header Content-Security-Policy \"frame-src 'self'; default-src 'self'; script-src 'self' 'unsafe-inline' https://maxcdn.bootstrapcdn.com https://ajax.googleapis.com; img-src 'self'; style-src 'self' https://maxcdn.bootstrapcdn.com; font-src 'self' data: https://maxcdn.bootstrapcdn.com; form-action 'self'; upgrade-insecure-requests;\" always;\n        add_header Referrer-Policy \"strict-origin-when-cross-origin\" always;\n    }\n\n    root /usr/share/nginx/html;\n    index index.html;\n}"
  }
]