Golang: Database migration to manage your database schema by creating incremental SQL

In this post I write down my experience regarding  database migration configuration for Golang using Goose database migration.

Goose installation

$ go get -u github.com/pressly/goose/cmd/goose

This will install the goose binary to your $GOPATH/bin directory.

Goose binary installed in bin folder

How to use

$ goose

Goose executable in action

Create a SQL migration using Goose

$ postgres=# CREATE DATABASE teahrm

Golang SQL migration using Goose
Just generated empty Migration

Create target database to migrate with

$ goose create create_tables_users sql

List of existing databases

Connect to the PostgresSQL database thru psql

$ postgres=# \connect teahrm

Show tables

$ teahrm=# \dt

Empty database without table yet

Create migration for table users (PostgreSQL datatype)

Migrate Up

goose postgres "user=postgres dbname=teahrm sslmode=disable" up


Migrate Down

goose postgres "user=postgres dbname=teahrm sslmode=disable" down


Common mistake while migrating up

Missing connection information

Wrong database name: goose: no migrations to run. current version: 1

Check Connection status to avoid connection error

goose postgres "user=postgres dbname=postgres sslmode=disable" status


That’s all guys… have a nice weekend…






Golang: Web development using Gorilla Mux and Pongo2 templating engine

What is Golang Gorilla ?

Gorilla is a web toolkit for the Go programming language.

What is Gorilla mux?

The name mux stands for “HTTP request multiplexer”. Like the standard http.ServeMux, mux.Router matches incoming requests against a list of registered routes and calls a handler for the route that matches the URL or other conditions.

What is HTTP Multiplexer / Mux?

ListenAndServe starts an HTTP server with a given address and handler. The handler is usually nil, which means to use DefaultServeMux. Handle and HandleFunc add handlers to DefaultServeMux

What is Pongo2 ?

pongo2 is the successor of pongo, a Django-syntax like templating-language.

pongo is a well-tested template engine which implements a Django-template-like syntax.

Install Gorilla Mux and Pongo

go get github.com/gorilla/mux
go get -u github.com/flosch/pongo2

Create app.yml

  runtime: go
  api_version: go1 

  - url: /.*
    script: _go_app
    secure: always
    redirect_http_response_code: 301 

create main.go

 package main

  import (

      pongo "github.com/flosch/pongo2"

  func init() {
      r := mux.NewRouter()

      r.HandleFunc("/", homeHandler)  

      http.Handle("/", r)

  func homeHandler(w http.ResponseWriter, r *http.Request) {
      template := "dashboard.html"
      tmpl := pongo.Must(pongo.FromFile(template))

      err := tmpl.ExecuteWriter(pongo.Context{"title": "Index", "greating": "Hallo"}, w)
      if err != nil {
          http.Error(w, err.Error(), http.StatusInternalServerError)

create base.html

              {% block title %}Website Title Default{% endblock %}
          {% block body %}Body Default{% endblock %}

create dashboard.html

  {% extends "base.html" %}

  {% block title  %}Dashboard Real Title{% endblock %}

  {% block body %}Hallo world Gorilla!{% endblock %}

Running the code on the local server

dev_appserver.py --port=9999 ./




Note: I am using App Engine local environment development

Golang Web: Setting Up GIN Framework with Pongo2 template engine on GAE Standard env

What Is Gin

Gin is a web framework written in Golang. It features a martini-like API with much better performance, up to 40 times faster. If you need performance and good productivity, you will love Gin.

What Is Pongo

Pongo is a well-tested template engine which implements a Django template like syntax and pongo2 is the successor of pongo, a Django-syntax like templating-language.

For Pongo documentation on how the templating language works you can head over to the Django documentation. pongo2 aims to be compatible with it (link).

Ok then. let’s start the journey

Installing GIN

go get github.com/gin-gonic/gin

go get github.com/gin-gonic/gin

Installing Pongo2

go get -u github.com/flosch/pongo2 go get -u github.com/flosch/pongo2

Install robvdl/pongo2gin

Package pongo2gin is a template renderer that can be used with the Gin web framework gin-gonic/gin it uses the Pongo2 template library flosch/pongo2 to use pongo2gin you need to set your router.HTMLRenderer to a new renderer instance, this is done after creating the Gin router when the Gin application starts up. You can use pongo2gin.Default() to create a new renderer with default options, this assumes templates will be located in the “templates” directory, or you can use pongo2.New() to specify a custom location.To render templates from a route, call c.HTML just as you would with regular Gin templates, the only difference is that you pass template data as a pongo2.Context instead of gin.H type.

Create app.yml

  runtime: go
  api_version: go1 
  - url: /.* 
    script: _go_app
    secure: always
    redirect_http_response_code: 301 

Create main.go

 package main

  import (


  func init() {
      r := gin.Default()

      r.HTMLRender = pongo2gin.Default()


      r.GET("/", func(c *gin.Context) {
          c.HTML(http.StatusOK, "main.html", pongo2.Context{
              "title":    "Hello world !",
              "greating": "Hi, Hello world my mate!",

      http.Handle("/", r)

Create templates/main.html

              {{ .title }}
          {{ .greating }}

Run App engine development server

dev_appserver.py –port=9999 ./The result

Deployment to GAE using gcloud command

gcloud app deploy –verbosity=info

The Final Result On Browser


Resources: link1

Golang Common Error: missing ‘,’ before newline in composite literal

This is my previous (error) code:

r.GET("/", func(c *gin.Context) {
          c.HTML(http.StatusOK, "main.html", pongo2.Context{
              "title":    "Hello world !",
              "greating": "Hi, Hello world my mate!"

And here is the changes:

r.GET("/", func(c *gin.Context) {
          c.HTML(http.StatusOK, "main.html", pongo2.Context{
              "title":    "Hello world !",
              "greating": "Hi, Hello world my mate!",

can you find the different ? no ? here is the mitsake:

“greating”: “Hi, Hello world my mate!”,

Yeah the error is because of missing a comma LOL

Using Git Rebase to Squash Commits

A Git command that can be very useful, yet is often overlooked by beginners (such as myself) is the rebase command. I admit to not fully understanding all of its uses, but there is one simple use for it that I have found myself taking advantage of lately. Here’s the scenario:

You have a remote Git repository, perhaps hosted at GitHub. You want to work on a new feature, so you create a local branch on your machine:

git checkout -b newBranch

You make some changes and commit them to the local branch:

git commit -a -m”My first set of changes”

You make some more changes and commit them to the local branch:

git commit -a -m”My second set of changes”

You make some more changes and commit them to the local branch:

git commit -a -m”My third set of changes”
You now have three separate commits that relate to one feature, and the feature is complete. You could simply push the changes to your remote, but then you’d end up with three commits on the remote that are not particularly meaningful. The only reason you have three commits in your local repo is that you completed the work in three steps. Perhaps you’d rather have just one commit reported in the remote repo for this feature. Thankfully git rebase allows you to do that very simply.
If you issue a git log command, you’ll see something similar to this:


I can see from this that I have three commits corresponding to the changes that I made for the feature. To squash these three commits into one, and specify a commit message for the group, I can use git rebase, with the -i (which stands for interactive), argument:

git rebase -i HEAD~3

The HEAD~3 tells git that I want to rebase the past three commits.

This will pop open my text editor, which I have configured to be TextMate, with some rebasing instructions. The file will look something like this:


This is quite convenient as git actually provides you with some instructions. I want to combine the second and third commit with the first, so I edit the file to look like this:


When I save and close the file, git will pop open another file in the editor to edit our commit message:


From here I can either choose to accept the three individual commit messages that were picked up from our three commits, or I can remove them (or comment them out) and provide our own commit message. I’m going to remove the original commit messages and replace them with a single one that reads “A bunch of changes to support new feature A”. When I save and close this file I’ll be back at the command line with a message similar to this:


Now when I issue the git log command again, I’ll see my previous three commits squashed into one:


It’s as simple as that. Now you do need to be careful using the rebase command with remotes when you are collaborating with others. You should avoid rebasing commits that have already been pushed to a remote. There is also a lot more to rebasing than this simple example, but it’s not a bad place to start. Happy rebasing!


Source: link  (link dead)

  • Squash commits to one commit
  • Combine commits to one commit
  • Merge git commits to one commit

Let’s Encrypt on Google App Engine

Let’s Encrypt is free automated, and open certificate authority brought to you by the non-profit Internet Security Research Group (ISRG). it is a pretty awesome initiative to provide free SSL certificates to make creating a secure website easier.


Let’s Encrypt is a free, automated, and open Certificate Authority.

Here’s how to use it with App Engine. I used Google Cloud Shell to run these commands.

1.Download letsecrypt script  client using git clone:

git clone https://github.com/letsencrypt/letsencrypt
cd letsencrypt

so you will have folder containing files like this:


2.Generate certificate using letsencrypt:

sudo ./letsencrypt-auto -a manual certonly

3.Challenge and response verification the ownership of your domain.

You’ll see something like this on your console terminal:

mhyusufibrahim@myproject-999999:~/letsencrypt$ sudo ./letsencrypt-auto -a manual certonlySaving debug log to /var/log/letsencrypt/letsencrypt.log

Please enter in your domain name(s) (comma and/or space separated) (Enter ‘c’ to cancel): http://www.mydomain.com

Obtaining a new certificate Performing the following challenges: http-01 challenge for  http://www.mydomain.com


NOTE: The IP of this machine will be publicly logged as having requested this certificate. If you’re running certbot in manual mode on a machine that is not your server, please ensure you’re okay with that. Are you OK with your IP being logged?

(Y)es/(N)o: Y

Make sure your web server displays the following content at


before continuing:


If you don’t have HTTP server configured, you can run the following command on the target server (as root): mkdir -p /tmp/certbot/public_html/.well-known/acme-challenge cd /tmp/certbot/public_html printf “%s” nuHnBaCxYzkvcUQkOEjLhpYgY_umLjdCr4gRkby1YCM.qvOvSw_BDrdsxvw_X_ce5IgulKkYBS4BMWrUiaqY4iY > .well-known/acme-challenge/nuHnBaCxYzkvcUQkOEjLhpYgY_umLjdCr4gRkby1YCM # run only once per server: $(command -v python2 || command -v python2.7 || command -v python2.6) -c \ “import BaseHTTPServer, SimpleHTTPServer; \ s = BaseHTTPServer.HTTPServer((”, 80), SimpleHTTPServer.SimpleHTTPRequestHandler); \ s.serve_forever()” ——————————————————————————-

Press Enter to – NOTE: The IP of this machine will be publicly logged as having requested this certificate. If you’re running certbot in manual mode on a machine that is not your server, please ensure you’re okay with that. Are you OK with your IP being logged?

(Y)es/(N)o: y

Press Enter to Continue

Waiting for verification…Cleaning up challenges

IMPORTANT NOTES: – Congratulations! Your certificate and chain have been saved at /etc/letsencrypt/live/http://www.mydomain.com/fullchain.pem. Your cert will expire on 2017-09-26. To obtain a new or tweaked version of this certificate in the future, simply run letsencrypt-auto again. To non-interactively renew *all* of your certificates, run “letsencrypt-auto renew” – If you like Certbot, please consider supporting our work by: Donating to ISRG / Let’s Encrypt: https://letsencrypt.org/donate Donating to EFF: https://eff.org/donate-le

3.Get your private key.

sudo openssl rsa -inform pem -in /etc/letsencrypt/live/www.mydomain.com/privkey.pem -outform pem | less


4.Get your public key certificate.

sudo less /etc/letsencrypt/live/http://www.mydomain.com/fullchain.pem

Don’t forget to press enter to scroll down the text


Keep in mind that /etc/letsencrypt is not persisted through Cloud Shell restarts, so if you need to keep your private key, you can copy it to your home directory or save it.

5.Upload the certificate to the Google Cloud.

App Engine -> Settings -> SSL Certificate




The final result


Installing and Unistalling SpaceVim / SpaceVim on UBuntu Linux (Or just Linux in General)

I just Installed /SpaceVim on my Ubuntu 14.04 Laptop but I realized that It was wrong because my VIM IDE turned to unfamiliar IDE for me, and the worse case was my previous setting and configurations in my .vimrc are no longer working.

Here is the SpaceVim installation step:

curl -sLf https://spacevim.org/install.sh | bash


Installation result (Open the VIM first), beautiful but I think it’s better to use it later…


And here is how to uninstall / remove  SpaceVim from your LInux Computer:

curl -sLf https://spacevim.org/install.sh | bash -s — uninstall


Finally I get my standard VIM back…


Laravel PHPUnit: Check form submit redirection

I just made a Laravel  UnitTest to test and make sure that my create function is working and redirects user to the right url after form post submitted , this is how I make it work:

public function testSurveysCreateSuccess()
        $form = [
            'name' => 'New Survey',
            'type' => 'Lecturer',
            'description' => 'It\'s a text'

        $url =  '/admin/courses/'.$this->course->id.'/surveys';

        $response = $this->actingAs($this->user)->call('POST', $url, $form);
        $this->assertEquals(302, $response->status());
        $redirect_to = $response->getTargetUrl();

        $this->assertEquals($redirect_to, $this->baseUrl.$url);