Monday, September 5, 2016

Setup secure Docker Registry with Nginx and SSL


  1. Docker v1.12 installed. (though you could try it with lower version)
  2. Docker Compose v1.6 installed.
  3. apache2-utils are installed.
  4. Ubuntu (but it very similar for other distro).
  5. A domain name to run the docker registry. (a subdomain would work too).
  6. SSL certificate for the domain to run the docker registry on.

Step 1: create docker-compose.yml

Create a directory registry and under it create a docker-compose.yml.

This docker-compose file create a registry container using the registry:2 image and also a front-end proxy using the nginx:1.10.1 image.

The registry container is configured to expose it's port 5000 to other container that links to it (in this case, the proxy container can access the registry via that port)

The proxy container is configured to listen to port 80 and 443 on the host. Other nginx configuration are stores under the conf.d directory that are mapped as volume.

REGISTRY_HTTP_SECRETSet a secret text for the http header. You can put any text you want.
Volumes Set the path to both your SSL cert and key.

The file also refer to `config.yml`, `conf.d` and `html` which we're going to create later

Step 2: create config.yml

Under the same registry directory. create a config.yml file.

The config.yml configure how the docker registry needs to be setup to run. In this configuration, I setup the registry to use the local file system as the storage. It can be configured to use other storage engine, e.g. this one configures it to use Azure Blob Storage 

Full list of the configuration can be found here.

Step 3: create proxy.conf

Create a subdirectory nginx and under it create a file proxy.conf.  The nginx is configured to upstream the traffic to the docker registry on port 5000, and it is also configured to perform basic authentication via the htpasswd file (next step)

Remember to change the server_name.

Step 4: create basic authentication file htpasswd

Finally, create a htpasswd file under the nginx directory.

Once apache2-utils installed (sudo apt-get install apache2-utils on Ubuntu). Run htpasswd -c htpasswd john under the nginx directory, to create an access for john.

Tuesday, July 26, 2016

How to use ActiveRecord has_and_belongs_to_many (HABTM) association in Rails

When building an application in Rails, often when we need to create relationship between objects, we'll try look for the correct association that we can use based on our own use case. One of the association is has_and_belongs_to_many, a.k.a HABTM (yep, that acronym exists!). While many articles talks about why one should never use HABTM in place of the has_many..., but I think there's a place for HABTM, in my case, I intend to keep my application small and simple.

Let's assume I have a 2 models, "Programmer" and "Project", a programmer can work on many projects, and a project can have many programmers (obviously right?).

To do this in Rails, I took the following steps.

Generate the migration file

rails g migration CreateJoinTableProgrammerProject programmer project

This would generate a migration file like the following:

class CreateJoinTableProgrammerProject < ActiveRecord::Migration
  def change
    create_join_table :programmers, :projects do |t|
      # t.index [:programmer_id, :project_id]
      # t.index [:project_id, :programmer_id]

Uncomment the first line that create the index for [:programmer_id, :project_id]; this will let rails to add the index in the database (choosing the right index depend on how the data are query). 

Once the migration file has been configured, run migration to update the schema.rb

rake db:migrate

You'd also need to update the model classes to includes the necessary relations.

# models/programmer.rb
class Programmer < ActiveRecord::Base
  has_and_belongs_to_many :projects

# models/project.rb
class Project < ActiveRecord::Base
  has_and_belongs_to_many :programmers

Done, a many-to-many has been created relationships between "Programmer" and "Project". If you look under the hood, the migration actually created a joining table called programmers_projects with only two field, the programmer_id and the project_id, and this table have no corresponding model class in the project.

To associate a "Programmer" with a "Project", the codes can be written as follow:

# some_controller.rb
@project =

Important: Notice that the save are called from the programmer object, not the @project object. If you call save from the project, the relationship record won’t be added to the join table.

Thursday, February 12, 2015

Getting OAuth 2.0 Access Token for Google AdWords API access

Accessing AdWords data via the Google AdWords API can be confusing and complicated, especially with the way Google Services API OAuth works.

In order to access AdWords via API, you'll (or your codes)  need to be authenticate via through OAuth 2.0. This guide is focusing on getting the OAuth Access token so that you can call the API from your codes.

To do this, we'll first need to create a credential to access the API. API credentials are manage with Google Developer Console.

  1. Create New Client ID using Google Developers Console. (See the steps here - Create a client identifier and client secret)
  2. During the step #7 choose Web application and enter 

    • Save and you will see the Client ID being created as below
Next, we're going to get a token for our API calls. This actually involves getting an Authorization code, a Refresh token and an Access token (this is the token we need for API calls).
  1. Head over to, click on the gear icon on the top right corner and you'll see the following dialog.

  2. Check "Use your own OAuth credentials", and enter according the the screen shot below. The Adwords API is not in the selection, so you need to manually input "" in the Select & authorize APIs input field.

    See the highlighted boxes in the screenshot. You'll also need the Cliend ID information that you previously generate.

  3. Click the "Authorize APIs" button and login with your AdWords Account when prompted (only if you're not already logged in)
  4. You will then be redirected back to the OAuth 2.0 Playground's Step 2. At this point, an Authorization code has been generated for the Client ID.

  5. Click on "Exchange authorization code for tokens" button, and the Access token will be generated for you. There will be a counter telling you when the Access token is going to be expired and you'll need to click the "Refresh access token" to renew it.
  6. That's it, that is how you get the OAuth 2.0 Access token for Google AdWords API.

Saturday, September 27, 2014

automatically to Windows 8.1 without entering password

Every time Windows boot, I'm required to enter a password to logon to the Windows, while this is great security feature, though sometime I want the system just boot to desktop without any password.

Why? you ask, well just pure laziness I guess, and it's just a media server where I want to set this. I wanted to just press the power button of my PC, and the media server should just be ready. But because the media server service (Plex Media Server) required user to logon to Windows first before it starts itself on the system tray.

So here's the steps to set your Windows 8.1 PC to boot to Windows without any password.

1. Enter "control userpasswords2" in the Run menu (Win + R key), and press Enter.

2. Uncheck "Users must enter a user name and password to user this computer.",

enter your password when prompted.

Now try reboot the PC.

Tuesday, June 24, 2014

OneNote: We need the password to sync this notebook (Error code: 0xE4010643)

It happen to me once and it happen to me twice, and it happen again this morning.

When I saw this message, I knew no mater how many times I hit the "Sync All" it will never goes through (but I did it anyway).

I found these happen to me if I leave OneNote open, and put the computer to hibernate / sleep mode. Somehow when the computer awake from sleep, OneNote will failed to sync due to the credentials is out of sync. 

To avoid this I always close OneNote before putting the computer to sleep and often I simple shutdown the computer.

The fix to this is simply delete the cached credential used by OneNote to connect to server for synchronization, and re-login.

To do this, follow the following steps (Make sure you close OneNote before you proceed):
  1. Go to "Control Panel" > "User Accounts and Family Safety"
  2. Click "Credential Manager"
  3. Click "Manage Windows Credentials"
  4. Look for "MicrosoftOffice15_Data:live:cid=xxxxxxxxx"
  5. Expand the row and click "Remove" and click "Yes" when prompt to confirm.
  6. Don't start OneNote first, but instead, sign-out from Windows and sign-in again.
  7. Start OneNote and key in the credential when prompt. (sometime it doesn't prompt but it fixes the problem)
Update if removing item in step #4 doesn't work. Try removing the following
  • "MicrosoftAccount" - the credential you use to login to Windows
  • "OneDrive Cached Credential" 

Saturday, February 22, 2014

Express.JS quick-start guide on Windows


Express.JS is a fairly new but increasingly popular Node framework for building web application. Being a Node based application means you spin up a web application in just few steps. In this guide, I’m going to show a quick-start on just how to do this on Windows.

  1. Install node.js. See this tutorial if you don’t already have node.js on your Windows.
    • I’m using node v0.10.25, and express 3.4.8 on this guide.
  2. Create a directory for your new Express.JS app, run Command Prompt and cd into the directory. e.g. c:\users\<user name>\projects\fooApp
  3. Install express.js via npm ‘Node Package Manager’ that comes together with node.
    • In the Command Prompt, execute:

      npm install –g express

    • Watch and wait for npm to complete fetching the required dependencies for express.js. It’s going to take a while.
  4. Once installation completed, you will be presented with a summary of what packages has been downloaded and it’s respective version.
  5. Verify the Express.JS is installed and check it’s version with the command:

    express –-version

    Express will response with it’s version number.
  6. Before continue with creating an Express app, have a look at what options is available for creating an Express app.

    express –-help

    • If you do not specify any options, express will use it’s defaults that you see from this help screen
  7. Go ahead and create an express app. Execute:

    express fooApp

    For the sake of simplicity, I’m not going to specify any options.
    • Express will shows a summary of what has been created, and notice that there are 2 short instructions and the end of the summary. So we going to follow exactly that.
  8. Before proceed with the instructions, lets have a look at the content of fooApp/package.json

    cd fooApp
    more package.json

    • Like any other node.js application, the package.json defines the basic information for fooApp and it’s dependencies.
  9. Next we will install the related dependencies:
    npm install
    • Once completed, npm will again shows a summary of what have been downloaded.
  10. Before proceed to run fooApp, take a quick look at these 3 files:
    • fooApp\app.js
    • fooApp\routes\index.js
    • fooApp\views\index.jade
    • app.js – This file define the runtime configuration for fooApp

      routes\index.js & views\index.jade – This is the default route that will be executed when browse to fooApp.
      This give us an idea of what to expect to see when browse to the fooApp, and more importantly the basic idea of the MVC pattern in an Express.JS application.
      The *.jade file is template using node template engine jade.
  11. Proceed to run fooApp, in the Command Prompt, execute:

    node app.js

  12. Browse to http://localhost:3000
    • It works, just like magic.

Thursday, February 13, 2014

Installing and upgrading node.js on Windows

Steps for installation:

  1. Go to and download the latest version of node.  I'll proceed with the Windows Installer (.msi) version.
    1. You can also go to to download installer for other platform.
  2. Run the node-XXXXXXXXXX.msi installer, and proceed to installation like a normal Windows application (basically just Next... , Agree, Next … Finish). I'd strongly suggest that you accepts all the default configurations and selections during the setup.

  3. Once installation completed, start a command prompt and type "node --version" and verify that it shows the version of node.

Steps for upgrade:

  1. I personally don't use any special tools to switch between version of nodes,  I prefer install if using the same Windows Installer. (If you uses all the default settings during setup, upgrading is simple repeating the installation steps to overwrite  the current version of node)
  2. If you want to use NVM (Node Version Manager) kind of tools that available to Linux users, you can use take a look at Nodist ( You can get Nodist via Chocolatey (