How to integrate Python Django with Jenkins and Nexus

How to integrate Python Django with Jenkins and Nexus


Purpose – To setup a django project and integrate it with Jenkins and Nexus for automated build and artificatory deployment to Nexus repository which can be further download and run using the django development server.

Pre-requisite
Python 3.5 and later
Django 2.1 and later
pip 19.x and above
Jenkins
Nexus
twine
JDK 1.8 and later
git
Procedure
Step1 : Validate JDK
[root@centos3 ~]# java -version
openjdk version “1.8.0_181”
OpenJDK Runtime Environment (build 1.8.0_181-b13)
OpenJDK 64-Bit Server VM (build 25.181-b13, mixed mode)
[root@centos3 ~]#
Step2 : Validate GIT
[root@centos3 stack]# yum install git
Loaded plugins: fastestmirror, langpacks
Loading mirror speeds from cached hostfile
Installed:
git.x86_64 0:1.8.3.1-20.el7
Dependency Installed:
perl-Error.noarch 1:0.17020-2.el7 perl-Git.noarch 0:1.8.3.1-20.el7 perl-TermReadKey.x86_64 0:2.30-20.el7
[root@centos3 stack]# git –version
git version 1.8.3.1
Step3 : Clone the GIT repository
[root@centos3 stack]# git clone https://github.com/novicejava1/python.git
Cloning into ‘python’…
remote: Enumerating objects: 141, done.
remote: Counting objects: 100% (141/141), done.
remote: Compressing objects: 100% (108/108), done.
remote: Total 141 (delta 27), reused 138 (delta 24), pack-reused 0
Receiving objects: 100% (141/141), 30.57 KiB | 0 bytes/s, done.
Resolving deltas: 100% (27/27), done.
[root@centos3 stack]#
[root@centos3 polls]# tree .
.
├── admin.py
├── apps.py
├── __init__.py
├── migrations
│   ├── 0001_initial.py
│   ├── __init__.py
│   └── __pycache__
│   ├── 0001_initial.cpython-35.pyc
│   └── __init__.cpython-35.pyc
├── models.py
├── __pycache__
│   ├── admin.cpython-35.pyc
│   ├── apps.cpython-35.pyc
│   ├── __init__.cpython-35.pyc
│   ├── models.cpython-35.pyc
│   ├── urls.cpython-35.pyc
│   └── views.cpython-35.pyc
├── static
│   └── polls
│   ├── images
│   │   └── background.gif
│   └── style.css
├── templates
│   └── polls
│   ├── detail.html
│   ├── index.html
│   └── result.html
├── tests.py
├── urls.py
├── urls.py_without_generic_views
├── views.py
└── views.py_without_generic_views
8 directories, 24 files
[root@centos3 polls]#
Step4 : Upload the django Project source code
user@35dc1b29b52b:/projects$ git add mysite
user@35dc1b29b52b:/projects$ git commit -m “Django Application”
[master 48d27a4] Django Application
48 files changed, 520 insertions(+)
create mode 100644 mysite/db.sqlite3
create mode 100755 mysite/manage.py
create mode 100644 mysite/mysite/__init__.py
create mode 100644 mysite/mysite/__pycache__/__init__.cpython-35.pyc
create mode 100644 mysite/mysite/__pycache__/settings.cpython-35.pyc
create mode 100644 mysite/mysite/__pycache__/urls.cpython-35.pyc
create mode 100644 mysite/mysite/__pycache__/wsgi.cpython-35.pyc
create mode 100644 mysite/mysite/settings.py
create mode 100644 mysite/mysite/urls.py
create mode 100644 mysite/mysite/wsgi.py
create mode 100644 mysite/polls/__init__.py
create mode 100644 mysite/polls/__pycache__/__init__.cpython-35.pyc
create mode 100644 mysite/polls/__pycache__/admin.cpython-35.pyc
create mode 100644 mysite/polls/__pycache__/apps.cpython-35.pyc
create mode 100644 mysite/polls/__pycache__/models.cpython-35.pyc
create mode 100644 mysite/polls/__pycache__/urls.cpython-35.pyc
create mode 100644 mysite/polls/__pycache__/views.cpython-35.pyc
create mode 100644 mysite/polls/admin.py
create mode 100644 mysite/polls/apps.py
create mode 100644 mysite/polls/migrations/0001_initial.py
create mode 100644 mysite/polls/migrations/__init__.py
create mode 100644 mysite/polls/migrations/__pycache__/0001_initial.cpython-35.pyc
create mode 100644 mysite/polls/migrations/__pycache__/__init__.cpython-35.pyc
create mode 100644 mysite/polls/models.py
create mode 100644 mysite/polls/static/polls/images/background.gif
create mode 100644 mysite/polls/static/polls/style.css
create mode 100644 mysite/polls/templates/polls/detail.html
create mode 100644 mysite/polls/templates/polls/index.html
create mode 100644 mysite/polls/templates/polls/result.html
create mode 100644 mysite/polls/tests.py
create mode 100644 mysite/polls/urls.py
create mode 100644 mysite/polls/urls.py_without_generic_views
create mode 100644 mysite/polls/views.py
create mode 100644 mysite/polls/views.py_without_generic_views
create mode 100644 mysite/students/__init__.py
create mode 100644 mysite/students/__pycache__/__init__.cpython-35.pyc
create mode 100644 mysite/students/__pycache__/admin.cpython-35.pyc
create mode 100644 mysite/students/__pycache__/apps.cpython-35.pyc
create mode 100644 mysite/students/__pycache__/models.cpython-35.pyc
create mode 100644 mysite/students/admin.py
create mode 100644 mysite/students/apps.py
create mode 100644 mysite/students/migrations/0001_initial.py
create mode 100644 mysite/students/migrations/__init__.py
create mode 100644 mysite/students/migrations/__pycache__/0001_initial.cpython-35.pyc
create mode 100644 mysite/students/migrations/__pycache__/__init__.cpython-35.pyc
create mode 100644 mysite/students/models.py
create mode 100644 mysite/students/tests.py
create mode 100644 mysite/students/views.py
user@35dc1b29b52b:/projects$
user@35dc1b29b52b:/projects$ git push -u origin master
Username for ‘https://github.com’: xxx
Password for ‘https://novicejava1@github.com’:
Enumerating objects: 61, done.
Counting objects: 100% (61/61), done.
Delta compression using up to 2 threads.
Compressing objects: 100% (56/56), done.
Writing objects: 100% (60/60), 21.23 KiB | 2.65 MiB/s, done.
Total 60 (delta 5), reused 0 (delta 0)
remote: Resolving deltas: 100% (5/5), done.
To https://github.com/novicejava1/python.git
f75e0b5..48d27a4 master -> master
Branch ‘master’ set up to track remote branch ‘master’ from ‘origin’.
user@35dc1b29b52b:/projects$
Step5 : Install and Validate Jenkins
Install and Validate Jenkins
[root@centos3 Downloads]# rpm -ivh jenkins-2.164.1-1.1.noarch.rpm
warning: jenkins-2.164.1-1.1.noarch.rpm: Header V4 DSA/SHA1 Signature, key ID d50582e6: NOKEY
Preparing… ################################# [100%]
Updating / installing…
1:jenkins-2.164.1-1.1 ################################# [100%]
[root@centos3 Downloads]#
Validate the URL
http://localhost:8080
Step6: Install and Setup the nexus python repository
Unzip the tar.gz file and start the nexus using below command
./nexus start
Validate by accessing following url
http://localhost:8081
Create the Python repository as shown below
Update the linux server upload the artifactory to the above repository and creating the following file
[root@centos3 jenkins]# pwd
/var/lib/jenkins
[root@centos3 jenkins]# cat .pypirc
[distutils]
index-servers =
nexus
[nexus]
repository = http://localhost:8081/repository/pypi-hosted/
username = admin
password = admin123
Step7 : Configure and Build the Project using Jenkins
Output from the Jenkins job
Started by user admin
Building in workspace /var/lib/jenkins/workspace/django-polls
No credentials specified
> git rev-parse –is-inside-work-tree # timeout=10
Fetching changes from the remote Git repository
> git config remote.origin.url https://github.com/novicejava1/python.git # timeout=10
Fetching upstream changes from https://github.com/novicejava1/python.git
> git –version # timeout=10
> git fetch –tags –progress https://github.com/novicejava1/python.git +refs/heads/*:refs/remotes/origin/*
> git rev-parse refs/remotes/origin/master^{commit} # timeout=10
> git rev-parse refs/remotes/origin/origin/master^{commit} # timeout=10
Checking out Revision 052803c15e884d0af68d3c15a50f744490209f00 (refs/remotes/origin/master)
> git config core.sparsecheckout # timeout=10
> git checkout -f 052803c15e884d0af68d3c15a50f744490209f00
Commit message: “django polls app files”
> git rev-list –no-walk 052803c15e884d0af68d3c15a50f744490209f00 # timeout=10
[django-polls] $ /bin/sh -xe /tmp/jenkins7909551761134993963.sh
+ cd django-polls
+ python setup.py sdist
running sdist
running egg_info
writing django_polls.egg-info/PKG-INFO
writing top-level names to django_polls.egg-info/top_level.txt
writing dependency_links to django_polls.egg-info/dependency_links.txt
reading manifest file ‘django_polls.egg-info/SOURCES.txt’
reading manifest template ‘MANIFEST.in’
writing manifest file ‘django_polls.egg-info/SOURCES.txt’
running check
creating django-polls-0.1
creating django-polls-0.1/django_polls.egg-info
creating django-polls-0.1/polls
creating django-polls-0.1/polls/migrations
creating django-polls-0.1/polls/static
creating django-polls-0.1/polls/static/polls
creating django-polls-0.1/polls/static/polls/images
creating django-polls-0.1/polls/templates
creating django-polls-0.1/polls/templates/polls
making hard links in django-polls-0.1…
hard linking LICENSE -> django-polls-0.1
hard linking MANIFEST.in -> django-polls-0.1
hard linking README.rst -> django-polls-0.1
hard linking setup.py -> django-polls-0.1
hard linking django_polls.egg-info/PKG-INFO -> django-polls-0.1/django_polls.egg-info
hard linking django_polls.egg-info/SOURCES.txt -> django-polls-0.1/django_polls.egg-info
hard linking django_polls.egg-info/dependency_links.txt -> django-polls-0.1/django_polls.egg-info
hard linking django_polls.egg-info/top_level.txt -> django-polls-0.1/django_polls.egg-info
hard linking polls/__init__.py -> django-polls-0.1/polls
hard linking polls/admin.py -> django-polls-0.1/polls
hard linking polls/apps.py -> django-polls-0.1/polls
hard linking polls/models.py -> django-polls-0.1/polls
hard linking polls/tests.py -> django-polls-0.1/polls
hard linking polls/urls.py -> django-polls-0.1/polls
hard linking polls/views.py -> django-polls-0.1/polls
hard linking polls/migrations/0001_initial.py -> django-polls-0.1/polls/migrations
hard linking polls/migrations/__init__.py -> django-polls-0.1/polls/migrations
hard linking polls/static/polls/style.css -> django-polls-0.1/polls/static/polls
hard linking polls/static/polls/images/background.gif -> django-polls-0.1/polls/static/polls/images
hard linking polls/templates/polls/detail.html -> django-polls-0.1/polls/templates/polls
hard linking polls/templates/polls/index.html -> django-polls-0.1/polls/templates/polls
hard linking polls/templates/polls/result.html -> django-polls-0.1/polls/templates/polls
Writing django-polls-0.1/setup.cfg
Creating tar archive
removing ‘django-polls-0.1’ (and everything under it)
+ twine upload dist/django-polls-0.1.tar.gz -r nexus
Uploading distributions to http://localhost:8081/repository/pypi-hosted/
Uploading django-polls-0.1.tar.gz
0%| | 0.00/8.55k [00:00<?, ?B/s]
100%|██████████| 8.55k/8.55k [00:03<00:00, 2.23kB/s]
Finished: SUCCESS
Step7: Download the Artifactory and install using the PIP command
[root@centos3 tmp]# wget http://localhost:8081/repository/pypi-hosted/django-polls/0.1/django-polls-0.1.tar.gz
–2019-04-07 16:55:08– http://localhost:8081/repository/pypi-hosted/django-polls/0.1/django-polls-0.1.tar.gz
Resolving localhost (localhost)… ::1, 127.0.0.1
Connecting to localhost (localhost)|::1|:8081… failed: Connection refused.
Connecting to localhost (localhost)|127.0.0.1|:8081… connected.
HTTP request sent, awaiting response… 200 OK
Length: 3954 (3.9K) [application/x-gzip]
Saving to: ‘django-polls-0.1.tar.gz’
100%[============================================================================================================>] 3,954 –.-K/s in 0s
2019-04-07 16:55:08 (317 MB/s) – ‘django-polls-0.1.tar.gz’ saved [3954/3954]
[root@centos3 tmp]# pip install django-polls-0.1.tar.gz
[root@centos3 tmp]# ls -ld /usr/lib/python3.6/site-packages/*polls*
drwxr-xr-x. 2 root root 117 Apr 7 17:01 /usr/lib/python3.6/site-packages/django_polls-0.1-py3.6.egg-info
drwxr-xr-x. 6 root root 188 Apr 7 17:01 /usr/lib/python3.6/site-packages/polls
Step8: Validate the Application
[root@centos3 mysite]# python3.6 manage.py runserver 0:8085
Performing system checks…
System check identified no issues (0 silenced).
April 07, 2019 – 17:03:52
Django version 2.1.5, using settings ‘mysite.settings’
Starting development server at http://0:8085/
Quit the server with CONTROL-C.
[07/Apr/2019 17:04:16] “GET /polls/ HTTP/1.1” 200 414
[07/Apr/2019 17:04:17] “GET /static/polls/style.css HTTP/1.1” 200 101
[07/Apr/2019 17:04:17] “GET /static/polls/images/background.gif HTTP/1.1” 200 0
Not Found: /favicon.ico
[07/Apr/2019 17:04:17] “GET /favicon.ico HTTP/1.1” 404 2078
[07/Apr/2019 17:04:53] “GET /polls/1/ HTTP/1.1” 200 578
[07/Apr/2019 17:05:24] “POST /polls/1/vote/ HTTP/1.1” 302 0
[07/Apr/2019 17:05:24] “GET /polls/1/result/ HTTP/1.1” 200 176
Follow the steps in the README file for that particular application to be included in the Django Project on specific server

Hope you enjoyed reading this article. Thank you.