Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Functional testing #42

Merged
merged 20 commits into from
Feb 9, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
c4a4ed6
Add nginx-ssl interface (non-public)
jasonpincin Oct 19, 2016
602e0b5
Removing example
jasonpincin Oct 21, 2016
24ed42d
Exit without error when not leader. Added watch, which starts consul-…
jasonpincin Oct 21, 2016
80300a2
Seperated generate-config and reload for clarity in containerpilot.json
jasonpincin Oct 21, 2016
a70f486
Broke nginx config out into multiple files, suitable for partial over…
jasonpincin Oct 21, 2016
f7a8a63
Do not do debug logging by default. Axed absolute paths for readabili…
jasonpincin Oct 21, 2016
3789a55
Updated for restructured Nginx config and nginx config templates dire…
jasonpincin Oct 21, 2016
4eb70c0
Removed .sh extensions for consistency
jasonpincin Oct 21, 2016
06491cb
Pin Nginx container version
jasonpincin Oct 21, 2016
15fc76d
Update to ContainerPilot 2.4.4
jasonpincin Nov 7, 2016
ac6aeea
Link to mozilla SSL best practices
jasonpincin Nov 7, 2016
faf5c39
reduce calls to consul-template
jasonpincin Nov 7, 2016
855c6bc
No -k option on curl tests. Use LE Staging CA Cert for curl when ACME…
jasonpincin Nov 8, 2016
aca95b8
Resolve merge conflicts
tgross Feb 3, 2017
91c4d41
Bump ContainerPilot to 2.7.0, Consul to 0.7.3
tgross Feb 3, 2017
ea37c45
Stub out tests and provide new example deployment for Compose and Triton
tgross Feb 3, 2017
a41c023
Fix bugs in example CNS naming and Consul setup
tgross Feb 6, 2017
11767ec
Simple scale-up test
tgross Feb 6, 2017
e431efb
Add test section for netsplit recovery
tgross Feb 7, 2017
696895b
Instrument convergence and adjust waits
tgross Feb 7, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# credentials
_env*

# macos frustration
.DS_Store

# generated content
ExampleFile
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "test/testing"]
path = test/testing
url = https://github.com/autopilotpattern/testing.git
21 changes: 12 additions & 9 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# A minimal Nginx container including ContainerPilot and a simple virtualhost config
FROM nginx:latest
# A minimal Nginx container including ContainerPilot
FROM nginx:1.11

# Add some stuff via apt-get
RUN apt-get update \
Expand All @@ -11,8 +11,8 @@ RUN apt-get update \

# Install Consul
# Releases at https://releases.hashicorp.com/consul
RUN export CONSUL_VERSION=0.7.0 \
&& export CONSUL_CHECKSUM=b350591af10d7d23514ebaa0565638539900cdb3aaa048f077217c4c46653dd8 \
RUN export CONSUL_VERSION=0.7.3 \
&& export CONSUL_CHECKSUM=901a3796b645c3ce3853d5160080217a10ad8d9bd8356d0b73fcd6bc078b7f82 \
&& curl --retry 7 --fail -vo /tmp/consul.zip "https://releases.hashicorp.com/consul/${CONSUL_VERSION}/consul_${CONSUL_VERSION}_linux_amd64.zip" \
&& echo "${CONSUL_CHECKSUM} /tmp/consul.zip" | sha256sum -c \
&& unzip /tmp/consul -d /usr/local/bin \
Expand All @@ -25,18 +25,18 @@ RUN mkdir -p /etc/consul \

# Install Consul template
# Releases at https://releases.hashicorp.com/consul-template/
RUN export CONSUL_TEMPLATE_VERSION=0.14.0 \
&& export CONSUL_TEMPLATE_CHECKSUM=7c70ea5f230a70c809333e75fdcff2f6f1e838f29cfb872e1420a63cdf7f3a78 \
RUN export CONSUL_TEMPLATE_VERSION=0.18.0 \
&& export CONSUL_TEMPLATE_CHECKSUM=f7adf1f879389e7f4e881d63ef3b84bce5bc6e073eb7a64940785d32c997bc4b \
&& curl --retry 7 --fail -Lso /tmp/consul-template.zip "https://releases.hashicorp.com/consul-template/${CONSUL_TEMPLATE_VERSION}/consul-template_${CONSUL_TEMPLATE_VERSION}_linux_amd64.zip" \
&& echo "${CONSUL_TEMPLATE_CHECKSUM} /tmp/consul-template.zip" | sha256sum -c \
&& unzip /tmp/consul-template.zip -d /usr/local/bin \
&& rm /tmp/consul-template.zip

# Add Containerpilot and set its configuration
ENV CONTAINERPILOT_VER 2.4.3
ENV CONTAINERPILOT_VER 2.7.0
ENV CONTAINERPILOT file:///etc/containerpilot.json

RUN export CONTAINERPILOT_CHECKSUM=2c469a0e79a7ac801f1c032c2515dd0278134790 \
RUN export CONTAINERPILOT_CHECKSUM=687f7d83e031be7f497ffa94b234251270aee75b \
&& curl -Lso /tmp/containerpilot.tar.gz \
"https://github.com/joyent/containerpilot/releases/download/${CONTAINERPILOT_VER}/containerpilot-${CONTAINERPILOT_VER}.tar.gz" \
&& echo "${CONTAINERPILOT_CHECKSUM} /tmp/containerpilot.tar.gz" | sha1sum -c \
Expand All @@ -56,7 +56,10 @@ RUN export JQ_VERSION=1.5 \
&& chmod a+x /usr/local/bin/jq

# Add our configuration files and scripts
COPY etc /etc
RUN rm -f /etc/nginx/conf.d/default.conf
COPY etc/acme /etc/acme
COPY etc/containerpilot.json /etc/
COPY etc/nginx /etc/nginx/templates
COPY bin /usr/local/bin

# Usable SSL certs written here
Expand Down
32 changes: 3 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,39 +12,13 @@ The goal of this project is to create an Nginx image that can be reused across e

### Running in your own project

Consult https://github.com/autopilotpattern/wordpress for example usage.

### Hello world example

1. [Get a Joyent account](https://my.joyent.com/landing/signup/) and [add your SSH key](https://docs.joyent.com/public-cloud/getting-started).
1. Install the [Docker Toolbox](https://docs.docker.com/installation/mac/) (including `docker` and `docker-compose`) on your laptop or other environment, as well as the [Joyent Triton CLI](https://www.joyent.com/blog/introducing-the-triton-command-line-tool) (`triton` replaces our old `sdc-*` CLI tools).
1. [Configure Docker and Docker Compose for use with Joyent.](https://docs.joyent.com/public-cloud/api-access/docker)

Check that everything is configured correctly by running `./setup.sh`. This will check that your environment is setup correctly and will create an `_env` file that includes injecting an environment variable for the Consul hostname into the Nginx and App containers so we can take advantage of [Triton Container Name Service (CNS)](https://www.joyent.com/blog/introducing-triton-container-name-service).

Start everything:

```bash
docker-compose -p nginx up -d
```

The Nginx server will register with the Consul server named in the `_env` file. You can see its status there in the Consul web UI. On a Mac, you can open your browser to that with the following command:

```bash
open "http://$(triton ip nginx_consul_1):8500/ui"
```

You can open the demo app that Nginx is proxying by opening a browser to the Nginx instance IP:

```bash
open "http://$(triton ip nginx_nginx_1)/example"
```
Consult https://github.com/autopilotpattern/wordpress for example usage, or see the examples in the examples directory for deploying to Joyent's Triton Cloud or via Docker Compose.

### Configuring LetsEncrypt (ACME)

Setting the `ACME_DOMAIN` environment variable will enable LetsEncrypt within the image. The image will automatically acquire certificates for the given domain, and renew them over time. If you scale to multiple instances of Nginx, they will elect a leader who will be responsible for renewing the certificates. Any challenge response tokens as well as acquired certificates will be replicated to all Nginx instances.
Setting the `ACME_DOMAIN` environment variable will enable LetsEncrypt within the image. The image will automatically acquire certificates for the given domain, and renew them over time. If you scale to multiple instances of Nginx, they will elect a leader who will be responsible for renewing the certificates. Any challenge response tokens as well as acquired certificates will be replicated to all Nginx instances.

By default, this process will use the LetsEncrypt staging endpoint, so as not to impact your api limits. When ready for production, you must also set the `ACME_ENV` environment variable to `production`.
By default, this process will use the LetsEncrypt staging endpoint, so as not to impact your api limits. When ready for production, you must also set the `ACME_ENV` environment variable to `production`.

You must ensure the domain resolves to your Nginx containers so that they can respond to the ACME http challenges. Triton users may [refer to this document](https://docs.joyent.com/public-cloud/network/cns/faq#can-i-use-my-own-domain-name-with-triton-cns) for more information on how to insure your domain resolves to your Triton containers.

Expand Down
21 changes: 13 additions & 8 deletions bin/acme
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ function renewConsulSession () {

function createConsulSession () {
printf "Creating Consul session... "
local SID=$(curl -sX PUT -d '{"LockDelay":"0s","Name":"acme-lock","Behavior":"release","TTL":"600s"}' ${CONSUL_ROOT}/session/create | awk -F '"' '{print $4}')
local SID=$(curl -sX PUT -d '{"LockDelay":"0s","Name":"acme-lock","Behavior":"release","TTL":"5400s"}' ${CONSUL_ROOT}/session/create | awk -F '"' '{print $4}')
rc=$?
if [[ $rc -ne 0 ]]; then
echo "failed"
Expand Down Expand Up @@ -106,10 +106,10 @@ function updateKeys () {
local TEMP_PRIVKEY="${TEMP_CERT_DIR}/privkey.pem"
local FULLCHAIN="${CERT_DIR}/fullchain.pem"
local PRIVKEY="${CERT_DIR}/privkey.pem"
if [ -f ${TEMP_FULLCHAIN} -a -f ${TEMP_PRIVKEY} -a "$(cat ${TEMP_FULLCHAIN})" != "" -a "$(cat ${TEMP_PRIVKEY})" != "" ]; then
if [ -f ${TEMP_FULLCHAIN} -a -f ${TEMP_PRIVKEY} -a "$(cat ${TEMP_FULLCHAIN} 2> /dev/null)" != "" -a "$(cat ${TEMP_PRIVKEY} 2> /dev/null)" != "" ]; then
cp -f $TEMP_FULLCHAIN $FULLCHAIN
cp -f $TEMP_PRIVKEY $PRIVKEY
$SCRIPTPATH/reload.sh
$SCRIPTPATH/reload
fi
}

Expand All @@ -126,9 +126,8 @@ case "$1" in
acquire-leader)
acquireLeader
;;
checkin)
renewConsulSession &&
( acquireLeader || exit 0 )
watch)
/usr/local/bin/consul-template -config /etc/acme/watch.hcl -consul $CONSUL_HOST:8500
;;
init)
if [ -f ${CERT_DIR}/fullchain.pem -a -f ${CERT_DIR}/privkey.pem ]; then
Expand All @@ -142,13 +141,13 @@ case "$1" in
renew-certs)
shift
renewConsulSession &&
acquireLeader &&
(acquireLeader || exit 0) &&
${SCRIPTPATH}/dehydrated --cron --domain ${ACME_DOMAIN} --hook /etc/acme/dehydrated/hook.sh --config /etc/acme/dehydrated/config.${ACME_ENV}
;;
clean-certs)
shift
renewConsulSession &&
acquireLeader &&
(acquireLeader || exit 0) &&
${SCRIPTPATH}/dehydrated --cleanup --domain ${ACME_DOMAIN} --hook /etc/acme/dehydrated/hook.sh --config /etc/acme/dehydrated/config.${ACME_ENV}
;;
generate-challenge-token)
Expand All @@ -157,6 +156,12 @@ case "$1" in
update-keys)
updateKeys
;;
checkin)
renewConsulSession &&
( acquireLeader || exit 0 ) &&
${SCRIPTPATH}/dehydrated --cron --domain ${ACME_DOMAIN} --hook /etc/acme/dehydrated/hook.sh --config /etc/acme/dehydrated/config.${ACME_ENV} &&
${SCRIPTPATH}/dehydrated --cleanup --domain ${ACME_DOMAIN} --hook /etc/acme/dehydrated/hook.sh --config /etc/acme/dehydrated/config.${ACME_ENV}
;;
*)
echo $"Usage: $0 [ {get,create,renew}-consul-session | acquire-leader | init | checkin | renew-certs | clean-certs | generate-challenge-token ]"
exit 1
Expand Down
31 changes: 31 additions & 0 deletions bin/generate-config
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!/bin/bash
set -e

SERVICE_NAME=${SERVICE_NAME:-nginx}
CONSUL=${CONSUL:-consul}
CERT_DIR="/var/www/ssl"

# Determine whether ACME SSL certificates have been acquired
SSL_READY="false"
if [ -f ${CERT_DIR}/fullchain.pem -a -f ${CERT_DIR}/privkey.pem ]; then
export SSL_READY="true"
fi

# Generate a conf.d config file for every corresponding conf.d Consul template
for f in $(ls -1 /etc/nginx/templates/conf.d/)
do
consul-template \
-once \
-dedup \
-consul-addr "${CONSUL}:8500" \
-template "/etc/nginx/templates/conf.d/${f}:/etc/nginx/conf.d/${f}"
done

# Render Nginx configuration template using values from Consul
consul-template \
-once \
-dedup \
-consul-addr "${CONSUL}:8500" \
-template "/etc/nginx/templates/health.conf:/etc/nginx/health.conf" \
-template "/etc/nginx/templates/ssl.conf:/etc/nginx/ssl.conf" \
-template "/etc/nginx/templates/nginx.conf:/etc/nginx/nginx.conf"
17 changes: 17 additions & 0 deletions bin/health-check
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/usr/bin/env bash

LE_STAGING_CACERT=/etc/acme/ca/lets-encrypt-staging.crt
ACME_ENV=${ACME_ENV:-staging}

SCHEME=$1

if [[ $SCHEME == "https" ]]; then
grep -q $ACME_DOMAIN /etc/hosts || printf "\n\n127.0.0.1 ${ACME_DOMAIN}\n" >> /etc/hosts
if [[ "$ACME_ENV" == "staging" ]]; then
curl --cacert $LE_STAGING_CACERT -fsSo /dev/null "https://${ACME_DOMAIN}/nginx-health"
else
curl -fsSo /dev/null "https://${ACME_DOMAIN}/nginx-health"
fi
else
curl -fsSo /dev/null "http://localhost/nginx-health"
fi
5 changes: 5 additions & 0 deletions bin/reload
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash
set -e

generate-config
nginx -s reload
48 changes: 0 additions & 48 deletions bin/reload.sh

This file was deleted.

File renamed without changes.
53 changes: 0 additions & 53 deletions docker-compose.yml

This file was deleted.

29 changes: 29 additions & 0 deletions etc/acme/ca/lets-encrypt-staging.crt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
-----BEGIN CERTIFICATE-----
MIIFATCCAumgAwIBAgIRAKc9ZKBASymy5TLOEp57N98wDQYJKoZIhvcNAQELBQAw
GjEYMBYGA1UEAwwPRmFrZSBMRSBSb290IFgxMB4XDTE2MDMyMzIyNTM0NloXDTM2
MDMyMzIyNTM0NlowGjEYMBYGA1UEAwwPRmFrZSBMRSBSb290IFgxMIICIjANBgkq
hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA+pYHvQw5iU3v2b3iNuYNKYgsWD6KU7aJ
diddtZQxSWYzUI3U0I1UsRPTxnhTifs/M9NW4ZlV13ZfB7APwC8oqKOIiwo7IwlP
xg0VKgyz+kT8RJfYr66PPIYP0fpTeu42LpMJ+CKo9sbpgVNDZN2z/qiXrRNX/VtG
TkPV7a44fZ5bHHVruAxvDnylpQxJobtCBWlJSsbIRGFHMc2z88eUz9NmIOWUKGGj
EmP76x8OfRHpIpuxRSCjn0+i9+hR2siIOpcMOGd+40uVJxbRRP5ZXnUFa2fF5FWd
O0u0RPI8HON0ovhrwPJY+4eWKkQzyC611oLPYGQ4EbifRsTsCxUZqyUuStGyp8oa
aoSKfF6X0+KzGgwwnrjRTUpIl19A92KR0Noo6h622OX+4sZiO/JQdkuX5w/HupK0
A0M0WSMCvU6GOhjGotmh2VTEJwHHY4+TUk0iQYRtv1crONklyZoAQPD76hCrC8Cr
IbgsZLfTMC8TWUoMbyUDgvgYkHKMoPm0VGVVuwpRKJxv7+2wXO+pivrrUl2Q9fPe
Kk055nJLMV9yPUdig8othUKrRfSxli946AEV1eEOhxddfEwBE3Lt2xn0hhiIedbb
Ftf/5kEWFZkXyUmMJK8Ra76Kus2ABueUVEcZ48hrRr1Hf1N9n59VbTUaXgeiZA50
qXf2bymE6F8CAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMB
Af8wHQYDVR0OBBYEFMEmdKSKRKDm+iAo2FwjmkWIGHngMA0GCSqGSIb3DQEBCwUA
A4ICAQBCPw74M9X/Xx04K1VAES3ypgQYH5bf9FXVDrwhRFSVckria/7dMzoF5wln
uq9NGsjkkkDg17AohcQdr8alH4LvPdxpKr3BjpvEcmbqF8xH+MbbeUEnmbSfLI8H
sefuhXF9AF/9iYvpVNC8FmJ0OhiVv13VgMQw0CRKkbtjZBf8xaEhq/YqxWVsgOjm
dm5CAQ2X0aX7502x8wYRgMnZhA5goC1zVWBVAi8yhhmlhhoDUfg17cXkmaJC5pDd
oenZ9NVhW8eDb03MFCrWNvIh89DDeCGWuWfDltDq0n3owyL0IeSn7RfpSclpxVmV
/53jkYjwIgxIG7Gsv0LKMbsf6QdBcTjhvfZyMIpBRkTe3zuHd2feKzY9lEkbRvRQ
zbh4Ps5YBnG6CKJPTbe2hfi3nhnw/MyEmF3zb0hzvLWNrR9XW3ibb2oL3424XOwc
VjrTSCLzO9Rv6s5wi03qoWvKAQQAElqTYRHhynJ3w6wuvKYF5zcZF3MDnrVGLbh1
Q9ePRFBCiXOQ6wPLoUhrrbZ8LpFUFYDXHMtYM7P9sc9IAWoONXREJaO08zgFtMp4
8iyIYUyQAbsvx8oD2M8kRvrIRSrRJSl6L957b4AFiLIQ/GgV2curs0jje7Edx34c
idWw1VrejtwclobqNMVtG3EiPUIpJGpbMcJgbiLSmKkrvQtGng==
-----END CERTIFICATE-----
Loading