Skip to content

Instantly share code, notes, and snippets.

@lu911
Created February 24, 2017 10:23
Show Gist options
  • Save lu911/cdb5bd0420cf4c86bc823d72a454e8f7 to your computer and use it in GitHub Desktop.
Save lu911/cdb5bd0420cf4c86bc823d72a454e8f7 to your computer and use it in GitHub Desktop.
ddingdon deploy
@task
def deploy():
"""
Deploy the project.
"""
# check stage
require('stage', provided_by=(stage_api, stage_admin,
production_api, production_admin))
repo = env.docker_repo
latest_tag = env.docker_tag
prev_latest_tag = 'prev-{0}'.format(latest_tag)
service = env.docker_compose_service
with aws_credential():
ecr_login = local('aws ecr get-login', capture=True)
# check tags from current commit_id image
commit_id = local('git rev-parse HEAD', capture=True)
with settings(warn_only=True):
image = local('aws ecr describe-images '
'--repository-name {0} '
'--image-ids '
'--query imageDetails[0] '
'imageTag={1}'.format(repo, commit_id), capture=True)
if image.return_code != 0:
return abort("<ECR {0}:{1}> doesn't exist.".format(repo, commit_id))
image = json.loads(image)
image_tags = image['imageTags']
if latest_tag not in image_tags:
# "latest" image tagged "prev_latest"
manifest = local('aws ecr batch-get-image '
'--repository-name {0} '
'--image-ids imageTag={1} '
'--query images[].imageManifest '
'--output text'.format(repo, latest_tag), capture=True)
if manifest:
with settings(warn_only=True):
local('aws ecr put-image '
'--repository-name {0} '
'--image-tag {1} '
'--image-manifest \'{2}\''.format(repo, prev_latest_tag, manifest))
# last image tagged "latest"
commit_id = local('git rev-parse HEAD', capture=True)
manifest = local('aws ecr batch-get-image '
'--repository-name {0} '
'--image-ids imageTag={1} '
'--query images[].imageManifest '
'--output text'.format(repo, commit_id), capture=True)
local('aws ecr put-image '
'--repository-name {0} '
'--image-tag {1} '
'--image-manifest \'{2}\''.format(repo, latest_tag, manifest))
migrated = False
for host in env.docker_hosts:
with shell_env(DOCKER_HOST='tcp://{0}'.format(host)):
# docker login to ecr
local(ecr_login)
# pull image
local('docker-compose -f {0} pull {1}'.format(env.docker_compose_file, service))
# db migration
if env.db_migration and not migrated:
migration_container = '{0}-{1}'.format(repo, env.docker_compose_migration_service)
with settings(warn_only=True):
result = local(
'docker-compose -f {0} run --name {1} {2} '
'/bin/bash -c "cd {3}; python manage.py db upgrade"'.format(
env.docker_compose_file,
migration_container,
env.docker_compose_migration_service,
env.code_path)
)
local('docker rm {0}'.format(migration_container))
if result.return_code != 0:
return abort("Database migration failed.")
migrated = True
# check blue-green
blue_name = '{0}-blue'.format(repo)
green_name = '{0}-green'.format(repo)
with settings(warn_only=True):
exist_blue = local('docker-compose '
'-f {0} '
'ps | grep {1}.*Up'.format(env.docker_compose_file, blue_name),
capture=True)
if exist_blue:
current_container = blue_name
deploy_container = green_name
else:
current_container = green_name
deploy_container = blue_name
# run deploy container
local('docker-compose -f {0} run -d --name {1} {2}'.format(env.docker_compose_file,
deploy_container,
service))
# stop & remove current container
with settings(warn_only=True):
local('docker stop {0}'.format(current_container))
local('docker rm {0}'.format(current_container))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment