How To Create a CI CD in simple python program
The final project structure would be like this:
For CI CD we need this particular files:
- bin/ansible/project_name.playbook.yml
- hosts -> to list hostname and its IP of destination server
- Dockerfile -> image for the project
- .gitlab-ci.yml -> step to do the CI and CD in yaml format.
First, we create a Dockerfile to run the program. in this case, it would be a python program.
FROM python:3.8.0 AS project_name
ADD requirements.txt /tmp
RUN pip install -r /tmp/requirements.txt
COPY . /opt/project_name
WORKDIR /opt/project_name
ENTRYPOINT ["/opt/project_name/run.sh"]
try to run it manually, whether your program is running well or not. Adjust some configurations until it works perfectly.
$ sudo docker run -it project_name:latest /bin/bash
then push it to the repository. In this case, we use google cloud to store our image.
$ sudo docker tag project_name:latest your_region.gcr.io/your_google_project/project_name:latest$ sudo docker push your_region.gcr.io/your_google_project/project_name:latest
Created bin directory for ansible deployment:
- Create playbook
---
- name: deploy project_name scheduler
hosts: adhoc
connection: ssh
tasks: - name: Login to your_region.gcr.io
command: bash -c "cat /home/your_project/.config/your_configuration_file | docker login -u _json_key --password-stdin your_regio.gcr.io"
- name: pull image your_project
docker_image:
name: your_region.gcr.io/your_google_project/project_name
source: pull
repository: your_region.gcr.io/your_google_project/project_name
force_source: yes
- name: remove old docker image
command: bash -c 'docker images your_region.gcr.io/your_google_project/project_name:latest --filter "before=your_region.gcr.io/your_google_project/project_name:latest" -q | xargs docker rmi -f || true'
2. added file called hosts so the gitlab server can refer to your host
[localhost]
localhost[adhoc]
your_hostname ansible_host=your_host_ip ansible_user=your_host_user
3. create gitlab-ci.yml in root dir of your project. We’re using dind
image (docker in docker image). This image is used for creating docker image inside a docker image.
image:
name: your_region.gcr.io/your_google_project/your_ansible_imagestages:
- testing
- build
- deployvariables:
PATH_CREDENTIAL: "/tmp/id_rsa"
ANSIBLE_HOST_KEY_CHECKING: "false"before_script:
- echo "${RSA64_GITLAB_RUNNER}" | base64 -d > ${PATH_CREDENTIAL}
- chmod 600 ${PATH_CREDENTIAL}testing:config:
stage: testing
variables:
GCLOUD_CREDENTIAL: /root/gcloud-credential.json
before_script:
- echo "${GCLOUD_CREDENTIAL64}" | base64 -d > ${GCLOUD_CREDENTIAL}
script:
- echo "TODO:Config Testing"testing:unit:
image: your_region.gcr.io/your_google_project/project_name_testing:latest
stage: testing
script:
- pytestbuild:docker:
image: docker:latest
stage: build
services:
- docker:18.09.7-dind
variables:
DOCKER_HOST: tcp://docker:2375/
DOCKER_DRIVER: overlay2
tags:
- dind
before_script:
- echo "${GCLOUD_CREDENTIAL64}" | base64 -d | docker login -u _json_key --password-stdin your_region.gcr.io
script:
- docker build -t your_region.gcr.io/your_google_project/project_name .
- docker push your_region.gcr.io/your_google_project/project_name
- docker logout
- docker rmi your_region.gcr.io/your_google_project/project_name
only:
- masterdeploy:project_name-server:
image:
name: your_region.gcr.io/your_google_project/bi-ansible:latest
stage: deploy
script:
- ansible-playbook -v --inventory=$(pwd)/bin/ansible/hosts --private-key=${PATH_CREDENTIAL} $(pwd)/bin/ansible/project_name.playbook.yml
only:
- master
make sure to put any credential in gitlab ci-cd settings. In this case we used 3 credentials (RSA64_GITLAB_RUNNER, PATH_CREDENTIAL, PATH_CREDENTIAL).
in RSA64_GITLAB_RUNNER we put id_rsa private into the dind docker so it would be able to login into our production machine.