├── LICENSE ├── README.md ├── TODO.md ├── deploy.sh ├── docker-compose.yml └── nginx-data └── Dockerfile /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017 Matthias Noback 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is furnished 8 | to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Setup for running multiple websites on a single server 2 | 3 | - Uses Nginx as a proxy server, and the [docker-gen](https://github.com/jwilder/docker-gen) and [docker-letsencrypt-nginx-proxy-companion](https://github.com/jwilder/docker-letsencrypt-nginx-proxy-companion) container utilities. 4 | - Serves secure websites with automatically generated and renewed [Let's Encrypt](http://letsencrypt.org/) certificates. 5 | - Only exposes one web server, connects to other web servers using a custom network. 6 | 7 | ## Usage 8 | 9 | - If you didn't do so already, set up a server using `docker-machine create`. 10 | - Export the name you used for the server as the environment variable `DOCKER_MACHINE_NAME`, e.g.: 11 | 12 | export DOCKER_MACHINE_NAME=personal-websites 13 | 14 | - Run `./deploy.sh` to install the Nginx proxy server. 15 | 16 | Now *for every website* you want to expose on the same server: 17 | 18 | 1. Write a Dockerfile for the website server, for example (assuming that copying some files to the default document root is sufficient): 19 | 20 | ``` 21 | FROM nginx:1.11-alpine 22 | RUN rm -rf /usr/share/nginx/html 23 | COPY web /usr/share/nginx/html 24 | ``` 25 | 26 | 2. Define a service for that container in `docker-compose.yml`: 27 | 28 | ``` 29 | version: '2' 30 | 31 | services: 32 | website: 33 | image: your-username/your-website-name 34 | build: 35 | context: . 36 | dockerfile: Dockerfile 37 | restart: always 38 | environment: 39 | - VIRTUAL_HOST=your.hostname.com 40 | - VIRTUAL_NETWORK=nginx-proxy 41 | - LETSENCRYPT_HOST=your.hostname.com 42 | - LETSENCRYPT_EMAIL=your@email.com 43 | networks: 44 | - proxy-tier 45 | 46 | networks: 47 | proxy-tier: 48 | external: 49 | name: nginx-proxy 50 | ``` 51 | 52 | 3. Deploy the website by running the following commands (of course it would make sense to automate this): 53 | 54 | ``` 55 | eval $(docker-machine env $DOCKER_MACHINE_NAME) 56 | docker network create --driver bridge nginx-proxy || true 57 | docker-compose pull 58 | docker-compose up -d --force-recreate --no-build 59 | docker-compose ps 60 | eval $(docker-machine env -u) 61 | ``` 62 | 63 | It may take a minute or so before the secure site can be reached (because the certificate has to be created first). 64 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | - Try to add smart helper scripts (e.g. wrap docker-machine env stuff in a function) 2 | -------------------------------------------------------------------------------- /deploy.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -eu 4 | 5 | echo "Deploy to ${DOCKER_MACHINE_NAME}..." 6 | 7 | eval $(docker-machine env "${DOCKER_MACHINE_NAME}") 8 | docker network create --driver bridge nginx-proxy || true 9 | docker-compose pull 10 | docker-compose up -d --force-recreate --no-build 11 | docker-compose ps 12 | eval $(docker-machine env -u) 13 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | 3 | services: 4 | nginx-data: 5 | image: matthiasnoback/nginx-data 6 | container_name: nginx-data 7 | build: 8 | context: ./ 9 | dockerfile: nginx-data/Dockerfile 10 | volumes: 11 | - /etc/nginx/certs 12 | - /etc/docker-gen/templates 13 | 14 | nginx: 15 | image: nginx 16 | container_name: nginx 17 | restart: always 18 | ports: 19 | - "80:80" 20 | - "443:443" 21 | volumes: 22 | - /etc/nginx/conf.d 23 | - /etc/nginx/vhost.d 24 | - /usr/share/nginx/html 25 | volumes_from: 26 | - nginx-data 27 | networks: 28 | - proxy-tier 29 | 30 | nginx-gen: 31 | image: jwilder/docker-gen 32 | container_name: nginx-gen 33 | restart: always 34 | command: -notify-sighup nginx -watch -wait 5s:30s /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf 35 | volumes_from: 36 | - nginx 37 | - nginx-data 38 | volumes: 39 | - /var/run/docker.sock:/tmp/docker.sock:ro 40 | networks: 41 | - proxy-tier 42 | 43 | nginx-letsencrypt: 44 | image: jrcs/letsencrypt-nginx-proxy-companion 45 | container_name: nginx-letsencrypt 46 | restart: always 47 | volumes: 48 | - /var/run/docker.sock:/var/run/docker.sock:ro 49 | volumes_from: 50 | - nginx 51 | - nginx-data 52 | environment: 53 | - NGINX_DOCKER_GEN_CONTAINER=nginx-gen 54 | networks: 55 | - proxy-tier 56 | 57 | networks: 58 | proxy-tier: 59 | external: 60 | name: nginx-proxy 61 | -------------------------------------------------------------------------------- /nginx-data/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine 2 | ADD https://raw.githubusercontent.com/jwilder/nginx-proxy/master/nginx.tmpl /etc/docker-gen/templates/nginx.tmpl 3 | VOLUME /etc/docker-gen/templates 4 | CMD /bin/true 5 | --------------------------------------------------------------------------------