├── .editorconfig ├── .github └── FUNDING.yml ├── .gitignore ├── LICENSE ├── README.md ├── caddy-gen ├── app │ ├── Dockerfile │ └── index.js ├── certs │ └── .gitkeep └── docker-compose.yml ├── caddy ├── Caddyfile ├── app │ ├── Dockerfile │ └── index.js ├── certs │ └── .gitkeep └── docker-compose.yml ├── init.sh └── nginx ├── app ├── Dockerfile └── index.js ├── certs └── .gitkeep └── docker-compose.yml /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | 15 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: HugoDF 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.pem 2 | *.crt 3 | *.key 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) 2019 Hugo Di Francesco 3 | 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, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 19 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 20 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 21 | OR OTHER DEALINGS IN THE SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Docker Compose local HTTPS 2 | 3 | > Examples of local HTTPS with docker-compose + mkcert 4 | 5 | ## Prerequisites 6 | 7 | - [mkcert](https://github.com/FiloSottile/mkcert) 8 | - [Docker Desktop](https://www.docker.com/products/docker-desktop) 9 | 10 | Run `mkcert -install` 11 | 12 | Run `./init.sh` (creates local certificates using mkcert and copies them to where the Caddy and nginx examples expect them) 13 | 14 | ## The setup 15 | 16 | Each example has a barebones Node app running on the official Node 10 Docker image running on port 8080. 17 | 18 | The Node code is at [./caddy/app/index.js](./caddy/app/index.js), [./caddy-gen/app/index.js](./caddy-gen/app/index.js) and [./nginx/app/index.js](./caddy/app/index.js). 19 | 20 | It also has a reverse-proxy set up using Caddy and nginx respectively which 21 | 22 | ## Caddy Example with Caddyfile 23 | 24 | > Caddy is the HTTP/2 web server with automatic HTTPS. 25 | > 26 | > https://caddyserver.com/ 27 | 28 | See [./caddy](./caddy), uses [https://github.com/abiosoft/caddy-docker](https://github.com/abiosoft/caddy-docker) Docker image. 29 | 30 | To run it: 31 | 32 | ```sh 33 | cd caddy 34 | docker-compose up 35 | ``` 36 | 37 | Then either navigate to https://foo.test or `curl https://foo.test`. 38 | 39 | > Note: the nginx/Caddy examples needs to be stopped before starting this Caddy example 40 | 41 | ## Caddy Example with docker-gen 42 | 43 | > Caddy is the HTTP/2 web server with automatic HTTPS. 44 | > 45 | > https://caddyserver.com/ 46 | 47 | This image leverages [Docker-gen](https://github.com/jwilder/docker-gen) to "Generate files from docker container meta-data". 48 | 49 | Which allows us to build the configuration for the reverse proxy using labels on the target container (without a Caddyfile, that's the file generated from the labels). 50 | 51 | See [./caddy-gen](./caddy-gen), uses [https://github.com/wemake-services/caddy-gen](https://github.com/wemake-services/caddy-gen) Docker image. 52 | 53 | ```sh 54 | cd caddy-gen 55 | docker-compose up 56 | ``` 57 | 58 | Then either navigate to https://foo.test or `curl https://foo.test`. 59 | 60 | > Note: the nginx/other Caddy examples needs to be stopped before starting the Caddy example 61 | 62 | 63 | ## nginx Example 64 | 65 | > [nginx](https://www.nginx.com/) is a web server which can also be used as a reverse proxy, load balancer, mail proxy and HTTP cache. 66 | > 67 | > Wikipedia 68 | 69 | See [./nginx](./nginx), uses [https://github.com/jwilder/nginx-proxy](https://github.com/jwilder/nginx-proxy) Docker image. 70 | 71 | This image leverages [Docker-gen](https://github.com/jwilder/docker-gen) to "Generate files from docker container meta-data". 72 | 73 | ```sh 74 | cd nginx 75 | docker-compose up 76 | ``` 77 | 78 | Then either navigate to https://foo.test or `curl https://foo.test`. 79 | 80 | > Note: the Caddy examples needs to be stopped before starting the nginx example 81 | -------------------------------------------------------------------------------- /caddy-gen/app/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:10 2 | 3 | WORKDIR /node/app 4 | 5 | COPY ./index.js /node/app 6 | 7 | ENV NODE_ENV production 8 | 9 | ENV PORT 8080 10 | EXPOSE 8080 11 | 12 | CMD ["node", "index.js"] 13 | -------------------------------------------------------------------------------- /caddy-gen/app/index.js: -------------------------------------------------------------------------------- 1 | const http = require('http') 2 | 3 | const server = http.createServer((req, res) => { 4 | res.writeHead(200, { 'Content-Type': 'text/plain' }); 5 | res.end('Hello world'); 6 | }); 7 | 8 | server.listen(process.env.PORT) 9 | -------------------------------------------------------------------------------- /caddy-gen/certs/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HugoDF/docker-compose-local-https/e6e7a333fc987e9a1d280d669a3bd8715b045185/caddy-gen/certs/.gitkeep -------------------------------------------------------------------------------- /caddy-gen/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | caddy: 4 | image: "wemakeservices/caddy-gen:latest" 5 | volumes: 6 | - /var/run/docker.sock:/tmp/docker.sock:ro # needs socket to read events 7 | - ./certs:/root/certs # to sync mkcert certificates to Caddy 8 | ports: 9 | - "443:2015" 10 | depends_on: 11 | - web 12 | 13 | web: 14 | build: ./app 15 | labels: 16 | - "virtual.host=foo.test" 17 | - "virtual.port=8080" 18 | - "virtual.tls-email=/root/certs/foo.test.pem /root/certs/foo.test-key.pem" 19 | 20 | 21 | -------------------------------------------------------------------------------- /caddy/Caddyfile: -------------------------------------------------------------------------------- 1 | foo.test { 2 | log stdout 3 | # Mkcert - https://github.com/FiloSottile/mkcert 4 | tls /root/certs/foo.test.pem /root/certs/foo.test-key.pem 5 | 6 | proxy / http://web:8080 { 7 | transparent 8 | header_upstream X-Marotagem true 9 | header_upstream Host "foo.test" 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /caddy/app/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:10 2 | 3 | WORKDIR /node/app 4 | 5 | COPY ./index.js /node/app 6 | 7 | ENV NODE_ENV production 8 | 9 | ENV PORT 8080 10 | EXPOSE 8080 11 | 12 | CMD ["node", "index.js"] 13 | -------------------------------------------------------------------------------- /caddy/app/index.js: -------------------------------------------------------------------------------- 1 | const http = require('http') 2 | 3 | const server = http.createServer((req, res) => { 4 | res.writeHead(200, { 'Content-Type': 'text/plain' }); 5 | res.end('Hello world'); 6 | }); 7 | 8 | server.listen(process.env.PORT) 9 | -------------------------------------------------------------------------------- /caddy/certs/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HugoDF/docker-compose-local-https/e6e7a333fc987e9a1d280d669a3bd8715b045185/caddy/certs/.gitkeep -------------------------------------------------------------------------------- /caddy/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | caddy: 4 | image: "abiosoft/caddy:latest" 5 | volumes: 6 | - ./certs:/root/certs # to sync mkcert certificates to Caddy 7 | - ./Caddyfile:/etc/Caddyfile # to mount custom Caddyfile 8 | ports: 9 | - "443:2015" 10 | depends_on: 11 | - web 12 | 13 | web: 14 | build: ./app 15 | 16 | 17 | -------------------------------------------------------------------------------- /init.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | echo """ 3 | ================================================== 4 | Creating certificate for foo.test 5 | ================================================== 6 | """ 7 | mkcert foo.test 8 | 9 | echo """ 10 | ================================================== 11 | Copying foo.test certificates to ./caddy/certs 12 | ================================================== 13 | """ 14 | 15 | cp ./foo.test.pem ./caddy/certs 16 | cp ./foo.test-key.pem ./caddy/certs 17 | 18 | echo """ 19 | ================================================== 20 | Copying foo.test certificates to ./caddy-gen/certs 21 | ================================================== 22 | """ 23 | 24 | cp ./foo.test.pem ./caddy-gen/certs 25 | cp ./foo.test-key.pem ./caddy-gen/certs 26 | 27 | echo """ 28 | ================================================== 29 | Copying foo.test certificates to ./nginx/certs 30 | ================================================== 31 | """ 32 | 33 | cp ./foo.test.pem ./nginx/certs/foo.test.crt 34 | cp ./foo.test-key.pem ./nginx/certs/foo.test.key 35 | 36 | echo """ 37 | ================================================== 38 | Add the following to /etc/hosts file: 39 | 40 | 127.0.0.1 foo.test 41 | ================================================== 42 | """ 43 | 44 | -------------------------------------------------------------------------------- /nginx/app/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:10 2 | 3 | WORKDIR /node/app 4 | 5 | COPY ./index.js /node/app 6 | 7 | ENV NODE_ENV production 8 | 9 | ENV PORT 8080 10 | EXPOSE 8080 11 | 12 | CMD ["node", "index.js"] 13 | -------------------------------------------------------------------------------- /nginx/app/index.js: -------------------------------------------------------------------------------- 1 | const http = require('http') 2 | 3 | const server = http.createServer((req, res) => { 4 | res.writeHead(200, { 'Content-Type': 'text/plain' }); 5 | res.end('Hello world'); 6 | }); 7 | 8 | server.listen(process.env.PORT) 9 | -------------------------------------------------------------------------------- /nginx/certs/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HugoDF/docker-compose-local-https/e6e7a333fc987e9a1d280d669a3bd8715b045185/nginx/certs/.gitkeep -------------------------------------------------------------------------------- /nginx/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | nginx-proxy: 4 | image: jwilder/nginx-proxy 5 | container_name: nginx-proxy 6 | ports: 7 | - "80:80" 8 | - "443:443" 9 | volumes: 10 | - /var/run/docker.sock:/tmp/docker.sock:ro 11 | - ./certs:/etc/nginx/certs 12 | depends_on: 13 | - web 14 | 15 | web: 16 | build: ./app 17 | environment: 18 | - VIRTUAL_HOST=foo.test 19 | - VIRTUAL_PORT=8080 20 | 21 | 22 | --------------------------------------------------------------------------------