CI/CD For Python Code Using Azure, Jenkins, Nginx, and GitHub: Part One

Photo by Alex Nirta from Burst

As the first post in the “CI/CD For Python Code Using Azure, Jenkins, Nginx, and GitHub” series, I will introduce how to set a Jenkins server up behind an Nginx reverse proxy server on Azure by creating a Linux virtual machine on Azure and configuring Azure NSG(network security group). Of course, I know that Microsoft provides Jenkins template in the Azure marketplace, but personally I prefer to build Jenkins service by myself.

a user review I found on the template page

Create A Linux Virtual Machine

So the first thing is that you should have an Azure subscription if you don’t then you can create your Azure free account at

Now login to your Azure portal page and create a Resource Group.

Resource groups are a fundamental element of the Azure platform. A resource group is a logical container for resources deployed on Azure. In other words, the Linux virtual machine we’ll create on the Azure platform will be in a resource group. Therefore, we create a resource group first.

One thing to note is that resources from multiple different locations can be placed in a resource group and the location of the resource group can be different from the resources in it, too. This because the resource group only contains metadata about the resources it contains and when we specify a location for the resource group, we specify where the metadata is stored.

And the name of the resource group should meaningful, such as ‘rg-devops-001’. You can find many examples of the naming convention of Azure resources at here:

Next, let’s create a virtual machine. As you can see in the below image, we select the resource group we created, name the virtual machine ‘vm-jenkins-asse-001’ (format: resource type---<###>) and select the Ubuntu Server 18.04 LTS Image.

If you want to view all the options of VM Size, you can click the Select size link below the size you selected.

Then, we will use the SSH public key as the Authentication type.

The SSH public key comes from 3 sources, If you don’t have an existing public key you should ‘Generate new key pair’. Then once you create the virtual machine, Azure will generate the key pair and provide you the private key, you can store it on your computer. And as you can see above, port 22 will be used for SSH.

Now I have the private key generated by Azure and store it at Desktop/azure_ssh_key folder. Then I will use ssh to connect to the remote virtual machine from my Mac OS laptop.

ssh -i ./vm-jenkins-asse-001\_key.pem chenjd@

You should use the -i option to identify the private key, but you may encounter an error, as shown below:

This is because the default permission for the private key is too open, 0644 means the Owner has the right to read and write to the private key file. Therefore, we should set the owner’s permission to the private key file to read-only.

chmod 400 ./vm-jenkins-asse-001\_key.pem

By the way, there is an online tool that can help you calculate the right code to set the permission you want.

Now we can connect to the virtual machine.

Set A Jenkins Server Up Behind An Nginx Reverse Proxy Server

Next, we will install Nginx & Jenkins and set the Jenkins server up behind the Nginx reverse proxy server.

Let’s install Nginx first. Because this is our first interaction with the apt packaging tool, therefore we should update our local package index so that we can access the most recent packages list.

sudo apt update

Then install the Nginx server.

sudo apt install nginx

Now the Nginx server should run automatically. You can use the systemctl command to print out the status of the Nginx service instance.

sudo systemctl status nginx

As a result, you should find something similar to the image below.

The Nginx server will listen to the port 80, but if you try to visit the server via IP address in your browser, you will find your browser cannot access the page. Do you still remember we only open the port 22 for SSH when we created the virtual machine on Azure?

Yes, we need to open port 80 too. Ok, let’s open the Networking panel of your virtual machine and you can find the default rules defined in the Azure Network Security Group. A network security group works as a firewall and you can filter network traffic to and from Azure resources with it.

We add a new inbound port rule to allow the port 80 and you can find the new rule named Port_80 in the image below.

This time, we can access the Nginx default page via IP address in our browser, cool!

Next, let’s install the Jenkins server. Since Jenkins is an open-source automation server written in Java programming language, therefore we should install JDK first.

sudo apt install openjdk-8-jdk

Then install Jenkins.

wget -q -O - | sudo apt-key add -  
sudo sh -c 'echo deb binary/ > \\  
sudo apt update  
sudo apt install jenkins

Now the Jenkins server should run automatically, too. You can use the systemctl command to print out the status of the Jenkins service instance.

However, the Jenkins server listens to port 8080 and we did not allow the network traffic to this port. This time, we will not add a new inbound rule to our Azure network security group but we will use the Nginx server as a reverse proxy server to direct traffic sent to port 80 to port 8080.

For the sake of directing traffic sent to port 80 to port 8080 with Nginx, we should modify the Nginx’s config file. You can find it at /etc/nginx/sites-enabled/default and add the proxy_pass to the config file with Vim.

sudo vim /etc/nginx/sites-enabled/default

As you can see above, to route /, we added the ‘proxy_pass’ at the location / section.

 users --> nginx --- host ---> jenkins on localhost:8080 

Cool. Now let’s reload the Nginx configuration.

sudo nginx -s reload

Refresh the Nginx default page in our browser and you should find the Nginx default page is replaced by the Jenkins page. YEAH!

Finally, you can follow the instructions to copy and paste the initial administrator password. Then Jenkins should install the recommended plugins and our Jenkins server is ready to serve.


In this post, we talked about how to set a Jenkins server up behind an Nginx reverse proxy server on Azure by creating a Linux virtual machine on Azure and configuring Azure NSG(network security group). It’s a very interesting progress.

In the next post, I’ll introduce how to implement CI/CD for Python Code using the Jenkins server we set up in this post.

Thanks for reading and I hope it’s useful!

Subscribe To Jiadong Chen's Blog

Jiadong Chen
Senior Software Developer

HusbandㅣProgrammerㅣAuthorㅣBloggerㅣSpeakerㅣMicrosoft @MVPAward In Developer TechnologiesㅣPreviously @Unity3d ㅣOpinions = my own.

comments powered by Disqus