mirror of
https://github.com/cookiecutter/cookiecutter-django.git
synced 2025-07-30 17:59:48 +03:00
Add options for testing and continuous deployment with GitLab CI.
This commit is contained in:
parent
209db8aabc
commit
8a9eecea0e
|
@ -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
80
docs/ci-gitlab.rst
Normal 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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
39
{{cookiecutter.project_slug}}/.gitlab-ci.yml
Normal file
39
{{cookiecutter.project_slug}}/.gitlab-ci.yml
Normal 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 %}
|
22
{{cookiecutter.project_slug}}/compose/django/Dockerfile-test
Normal file
22
{{cookiecutter.project_slug}}/compose/django/Dockerfile-test
Normal 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"]
|
36
{{cookiecutter.project_slug}}/test.yml
Normal file
36
{{cookiecutter.project_slug}}/test.yml
Normal 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 %}
|
Loading…
Reference in New Issue
Block a user