Letsencrypt – HTTPS is the better way

Letsencrypt is free SSL Certificate Authority (CA). Provides you renewable free of charge secure connection to your resources from the internet. (https://letsencrypt.org/) Here i am going to explain how to secure web app (in my case its Jenkins run on port 8080) using Letsencrypt and NginX.

First you have to have your app running on a cloud environment like Azure or AWS. Make sure you get a domain name for your VM instance (Ex: blog.southeastasia.cloudapp.azure.com). You need a proper domain name configured with your cloud instance otherwise Letsencrypt reject your certificate request.

Things to per-configure in your cloud before begin

  1. Open both 80 and 443 to public
  2. Make sure you have a domain name for your resource

In my case, I have Jenkins up and running in a docker container with internal port 8080 and external port 8081, I have added my Jenkins to a external network called ‘nginx-network’

version: '3.7'

services:

  jenkins:
    image: jenkins/jenkins:latest
    container_name: jenkins
    user: root
    environment:
     - JENKINS_ARGS="--prefix=/jenkins"
    volumes:
     - ./jenkins_home:/var/jenkins_home
     - /var/run/docker.sock:/var/run/docker.sock
     - /usr/bin/docker:/usr/bin/docker
     - /usr/local/bin/docker-compose:/usr/local/bin/docker-compose
    ports:
     - 8081:8080
     - 50000:50000
    networks:
     - nginx-network

networks:
  nginx-network:
    external: true

Configuring NginX with Letsencrypt + Certbot

Download Letsencrypt automated script from here

https://raw.githubusercontent.com/wmnnd/nginx-certbot/master/init-letsencrypt.sh

Replace the domain name to yours

Put ‘init-letsencrypt.sh’ in the same folder where your ‘docker-compose.yml’ exists. The docker-compose for spin up Nginx and get certificates from Letsencript using Certbot as follows.

version: '3.7'

services:

  nginx:
    image: nginx:1.17.6-alpine
    container_name: nginx
    volumes:
     - ./nginx_data:/etc/nginx/conf.d
     - ./certbot_data/conf:/etc/letsencrypt
     - ./certbot_data/www:/var/www/certbot
    ports:
     - 80:80
     - 443:443
    networks:
     - nginx-network

  certbot:
    image: certbot/certbot
    volumes:
     - ./certbot_data/conf:/etc/letsencrypt
     - ./certbot_data/www:/var/www/certbot
    networks:
     - nginx-network

networks:
  nginx-network:
    external: true

Create all empty directories and put your ‘app.conf’ file inside ‘nginx_data’ directory.

upstream jk {
    server jenkins:8080;
    keepalive 256;
}

server {

        listen 80 default_server;
        listen [::]:80 default_server;

        server_name xxx.southeastasia.cloudapp.azure.com;

        location /.well-known/acme-challenge/{
                root /var/www/certbot;
        }
        location / {
                return 301 https://$host$request_uri;
        }
}

server {
        listen 443 ssl;
        server_name xxx.southeastasia.cloudapp.azure.com;

        ssl_certificate /etc/letsencrypt/live/xxx.xx.cloudapp.azure.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/xxx.xx.cloudapp.azure.com/privkey.pem;
        include /etc/letsencrypt/options-ssl-nginx.conf;
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

        location / {

                proxy_set_header        Host $host:$server_port;
                proxy_set_header        X-Real-IP $remote_addr;
                proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header        X-Forwarded-Proto $scheme;
                proxy_redirect http:// https://;
                proxy_pass http://jk;

                proxy_http_version 1.1;
                proxy_request_buffering off;
                proxy_buffering off;
        }
}

Now the configurations are done. Lets get the certificates now.

Execute ‘init-letsencrypt.sh’ file and see the magic !

Then visit to your web app in the cloud. You can see now your free SSL certificate is issued from Letsencrypt is in action.

Website SSL
Certificate Details

Lets Encrypt , Coz Self Signed is for Kids 🙂 …..

SpringBoot CI/CD with Azure Container Registry and Jenkins (Part 1)

Create Git Clone, ACR Push/Pull, Docker Run Pipeline Stages

Jenkins is the mostly and widely used pipelining tool for continuous deployments. Here I am planing to explain you that how to push an SpringBoot application build image to Azure Container registry and reused it inside your docker-compose file while you run your deployment. There are some basic steps to complete before the Jenkins pipeline part.

  1. From your Azure Console, create container registry and get your login password from Settings -> Access keys (We are going to create Jenkins credential id using this)
  2. You have a SpringBoot app with Dockerfile, docker-compose file and Jenkins file located in same directory structure
SpringBoot Application Directory Structure
Azure Container Registry

Here is the sample content of above files

Dockerfile
docker-compose file
Jenkinsfile

In your Jenkins, if you are using Jenkins docker image you have to have below configurations

First execute below in your Jenkins host machine

sudo adduser jenkins
sudo usermod -a -G docker jenkins

Here I map docker and docker-compose executable files from host machine to Jenkins docker container, so Jenkins can execute docker commands.

Jenkins docker-compose file

Jenkins – Create pipeline using existing Jenkinsfile

Log into your Jenkins and Select “New Item” -> Pipeline , put a suitable name for your build

You can add triggers later, for now , go to “Pipeline Section” and select “pipeline script from SCM”

Put your Git repo, if your repo is a private one add credentials by clicking Add button

Mention your branch, if you are using different branch than master, put that name

Script path is “Jenkinsfile”, its relative url to your project

Adding Azure Container registry credentials to Jenkins

Go to Credentials -> System -> Global credentials (unrestricted) -> Add Credentials

Username/password Entry

In your Pipeline script , put the same credential ID as above

Now you can execute “Build Now” command

Build Now

Summery of the flow (pipeline)

  1. Compile your java code using maven
  2. Package it to jar
  3. Optimize and jar (break fat jar)
  4. Build docker image
  5. Push the image to ACR with tag
  6. Pull back the image
  7. Remove all previous docker containers
  8. Spin up all the containers (including dependencies) using docker-compose

You can check the containers after the deployment

Running Containers

Source-code

https://github.com/dumindarw/reactive-eventservice

To be continued ….