Category Archives: DevOps

Containerize Spring Boot App with Docker

  • Add docker maven plugin to pom.xml
  • Create Dockerfile at the root of the project
FROM openjdk:8-jdk-alpine
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","","-jar","/app.jar"]
  • Build docker image

mvn clean install dockerfile:build

  • Login to docker hub and push the image to docker hub (Optional Step)

docker login -u <username>
mvn dockerfile:push

  • Verify the image is built and available

docker images

  • Run Spring Boot App from docker

docker run –rm -d –restart -p 8080:8080 ${docker.image.prefix}/${project.artifactId}

Deploy Flask Application to Apache Webserver

  • Install mod_wsgi

sudo apt-get install libapache2-mod-wsgi

  • Enable wsgi module

sudo a2enmod wsgi

sudo systemctl restart apache2

  • Create .wsgi file with below content

from yourapp import app as application

  • Configure a new site in Apache2
    ServerName site.api

    WSGIDaemonProcess site user=www-data group=www-data threads=5 home=/var/www/site
    WSGIScriptAlias / /var/www/site/app.wsgi

    <Directory /var/www/site>
        WSGIProcessGroup site
        WSGIApplicationGroup %{GLOBAL}
        Order deny,allow
        Allow from all

    WSGIPassAuthorization On

  • Enable the site and reload Apache2

Nginx configuration for Gunicorn

user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log;
pid /run/;

# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
	accept_mutex off; # set to 'on' if nginx worker_processes > 1

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See
    # for more information.
    include /etc/nginx/conf.d/*.conf;
	upstream app_server {
		# fail_timeout=0 means we always retry an upstream even if it failed
		# to return a good HTTP response

		# for UNIX domain socket setups
		#server unix:/tmp/gunicorn.sock fail_timeout=0;

		# for a TCP configuration
		server fail_timeout=0;

    server {
        listen       *:80;
		client_max_body_size 4G;
        #server_name  localhost;
        root         /usr/share/nginx/html;
		keepalive_timeout 5;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
		try_files $uri @proxy_to_app;
		location @proxy_to_app {
		  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		  # enable this if and only if you use HTTPS
		  # proxy_set_header X-Forwarded-Proto https;
		  proxy_set_header Host $http_host;
		  # we don't want nginx trying to do something clever with
		  # redirects, we set the Host: header above already.
		  proxy_redirect off;
		  proxy_pass http://app_server;

        error_page 404 /404.html;
            location = /40x.html {

        error_page 500 502 503 504 /50x.html;
            location = /50x.html {