Create Docker build image, build project with Docker

This commit is contained in:
bandesz
2016-08-12 11:23:50 +01:00
parent e610d83be4
commit 26ff449b77
13 changed files with 244 additions and 22 deletions

3
.gitignore vendored
View File

@@ -70,3 +70,6 @@ app/templates/govuk_template.html
npm-debug.log
environment.sh
.envrc
app/version.py

View File

@@ -18,6 +18,7 @@ after_success:
- coveralls
- ./scripts/trigger-dependent-build.sh
script:
- make generate-version-file
- npm run build
- ./scripts/run_tests.sh
notifications:
@@ -88,7 +89,6 @@ deploy:
region: eu-west-1
on: *2
before_deploy:
- ./scripts/update_version_file.sh
- rm -rf node_modules bower_components app/assets
- zip -r --exclude=*__pycache__* notifications-admin *
- mkdir -p dpl_cd_upload

128
Makefile Normal file
View File

@@ -0,0 +1,128 @@
.DEFAULT_GOAL := help
SHELL := /bin/bash
DATE = $(shell date +%Y-%m-%d:%H:%M:%S)
PIP_ACCEL_CACHE ?= ${CURDIR}/cache/pip-accel
APP_VERSION_FILE = app/version.py
GIT_BRANCH = $(shell git symbolic-ref --short HEAD 2> /dev/null || echo "detached")
GIT_COMMIT ?= $(shell git rev-parse HEAD)
DOCKER_BUILDER_IMAGE_NAME = govuk/notify-admin-builder
BUILD_TAG ?= notifications-admin-manual
BUILD_NUMBER ?= 0
DEPLOY_BUILD_NUMBER ?= ${BUILD_NUMBER}
BUILD_URL ?=
DOCKER_CONTAINER_PREFIX = ${USER}-${BUILD_TAG}
.PHONY: help
help:
@cat $(MAKEFILE_LIST) | grep -E '^[a-zA-Z_-]+:.*?## .*$$' | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
.PHONY: venv
venv: venv/bin/activate ## Create virtualenv if it does not exist
venv/bin/activate:
test -d venv || virtualenv venv
./venv/bin/pip install pip-accel
.PHONY: check-env-vars
check-env-vars: ## Check mandatory environment variables
$(if ${DEPLOY_ENV},,$(error Must specify DEPLOY_ENV))
$(if ${DNS_NAME},,$(error Must specify DNS_NAME))
$(if ${AWS_ACCESS_KEY_ID},,$(error Must specify AWS_ACCESS_KEY_ID))
$(if ${AWS_SECRET_ACCESS_KEY},,$(error Must specify AWS_SECRET_ACCESS_KEY))
.PHONY: development
development: ## Set environment to development
$(eval export DEPLOY_ENV=development)
$(eval export DNS_NAME="notify.works")
@true
.PHONY: staging
staging: ## Set environment to staging
$(eval export DEPLOY_ENV=staging)
$(eval export DNS_NAME="staging-notify.works")
@true
.PHONY: production
production: ## Set environment to production
$(eval export DEPLOY_ENV=production)
$(eval export DNS_NAME="notifications.service.gov.uk")
@true
.PHONY: dependencies
dependencies: venv ## Install build dependencies
npm set progress=false
npm install
npm rebuild node-sass
mkdir -p ${PIP_ACCEL_CACHE}
PIP_ACCEL_CACHE=${PIP_ACCEL_CACHE} ./venv/bin/pip-accel install -r requirements_for_test.txt
.PHONY: generate-version-file
generate-version-file: ## Generates the app version file
@echo -e "__travis_commit__ = \"${GIT_COMMIT}\"\n__time__ = \"${DATE}\"\n__travis_job_number__ = \"${BUILD_NUMBER}\"\n__travis_job_url__ = \"${BUILD_URL}\"" > ${APP_VERSION_FILE}
.PHONY: build
build: dependencies generate-version-file ## Build project
npm run build
.PHONY: build-codedeploy-artifact
build-codedeploy-artifact: ## Build the deploy artifact for CodeDeploy
mkdir -p target
zip -r -x@deploy-exclude.lst target/notifications-admin.zip *
.PHONY: upload-codedeploy-artifact ## Upload the deploy artifact for CodeDeploy
upload-codedeploy-artifact: check-env-vars
aws s3 cp --region eu-west-1 target/notifications-admin.zip s3://${DNS_NAME}-codedeploy/notifications-admin-${DEPLOY_BUILD_NUMBER}.zip
.PHONY: test
test: venv ## Run tests
./scripts/run_tests.sh
.PHONY: deploy
deploy: check-env-vars ## Upload deploy artifacts to S3 and trigger CodeDeploy
aws deploy create-deployment --application-name notify-admin --deployment-config-name CodeDeployDefault.OneAtATime --deployment-group-name notify-admin --s3-location bucket=${DNS_NAME}-codedeploy,key=notifications-admin-${DEPLOY_BUILD_NUMBER}.zip,bundleType=zip --region eu-west-1
.PHONY: coverage
coverage: venv ## Create coverage report
./venv/bin/coveralls
.PHONY: prepare-docker-build-image
prepare-docker-build-image: ## Prepare the Docker builder image
mkdir -p ${PIP_ACCEL_CACHE}
make -C docker build-build-image
.PHONY: build-with-docker
build-with-docker: prepare-docker-build-image ## Build inside a Docker container
docker run -i --rm \
--name "${DOCKER_CONTAINER_PREFIX}-build" \
-v `pwd`:/var/project \
-v ${PIP_ACCEL_CACHE}:/var/project/cache/pip-accel \
${DOCKER_BUILDER_IMAGE_NAME} \
make build
.PHONY: test-with-docker
test-with-docker: prepare-docker-build-image ## Run tests inside a Docker container
docker run -i --rm \
--name "${DOCKER_CONTAINER_PREFIX}-test" \
-v `pwd`:/var/project \
${DOCKER_BUILDER_IMAGE_NAME} \
make test
.PHONY: coverage-with-docker
coverage-with-docker: prepare-docker-build-image ## Generates coverage report inside a Docker container
docker run -i --rm \
--name "${DOCKER_CONTAINER_PREFIX}-coverage" \
-v `pwd`:/var/project \
${DOCKER_BUILDER_IMAGE_NAME} \
make coverage
.PHONY: clean-docker-containers
clean-docker-containers: ## Clean up any remaining docker containers
docker rm -f $(shell docker ps -q -f "name=${DOCKER_CONTAINER_PREFIX}") 2> /dev/null || true
clean:
rm -rf node_modules cache target venv .coverage

View File

@@ -1,3 +1,4 @@
__travis_commit__ = ""
__time__ = "2016-07-05:14:44:52"
__time__ = ""
__travis_job_number__ = ""
__travis_job_url__ = ""

View File

@@ -1,11 +1,11 @@
---
files:
-
---
files:
-
destination: /home/notify-app/notifications-admin
source: /
hooks:
AfterInstall:
-
hooks:
AfterInstall:
-
location: scripts/aws_install_dependencies.sh
runas: root
timeout: 300
@@ -27,11 +27,9 @@ hooks:
location: scripts/deregister_from_elb.sh
runas: ubuntu
timeout: 300
-
-
location: scripts/aws_stop_app.sh
runas: root
timeout: 300
os: linux
version: 0.0

9
deploy-exclude.lst Normal file
View File

@@ -0,0 +1,9 @@
*__pycache__*
*.git*
*app/assets*
*bower_components*
*cache*
*docker*
*node_modules*
*target*
*venv*

36
docker/Dockerfile-build Normal file
View File

@@ -0,0 +1,36 @@
FROM python:3.4-slim
ENV PYTHONUNBUFFERED=1 \
DEBIAN_FRONTEND=noninteractive \
NODEJS_VERSION=6.3.1-1nodesource1~jessie1
RUN \
echo "Install base packages" \
&& apt-get update \
&& apt-get install -y --no-install-recommends \
apt-transport-https \
make \
curl \
git \
build-essential \
libxml2-dev \
libxslt-dev \
zlib1g-dev \
zip \
rlwrap \
&& echo "Install nodejs" \
&& cd /tmp \
&& curl -sSLO https://deb.nodesource.com/node_6.x/pool/main/n/nodejs/nodejs_${NODEJS_VERSION}_amd64.deb \
&& dpkg -i /tmp/nodejs_${NODEJS_VERSION}_amd64.deb \
&& echo "Clean up" \
&& rm -rf /var/lib/apt/lists/* /tmp/*
RUN \
echo "Install global pip packages" \
&& pip install \
virtualenv \
awscli
WORKDIR /var/project

10
docker/Makefile Normal file
View File

@@ -0,0 +1,10 @@
.DEFAULT_GOAL := help
SHELL := /bin/bash
.PHONY: help
help:
@cat $(MAKEFILE_LIST) | grep -E '^[a-zA-Z_-]+:.*?## .*$$' | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
.PHONY: build-build-image
build-build-image:
docker build -f Dockerfile-build -t govuk/notify-admin-builder .

View File

@@ -183,7 +183,7 @@ get_instance_health_elb() {
;;
*)
msg "Instance '$instance_id' not part of ELB '$elb_name'"
return 0
return 1
esac
fi
}
@@ -345,3 +345,40 @@ get_instance_id() {
curl -s http://169.254.169.254/latest/meta-data/instance-id
return $?
}
# Usage: get_instance_name_from_tags <instance_id>
#
# Looks up tags for the given instance, extracting the 'name'
# returns <name> or error_exit
get_instance_name_from_tags() {
local instance_id=$1
local instance_name=$($AWS_CLI ec2 describe-tags \
--filters "Name=resource-id,Values=${instance_id}" \
--query Tags[0].Value \
--output text)
if [ $? != 0 ]; then
error_exit "Couldn't get instance name for '$instance_id'"
fi
echo $instance_name
return $?
}
ELB_NAME=""
get_elb_name_for_instance_name() {
local instance_name=$1
declare -A elb_to_instance_mapping
elb_to_instance_mapping['notify-admin']='notify-admin'
elb_to_instance_mapping['notify_admin']='notify-admin-elb'
local elb_name=${elb_to_instance_mapping[${instance_name}]}
if [ -z $elb_name ]; then
msg "No ELB for instance ${instance_name}"
else
ELB_NAME=$elb_name
fi
}

View File

@@ -28,7 +28,9 @@ msg "Started $(basename $0) at $(/bin/date "+%F %T")"
start_sec=$(/bin/date +%s.%N)
msg "Getting relevant load balancer"
get_elb_list $INSTANCE_ID "notify-admin-elb"
INSTANCE_NAME=$(get_instance_name_from_tags $INSTANCE_ID)
get_elb_name_for_instance_name $INSTANCE_NAME
get_elb_list $INSTANCE_ID $ELB_NAME
msg "Checking that user set at least one load balancer"
if test -z "$ELB_LIST"; then

View File

@@ -28,8 +28,10 @@ msg "Started $(basename $0) at $(/bin/date "+%F %T")"
start_sec=$(/bin/date +%s.%N)
msg "Getting relevant load balancer"
get_elb_list $INSTANCE_ID "notify-admin-elb"
INSTANCE_NAME=$(get_instance_name_from_tags $INSTANCE_ID)
get_elb_name_for_instance_name $INSTANCE_NAME
ELB_LIST=$ELB_NAME
get_elb_list $INSTANCE_ID $ELB_NAME
msg "Checking that user set at least one load balancer"
if test -z "$ELB_LIST"; then

View File

@@ -24,6 +24,9 @@ function display_result {
fi
}
if [ -d venv ]; then
source ./venv/bin/activate
fi
pep8 .
display_result $? 1 "Code style check"

View File

@@ -1,7 +0,0 @@
#!/bin/bash
#
# Update the version file of the project from the Travis build details
#
sed -i -e "s/__travis_commit__ =.*/__travis_commit__ = \"$TRAVIS_COMMIT\"/g" ./app/version.py
sed -i -e "s/__travis_job_number__ =.*/__travis_job_number__ = \"$TRAVIS_BUILD_NUMBER\"/g" ./app/version.py
sed -i -e "s/__time__ =.*/__time__ = \"$(date +%Y-%m-%d:%H:%M:%S)\"/g" ./app/version.py