27 Jan

Adding SSL with Let’s Encrypt and NGINX

Editor – This is an update to a previous blog post about using Let’s Encrypt certificates with NGINX. This new blog is based on newly added NGINX support in certbot.

The Certbot client supports two types of plugins for obtaining and installing certificates: authenticators and installers.

Authenticators validates that you control the domain(s) you are requesting a certificate for, obtains a certificate for the specified domain(s), and places the certificate in the /etc/letsencrypt directory on your machine. The authenticator does not install the certificate (it does not edit any of your server’s configuration files to serve the obtained certificate).

Installers are Plugins used with the install command to install a certificate. These plugins can modify your webserver’s configuration to serve your website over HTTPS using certificates obtained by certbot.

Let’s Encrypt client provides 3 plugins for different web servers.

apache – Automates obtaining and installing a certificate with Apache 2.4 on Debian-based distributions with libaugeas0 1.0+.
webroot – Obtains a certificate by writing to the webroot directory of an already running webserver.
nginx – Automates obtaining and installing a certificate with Nginx.
standalone – Uses a “standalone” webserver to obtain a certificate. This is useful on systems with no webserver, or when direct integration with the local webserver is not supported or not desired. Requires port 80 or 443 to be available.
manual – Helps you obtain a certificate by giving you instructions to perform domain validation yourself. Additionally allows you to specify scripts to automate the validation task in a customized way.

We will be using the webroot plugin for this guide

1. Add the certbot repository:

$ sudo add-apt-repository ppa:certbot/certbot

Now install certbot:

$ sudo apt-get update
$ sudo apt-get install python-certbot-nginx

2. Set up NGINX
Add the webroot on the nginx server block

$ sudo vi /etc/nginx/sites-available/example.com
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name example.com www.example.com;

#LetsEncrypt webroot
location ~ /.well-known {
allow all;
root /home/www/example;
$ sudo nginx -t
$ sudo service nginx restart
3. Obtain the SSL certificate
$ sudo certbot certonly --webroot -w /home/www/example/ -d example.com -d www.example.com

4. Update NGINX
$ sudo vi /etc/nginx/sites-available/example.com

Check if the settings are updated by the

server {
listen 80;
server_name example.com www.example.com;

# Redirect non-https traffic to https
location / { return 301 https://$host$request_uri; }
server {
listen 443 ssl;
server_name example.com www.example.com;

# RSA certificate
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot

include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
$ sudo nginx -t
$ sudo service nginx restart

To obtain a new certificate that contains additional domains without replacing your existing certificate you must use the –duplicate option.

For example:
$ /usr/bin/certbot --duplicate certonly --webroot -w /home/www/example/ -d example.com -d www.example.com -d sub.example.com


$ sudo certbot --nginx -d conva.net -d home/www/example/ -d example.com -d www.example.com -d sub.example.com

5. Add R
sudo crontab -e

Add line on crontab
12 3 * * * letsencrypt renew >> /var/log/letsencrypt/renew.log

25 Feb

Migrating from Python 2.7 to Python 3.4

Last year, we made a decision to migrate to python 3.4 in 2016. This was not an easy decision as all our code base in developed using python 2.7 and it has served us very well.

Yesterday, We took the big step. This has already been delayed and was overdue.

First the Python 3.4 has to be installed, using the same process as in previous blog. However, replacing 2.7 with 3.4

the virtualenv has to be recreated for python 3.4.

pyvenv <virtual env>

thunder lock: disabled (you can enable it with --thunder-lock)
 uwsgi socket 0 bound to UNIX address xhod.sock fd 3
 Python version: 2.7.10 (default, Sep 21 2015, 12:21:01) [GCC 4.4.7 20120313 (Red Hat 4.4.7-16)]
 Set PythonHome to /home/uobis/webapps/xhod/venv
 ImportError: No module named site

I had to recompile uwsgi for python 3.4

/usr/local/bin/pip2.7 uninstall uWSGI

/usr/local/bin/pip3.4 install uWSGI

*** Starting uWSGI 2.0.12 (64bit) on [Thu Feb 25 22:31:10 2016] ***
compiled with version: 4.4.7 20120313 (Red Hat 4.4.7-16) on 25 February 2016 22:30:37
os: Linux-2.6.32-042stab108.8 #1 SMP Wed Jul 22 17:23:23 MSK 2015


27 May

NGINX server blocks in Centos 6

How to setup NGINX server blocks (aka VirualHosts) on Centos
Step One — Set Up New Document Root Directories
sudo mkdir -p /var/www/example.com/html
sudo mkdir -p /var/www/test.com/html

sudo chown -R $USER:$USER /var/www/example.com/html

Step Two — Create Sample Pages for Each Site
Step Three — Create Server Block Files for Each Domain
The sites-available directory will keep all of our server block files, while the sites-enabled directory will hold symbolic links to server blocks that we want to publish.

sudo mkdir /etc/nginx/sites-available
sudo mkdir /etc/nginx/sites-enabled

sudo vi /etc/nginx/nginx.conf

Add these lines to the end of the http {} block:

include /etc/nginx/sites-enabled/*.conf;
server_names_hash_bucket_size 64;

Create the First Server Block File

sudo cp /etc/nginx/conf.d/default.conf /etc/nginx/sites-available/example.com.conf

sudo nano /etc/nginx/sites-available/example.com.conf

server {
listen 80
server_name example.com www.example.com;
location / {
root /var/www/example.com/html;
index index.html index.htm;
try_files $uri $uri/ =404;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;

Create the Second Server Block File

sudo cp /etc/nginx/conf.d/default.conf /etc/nginx/sites-available/example2.com.conf

Step Four — Enable the New Server Block Files

sudo ln -s /etc/nginx/sites-available/kabbu.ng.conf /etc/nginx/sites-enabled/kabbu.ng.conf
sudo ln -s /etc/nginx/sites-available/umscholar.org.conf /etc/nginx/sites-enabled/umscholar.org.conf

Restart NGINX
/etc/init.d/nginx restart

02 Nov

Git adventures

I wanted to clean up some Bootstrap files from a project directory. After the cleanup. I pushed the changes to the remote repo (BitBucket).
However, I noticed that the files that should be deleted (and was deleted on local repo), was still existing on the remote repo.
After some head scratching, i released that the problem was that I used the file system delete, instead of the git delete.

$ git rm 
$ git add .
$ git commit -m "changes"
$ git push

Everything was fine now and good, until I come back to see that i deleted an important directory due to a misuse of the “*” during the delete.
Well, that what and DSCM was meant for.. Git come to the rescue…. except that it took me 30mins or trying different command ( and help from Stackoverflow) to find the right combo, thus:

cf361cb is the last commit with the missing directory

$ git revert --no-commit cf361cb..HEAD
$ git commit

This is a safe and easy way to rollback to a previous state. Checks for the missing directory

$ ls -ltr
$ cd static/

Cleanup files

$ git rm *.css
$ git rm *.js

Then commit and push

$ git add .
$ git status
$ 1398 git commit -m "UI file cleanup"
$ git push

And Wossah!!
The git throws up a new error, “fatal: You are not currently on a branch”
I checked on the git

$ git status

And trully, you are not a branch!
I was getting loosing the modification twice after using 2 different command, until i hit on the right combo (also good help from stackoverflow)

$ git checkout -b newbranch
$ git checkout master
$ git merge newbranch
$ git branch -d newbranch
$ git status
$ git push


02 Oct

python+virtualenv on Cygwin

I have been trying to make my default environment for development to be

  1. Install Python.
  2. Download and unzip pip.
  3. Install by going into the expanded directory and running python setup.py in a command prompt.
  4. Set the %PYTHONHOME% system variable to the python base directory, (i.e. C:\Python27\) and adding the python base directory and script directory (i.e. C:\Python27\Scripts) to your %PATH% system variable.
  5. Install Cygwin WITHOUT Python. The previous step tells Cygwin to use the Windows binary.
  6. Install Cygwin-Virtualenvwrapper using pip install https://bitbucket.org/cliffxuan/virtualenvwrapper-for-cygwin-windows-python/get/tip.tar.gz
  7. Install virtualenvwrapper-win using pip install virtualenvwrapper-win
  8. Make a symlink between Cygwin’s virtualenvhome directory and Windows’s using ln -s /cygdrive/c/Users/<USER>/Envs/ ~/.virtualenvs
  9. Add the following to Cygwin’s .bashrc file:
      export VIRTUALENVWRAPPER_PYTHON=”/cygdrive/c/Python27/python.exe”
      export VIRTUALENVWRAPPER_VIRTUALENV=”/cygdrive/c/Python27/Scripts/virtualenv.exe”
      source virtualenvwrapper.sh
  10. Go to C:\User\<username>\Env (or other %VIRTUALENV_HOME% location) and use virtualenv to start a new environment. Doing this allows virtualenvwrapper-win‘s workon command to work.