Add options for testing and continuous deployment with GitLab CI.

This commit is contained in:
Gregg Sangster 2016-06-18 00:14:05 -04:00
parent 209db8aabc
commit 8a9eecea0e
7 changed files with 228 additions and 1 deletions

View File

@ -20,5 +20,9 @@
"use_compressor": "n", "use_compressor": "n",
"js_task_runner": ["Gulp", "Grunt", "None"], "js_task_runner": ["Gulp", "Grunt", "None"],
"use_lets_encrypt": "n", "use_lets_encrypt": "n",
"use_gitlab_ci": "n",
"staging_branch": "",
"staging_domain_name": "beta.{{ cookiecutter.domain_name }}",
"production_branch": "",
"open_source_license": ["MIT", "BSD", "Apache Software License 2.0", "Not open source"] "open_source_license": ["MIT", "BSD", "Apache Software License 2.0", "Not open source"]
} }

80
docs/ci-gitlab.rst Normal file
View File

@ -0,0 +1,80 @@
Testing and Contiinuous Deployment with GitLab CI
=================================================
Prerequisites
-------------
* Docker and Docker Compose (minimum versions in Deployment with Docker)
* Docker Machine for continuous deployment (tested with 0.5.5)
Configuring GitLab CI to Run the Tests
--------------------------------------
1) Set up an Ubuntu machine with Docker. Digital Ocean has a droplet configuration
that makes this very convenient but any machine will do.
2) Install docker-compose according to the docs:
::
curl -L https://github.com/docker/compose/releases/download/1.5.2/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
2) Install docker-machine according to the docs:
::
curl -L https://github.com/docker/machine/releases/download/v0.5.5/docker-machine_linux-amd64 > /usr/local/bin/docker-machine
chmod +x /usr/local/bin/docker-machine
3) Install and register gitlab-ci-multi-runner according to the docs. When registering,
use the shell executor:
::
curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-ci-multi-runner/script.deb.sh | sudo bash
apt-get install gitlab-ci-multi-runner
gitlab-runner register # Use shell executor.
4) Add the gitlab-runner user account to the docker group:
::
usermod -aG docker gitlab-runner
At ths point, GitLab CI is capable of running the tests. Continue on below to
set up continuous deployment.
Configuring GitLab CI for Continuous Deployment
-----------------------------------------------
1) Set up Ubuntu machines with Docker for the staging (if desired) and production
sites. Digital Ocean has a droplet configuration that makes this very convenient
but any machines will do.
2) On the test runner, create an ssh key. Add it as an authorized key on the
staging and production machines and as a deploy key in the GitLab project:
::
sudo -u gitlab-runner -H ssh-keygen -t rsa -C "gitlab-runner@DOMAIN"
3) On the test runner, create a docker machine for the staging site:
::
sudo -u gitlab-runner -H docker-machine create -d generic --generic-ip-address <IP address of staging site> {{cookiecutter.staging_domain_name}}
4) On the test runner, create a docker machine for the production site:
::
sudo -u gitlab-runner -H docker-machine create -d generic --generic-ip-address <IP address of production site> {{cookiecutter.domain_name}}
All Done
--------
Congratulations! You now have a GitLab CI environment to run the tests for
every commit (all branches including feature branches) and automatically deploy
staging and production environments.

View File

@ -49,6 +49,20 @@ use_python2 [n]
By default, the Python code generated will be for Python 3.x. But if you By default, the Python code generated will be for Python 3.x. But if you
answer `y` here, it will be legacy Python 2.7 code. answer `y` here, it will be legacy Python 2.7 code.
use_gitlab_ci [n]
Whether to use GitLab CI for testing.
staging_branch []
If using GitLab for continuous deployment, the git branch to deploy in the
staging environment.
staging_domain_name [beta.domain_name]
If deploying to a staging environment, the domain name of the staging site.
production_branch []
If using GitLab for continuous deployment, the git branch to deploy in the
production environment.
.. _WhiteNoise: https://github.com/evansd/whitenoise .. _WhiteNoise: https://github.com/evansd/whitenoise
.. _Celery: https://github.com/celery/celery .. _Celery: https://github.com/celery/celery
.. _MailHog: https://github.com/mailhog/MailHog .. _MailHog: https://github.com/mailhog/MailHog

View File

@ -170,6 +170,20 @@ def remove_certbot_files():
file_name = os.path.join(nginx_dir_location, filename) file_name = os.path.join(nginx_dir_location, filename)
remove_file(file_name) remove_file(file_name)
def remove_gitlab_ci_files():
"""
Removes files needed for GitLab CI if it isn't going to be used
"""
for filename in [".gitlab-ci.yml, test.yml"]:
os.remove(os.path.join(
PROJECT_DIRECTORY, filename
))
django_dir_location = os.path.join(PROJECT_DIRECTORY, 'compose/django')
for filename in ["Dockerfile-test"]:
file_name = os.path.join(django_dir_location, filename)
remove_file(file_name)
# IN PROGRESS # IN PROGRESS
# def copy_doc_files(project_directory): # def copy_doc_files(project_directory):
# cookiecutters_dir = DEFAULT_CONFIG['cookiecutters_dir'] # cookiecutters_dir = DEFAULT_CONFIG['cookiecutters_dir']
@ -245,5 +259,23 @@ if '{{ cookiecutter.use_lets_encrypt }}'.lower() == 'y' and '{{ cookiecutter.use
"You must generate a dhparams.pem file before running docker-compose in a production environment." "You must generate a dhparams.pem file before running docker-compose in a production environment."
) )
# 4. Copy files from /docs/ to {{ cookiecutter.project_slug }}/docs/ # 11. Removes all GitLab CI files if it isn't going to be used
if '{{ cookiecutter.use_gitlab_ci }}'.lower() != 'y':
remove_gitlab_ci_files()
# 12. Removes the GitLab CI files and display a warning if use_gitlab_ci is selected and use_docker isn't.
if '{{ cookiecutter.use_gitlab_ci }}'.lower() == 'y' and '{{ cookiecutter.use_docker }}'.lower() != 'y':
remove_gitlab_ci_files()
print(
"You selected to use GitLab CI and didn't select to use docker. This is NOT supported out of the box for now. You "
"can continue to use the project like you normally would, but GitLab CI files have not been included."
)
# 13. Directs the user to the documentation if certbot and docker are selected.
if '{{ cookiecutter.use_gitlab_ci }}'.lower() == 'y' and '{{ cookiecutter.use_docker }}'.lower() == 'y':
print(
"You selected to use GitLab CI. Please see the documentation for instructions on how to set up the GitLab CI environment"
)
# 14. Copy files from /docs/ to {{ cookiecutter.project_slug }}/docs/
# copy_doc_files(PROJECT_DIRECTORY) # copy_doc_files(PROJECT_DIRECTORY)

View File

@ -0,0 +1,39 @@
stages:
- test
- deploy
test:
script:
- docker-compose -f test.yml build
- docker-compose -f test.yml run --rm django bash -c "flake8"
- docker-compose -f test.yml run --rm django bash -c "coverage run --branch manage.py test && coverage report -m"
{% if cookiecutter.staging_branch != '' %}
staging:
type: deploy
script:
- eval "$(docker-machine env {{cookiecutter.staging_domain_name}})"
- docker-compose build
- docker-compose run --rm django python manage.py migrate
- docker-compose up -d
- docker rm -v `docker ps -a -q -f status=exited` || true
- docker rmi `docker images -f "dangling=true" -q` || true
- docker run -v /var/run/docker.sock:/var/run/docker.sock -v /var/lib/docker:/var/lib/docker --rm martin/docker-cleanup-volumes
only:
- {{cookiecutter.staging_branch}}
{% endif %}
{% if cookiecutter.production_branch != '' %}
production:
type: deploy
script:
- eval "$(docker-machine env {{cookiecutter.domain_name}})"
- docker-compose build
- docker-compose run --rm django python manage.py migrate
- docker-compose up -d
- docker rm -v `docker ps -a -q -f status=exited` || true
- docker rmi `docker images -f "dangling=true" -q` || true
- docker run -v /var/run/docker.sock:/var/run/docker.sock -v /var/lib/docker:/var/lib/docker --rm martin/docker-cleanup-volumes
only:
- {{cookiecutter.production_branch}}
{% endif %}

View File

@ -0,0 +1,22 @@
{% if cookiecutter.use_python2 == 'n' -%}
FROM python:3.5
{% else %}
FROM python:2.7
{%- endif %}
ENV PYTHONUNBUFFERED 1
# Requirements have to be pulled and installed here, otherwise caching won't work
COPY ./requirements /requirements
RUN pip install -r /requirements/local.txt
RUN groupadd -r django && useradd -r -g django django
COPY . /app
RUN chown -R django /app
COPY ./compose/django/entrypoint.sh /entrypoint.sh
RUN sed -i 's/\r//' /entrypoint.sh
RUN chmod +x /entrypoint.sh
WORKDIR /app
ENTRYPOINT ["/entrypoint.sh"]

View File

@ -0,0 +1,36 @@
version: '2'
volumes:
postgres_data_dev: {}
postgres_backup_dev: {}
services:
postgres:
build: ./compose/postgres
volumes:
- postgres_data_dev:/var/lib/postgresql/data
- postgres_backup_dev:/backups
environment:
- POSTGRES_USER={{cookiecutter.project_slug}}
django:
build:
context: .
dockerfile: ./compose/django/Dockerfile-test
command: python /app/manage.py runserver_plus 0.0.0.0:8000
depends_on:
- postgres
ports:
- "8000:8000"
links:
- postgres
{% if cookiecutter.use_mailhog == 'y' %}
- mailhog
{% endif %}
{% if cookiecutter.use_mailhog == 'y' %}
mailhog:
image: mailhog/mailhog
ports:
- "8025:8025"
{% endif %}