Total Health Pharmacy

Working with my father’s pharmacy chain, Total Health Pharmacy, as a client was a responsibility and a pleasure, but our success came with many lessons. So when my dad told me that his work emails were bouncing, I knew that I needed to step in and get it done.

Total Health Pharmacy is one of Ontario’s largest Pharmacy chains with over 40 locations, it’s strength is actually that the stores are primarily pharmacist-owned. Owners know what is needed to service customers well, but not how to handle lower-priority items like maintaining their digital tools.

The first step was to investigate the issues. We logged into their email and immediately noticed that the email was a self-hosted system. These are great because they don’t have additional cost for adding new accounts. However, email systems are built on trust so when a virus sent out spam, the IP address was blacklisted by Outlook. They also tend to have poor spam filters.

We took a closer look at specific accounts and noticed an account that had been receiving a lot of spam that wasn’t being blocked. This turned out to be the one from the contact form. The form claimed the emails were all coming from an insider account so spam filters couldn’t connect it to the right addresses. As a result, those who were trying to maintain the inbox had to give up. The inboxes had notoriously low usage and we had to do something about it.

Our plan was to start by fixing the contact form, figure out what was causing the low usage, then fix the email system.

The contact form was simple. It just took changing the email “from address” to the contact email in the form. It immediately fixed a number of issues and the account was usable again.

We also took it upon ourselves to make an up-to-date list of stores and pharmacists. We emailed all the accounts and also called every store we could find. We asked them what issues they had with the emails and what they were using them for. Some accounts were unused or duplicates, such as a pharmacist account duplicated with a store account, where only one was being checked.

What we found out is that most of the issues could be solved by migrating the email accounts to a recognized email provider such as Gmail or Zoho. We ended up choosing Zoho because the price was good and they had good support and migration tools for the old emails and contacts.

The email migration was a difficult process nevertheless because the addresses were live and still in use. We started by creating a diagram of how the migration would go and confirmed it with outside industry professionals. We were lucky because the company has a .ca and a .com domain, one with emails, the other without. Our plan was to:

  1. Create .ca copies of the email addresses
  2. Forward .com emails from the original server to the .ca email addresses
  3. Copy emails from the old server to Zoho
  4. Point the domain to Zoho

We let people know about the changes at every step. Creating the copies wasn’t bad. We had a list of emails and went through it one-by-one. We had made a list of the emails that were requested to be deleted, requested to be merged, etc. and made sure to follow through with those requests.

We added the forwarding rules to forward new emails to the .ca accounts. This was so that we didn’t miss a single email.

We migrated emails in batches as we were limited to a certain size per migration and kept track of every address we had copied over.

Before we pulled the trigger and made the move permanent, we double checked to make sure each account was working. We added the (.com) “aliases” for each account while the domain was unconfirmed. This meant that both and would go to the same inbox. We then decoupled the domain from the old server and coupled it with Zoho. We also made sure everyone could use the emails and had the support phone number for Zoho.

We successfully completed the migration with 0 email downtime. The thing that we got right was making a comprehensive plan first. We also were right to make sure to contact every store through all mediums. Logging our tracks along the way in the migration was tricky, but helped tremendously. The only thing that may have helped was if we had made an external backup of the old emails from addresses that were deleted as some patrons changed their mind about keeping old accounts.

Total Health Pharmacy

GitHub: The teamwork convenience that we take for granted

We humans have this amazing (#sarcasm) ability to start taking things for granted. Every time something new comes along, we have a fleeting ‘wow’ moment and then we completely forget about how much of a blessing that something is. 

For example, when you get into your heated car in the winter morning to go to work/school, do you ever stop to consider how our commute would have been if we were still riding horses? Granted, most of us haven’t experienced commuting to work on horses but… just use your imagination for now! Also, I am not that old! 

So why do I bring this up? I firmly believe that sometimes pondering over how we got here is a good way to drive innovation.

One such convenience that we in the software world take for granted is GitHub. More specifically, the GitHub tools that allow us to organize teams, distribute responsibilities and compare the work we do with other brilliant people around the world.

For this blog, I want to focus on just one of GitHub’s many amazing features, the GitHub ticketing system. Though assigning tickets to your teammates is not exclusive to GitHub, the fact that it is part of this convenient package is something to appreciate.

The success of the projects that we at Communote Inc. undertake, depends largely on how well we are able to distribute responsibilities in the team. Most of the time, our team has members that work remotely…and when I say ‘remotely’, I mean different time zones ‘remotely’. When we get a project, the team lead decides on how to break the project into bite-sized pieces and who’s plate these pieces are going too. 

Being able to create a separate project section in our Communote GitHub page and then assigning tickets to individual team members is nothing short of a blessing. Each member of the team can then freely comment to communicate what is required for that specific ticket/task and if another member of the team would like to help with that ticket. 

It is such an amazing way to organize and communicate with the team. It brings the team closer and gives a sense of teamwork that is much different than the cogs-in-a-machine mindset that we are accustomed too.

Not to mention… feels so good to close tickets at the end of the day. It gives you a sense of accomplishment! You made a difference in the team and that your achievements are there for everyone to see. You are not a lone individual slaving away without any recognition. And hey…if you are stuck somewhere…guess what? You can create your own tickets to get help! More power to you!

The ticketing system is also a good management tool. Closed tickets allow the team leads and management to gauge the performance of individual team members and the team overall. This is very helpful when the time comes to make future management decisions. It helps answer questions like:

  1. Can we put more responsibilities on the team? If not, do we need to add members to the team?
  2. Are there areas for improvement?
  3. What are the strengths and weaknesses of our teams/team members?
  4. Which team/team member seems more active?

These questions are very important when making hiring/firing or promotions/pay-raise decisions. Sup HR? Here’s me looking out for you…so about that pay raise I requested…right… not the place.

Overall the GitHub ticketing system is a very versatile tool and if used properly, it will help organize teams, reduce management headaches and increase efficiency. Talk about a win-win…win situation.

What do you like and dislike about GitHub? Let’s get the conversation started!

GitHub: The teamwork convenience that we take for granted


We’re disruptive. We’re passionate. We’re here to change the way you read.

Information is meant to be free, but authors need to be compensated. We give information its wings by giving back to the authors using ad revenue.

YouTube changed videos. Spotify changed music. It’s time for someone to take back books.

But we’re more than that. We’re tools that help you publish your awesome stuff. We’re micro-communities for each category of content. We’re a community governed by a blockchain-backed discussion platform.

Not Amazon, not OneClass, not Scribd, not any of the “game-changers” could balance free and paying the authors. We’re the ones to do it. We’re the students in your class you copied your notes off of even though you took them yourself. Most of the people we know are published researchers.

We are communote.



Why use MongoDB?

  1. You can query on it like SQL.
  2. It uses a flexible schema because it saves everything in JSON. That means within a table (a.k.a. collection, since there is no rigidity in Mongo), some rows (a.k.a. documents, since each row is a JSON document)
  3. It doesn’t require joins. Usually, everyone pushes for normalization, i.e. no redundant data, but that is only optimal for writing to the disk because you only have to write once. However, the real struggles are querying and reading. Since you’re using JSON, there’s enough room in each document to put the relationship in both collections that are being related. Yes, it is redundant, but it is faster for reads.

There is a date operator

 _id: ObjectId("1234567890abcde"),
 birthday: ISODate("1983-02-29T00:00:00Z"),
 gender: null, 
 pizza: [{
   "green peppers",
   "red onions"
  sauce: "white",
  crust: "thick"

I allow three options for gender. I can do this, since booleans in databases actually have 3 values:

  • true: “male”
  • false: “female”
  • null: “other / prefer not to disclose”

I don’t mean to make a patriarchy.

If you’re storing messages in MongoDB, you need to define a limit to the size of the message. Let’s calculate it together! The maximum size of a document is 16MB. That means 16 million bytes. Strings (the format the text will be saved) are stored in UTF-8 format. That’s a crazy large size. I copied the text from a 306 page programming manual into this calculator and the >1 million bytes held <1M characters. I would even go ahead and say to just put a 1M character cap to posts.


There are two types of sorting: internal and external. External sorting is when you sort the data every time you query, whereas internal sorting is organizing the way the data is stored.

Internal sorting is good if most of your queries require the same sorting schema (what attribute(s) are you sorting by?). External sorting is useful for when you have many different ways you want to sort the data.

Note: remember how I said attribute(s)? That’s because you can sort by multiple attributes at a time. It’s something called a compound index.


There are actually multiple types of internal sorting methods. There’s clustered, and unclustered. Think of clustered as being a phonebook, whereas unclustered is the index at the back of a book.

Clustered is sorting the entire database according to an attribute. You can have multiple clusters for each index you want to sort by. However, you have to completely replicate the entire data set for each cluster, which is a huge amount of space. This can take up less space than unclustered if you are archiving old data, which you know won’t change often and you only have one set. It’s worse for tables you’re changing often because there’s a larger cost for moving your data around.

Unclustered is having a separate table for each index. This is useful if you have multiple ways you want to sort the data and / or you’re moving the values around a lot.


These sorts are built into the query syntax.

I’ll explain more in my article on Motor, an asynchronous Python package built specifically for Tornado.


Git Help

If you know nothing about the git commands, go do this tutorial:

Yeah, you’ve checked out the online GitHub editor for files. However, that doesn’t work for editing everything. It also requires that you’re online to make changes and there’s no flexibility for testing what you’ve made. For that reason, there’s a way to edit your files locally, through something called a git client. Clients allow you to keep a copy of the code on your computer and push changes when you want.

However, for anything other than the basic pull and push, the basic GitHub for Windows client doesn’t support this. I recommend you use something else, such as TortoiseGit (my favourite for Windows) or SourceTree (my favourite for OS X) or kdiff3 (favourite for Linux) or even the command-line tools

git Branch

Occasionally, you’ll start on something that you want to work on later that you no longer have the time to work on. You can either lose your changes, or branch. Branching means you have multiple directions in which the code is changing. Think of each change as a money transaction.

  1. Branch
  2. Make a random change (add a comment, update readme, or actually make a proper update if you have the time)
  3. Push the changes
  4. Checkout back to your master branch (clean, i.e. make your local branch match the master branch and ignore the changes you just made to your branch.
  5. Remove the project.

Types of branches

When versioning, you will have multiple branches that will reflect different sets of changes. Until you save your changes on your git server, you’ll have a different set of changes that have happened.

The default branch is called the master branch. It is the branch that you get when you use the command git init.

All branches have 2 aliases:

  • Remote: the version of branches hosted on servers, like GitHub; AND
  • Origin: the version of branches on your computer.

HEAD points to the last commit made on the current branch.

git merge

If there are changes from another branch that you want to exist in your branch, git merge puts them into your current branch while keeping your changes (as long as they don’t conflict). To prevent conflicts you can either choose to keep your own version:

git merge -X ours branchB

or the version on the branch you’re merging:

git merge -X theirs branchB

git rebase

Moving a branch history so it begins at a different point in time.

git remote

Often when you’re trying to automate updates, you’ll get frustrated having to enter a ton of commands and passwords. So you try However, you still have to enter your git password each time. This is especially true for something like accessing your MongoDB server. That’s where you can use git remote.

git remote set-url origin

If you ever need to change the url / password, you just repeat that command, except with your changed password. If you’re unsure about whether you got it right or not, you can list the different urls you have saved in there, using

git remote -v

Which should respond with:

origin (fetch)
origin (push)

git Submodules

This is how to have git-ception. Git repos inside git repos. It’s especially useful if you’re using someone else’s git repos as a component in your project or you just wanted to split the project up into multiple components.


git submodule add <link>


git submodule update

Syncing individual packages

cd into the folder

git pull

Git Help

Search Engine Optimization

In order for more people to find your website, you want it to be higher in search engine rankings. There are a number of ways you can do this.

  1. Use https (see how to in my article on CloudFlare): Google and other search engines are trying to push https because it makes your website more secure.
  2. Link to your website where it is relevant: don’t try to spam your website link everywhere, but find places where it would be important, such as your Facebook, Twitter, maybe in a couple places on Reddit, alternativeTo, blogs that discuss something similar to your website, etc. When the engines notice there are a lot of cross-listings, they figure your website is pretty popular. However, I’m pretty sure they can identify spam (not sure about it, but it’s also not very nice to spam).
  3. Sign up for search engine trawlers: you shouldn’t have to sign up to most search engine crawlers. Don’t pay for any of them! However, some could be useful to sign up for. I noticed one called Yandex, which also does things like lets you know if there are viruses and other vulnerabilities on your website. It’s a very thorough virus scanner that picked up things that website scanners, such as Norton and McAfee have missed. It’s also endorsed by CloudFlare. In this article, I’m going to show you how to get Yandex to crawl your site.
  4. More tips are coming.


How to get Yandex to crawl your site:

  1. Sign up as a webmaster.
  2. Click the “Add site” button.
  3. Enter your domain details.
  4. Verify your account: there are a number of methods, but I didn’t feel like changing the content on my page, so I chose the DNS method.
    1. Click on the “by dns” tab.
    2. Go to your DNS Settings page on CloudFlare (or wherever you have yours, but you should probably use CloudFlare).
    3. Add a new TXT entry:
      1. In the “Name” or “Host” field, enter the domain you want to get crawled
      2. In the “Value” or “IP ADDRESS / URL” field, enter yandex-verification: 1234567890abcde, except, of course, use the number you were given.
    4. Press the “Check” button on Yandex.

A crawling summary page will appear. You are done! You can run a scan by hitting the “Security” link on the left.

Search Engine Optimization


How to install and configure LibreSSL. I explain its importance in my CloudFlare article. Before continuing, download the latest version here. Or get the latest version using this command:

$ curl -O ""$(curl -s "" | grep "(libressl-\d.\d.\d.tar.gz)" | tail -1 | cut -c 9-29)


1) Unpack LibreSSL

$ tar -xzvf libressl-2.1.3.tar.gz
$ cd libressl-2.1.3
$ ./configure
$ make
$ sudo make install

2) Install LibreSSL locally

If you’re using LibreSSL version 2.0.0 or earlier:

$ ./configure --prefix=/usr LDFLAGS=-lrt && make check && sudo make install

Fortunately, LibreSSL runs all the OpenSSL commands. So you can probably find tutorials that tell you how to configure OpenSSL and apply that to LibreSSL. Think of LibreSSL as the non-broken version of OpenSSL.

To check if it installed properly:

$ which openssl
> /usr/local/bin/openssl
$ openssl version
> LibreSSL 2.1.3

3) Making the certificate

3.1) Your Private Key

Now, you’ll need to use a password to make your private-key file. Think of something that isn’t a common thing. Maybe get a password generator but store it somewhere you can retrieve it, like a password manager. You can put your private key file anywhere and name it whatever as long is it’s “something.key”

$ openssl genrsa -des3 -out privatekey.key 2048

3.2) The Certificate Request

Now you need to make a CSR (Certificate Signing Request) file. This is also the public key. This is information about your company to maintain integrity, i.e. so people know you’re the host sending them responses. First of all, you can save this anywhere as long as the extension is “something.csr”. Usually, it’s best if you save it as “domain.csr”.

The terminal will ask you each of the following questions:

  • Country code [C]: check your country here
  • Province/STate name [ST]: spell out your province or state fully
  • City/Location [L]: the city your company is registered under
  • Organization Name [O]: Your legal business name
  • Organizational Unit Name [OU]: (Optional) What part of the company are you?
  • Common Name [CN]: the hostname+domain, i.e. “” is different than “”. In our case, we’re putting SSL on our IP address, not a usual occurrence.

Do not enter an email address, challenge password or an optional company name when generating the CSR.

You can run the following command or you can change the configuration file settings:

$ openssl req -new -key privatekey.key -out domain.csr

3.2.1) Config Files

Using a configuration file will allow you to customize your certificate more than if you don’t. The reason why I’m recommending you do is because you can put multiple hosts, i.e. you can enter “” AND “” for the same config file. Otherwise, the certificate will only be valid for the default subdomain. You could also forward www to no-www or vice versa and just do one of them. I did that by doing CloudFlare > Page Rules > forwarding* to

It also allows you to use it if you have multiple domain endings, e.g. “” or “”.

The configuration file outlines the default settings for the certificate.

Make a new file and call it “something.cnf“. Usually, it should be named “openssl.cnf”. By the way, if you’re Googling this, there are two encodings for configuration files: DER and PEM. I’m using PEM.

Here’s a sample certificate. The certificate will use the following format. There are limitations to the lengths of the inputs. Usually, when you look at documentation, attribute is the question the terminal asks when requesting the value for the given  attribute, attribute_default is the value if you don’t put a value, attribute_min is the minimum length of your input, and attribute_max is the maximum length of your input. A ‘.’ represents an empty input. Comments are denoted by an octothorpe ‘#’. Yes I just wanted to say octothorpe. I played around with the file a bit to get a better understanding of how it works. Take the following code, alter DNS.1 with “” add any other domains that you want as additional alt_names, and save it in your config file:

[ req ]
string_mask = nombstr # permitted characters
distinguished_name = req_distinguished_name
req_extensions = v3_req

[ req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = US
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = California
localityName = City of your company
localityName_default = San Francisco
organizationalUnitName = Department
organizationalUnitName_default = IT Department
commonName = Domain Name
commonName_max = 64
commonName_default =

[ v3_req ]
# Extensions to add to a certificate request
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names

[ alt_names ]
DNS.1 =
#DNS.2 =
#DNS.3 = *
#IP.1 =

Make the CSR with:

$ openssl req -new -key privatekey.key -out domain.csr -config openssl.cnf

You can check what you made by running:

$ openssl req -text -noout -in domain.csr

3.3) Signing the certificate

Quick note before I continue. Methods like this to obtain a TLS certificate are called “self-signed” because you sign them yourself. The alternative is paying for a subscription from a TLS provider. There are varying differences in security, but self-signed certificates can still have a lot of the same features that those from Certificate Authorities (CA) have. The only difference is how long they are valid. When someone cracks your passphrase, you need to change it ASAP or else they can spoof your certificates, which permits them to send viruses and crap to your users who think that you’re the one sending them.

If you self-sign your certificates, you can only either assign a days limit before the certificate expires or let it never expire. With CA certificates, you can renew your certificates on-demand. For this reason, sites with “self-signed” certs are called insecure by browsers. It’s ok to use this behind CloudFlare, though. For the next step, the self-signing stage, think of the number of days would make you feel safe about a certificate. I’d say 90 days. Circle the day on your calendar when you have to renew the certificate and use a different passphrase. Save it as “something.crt“.

$ openssl req -x509 -days 90 -key privatekey.key -in domain.csr -out certificate.crt

Each certificate generally applies to one sub-domain, i.e. “” OR “”, not both. However, you can get a wildcard certificate that applies to everything within one level of sub-domains, i.e. not “”.

You can review your certificate with the following command:

$ openssl x509 -in certificate.crt -noout -text -purpose | more

Some things will ask for “.pem” files. Actually, pretty much all of these are “.pem” files. You can just rename all the extensions to “.pem”, similar to this.

Soon, I’ll talk about how to configure this with AWS or Nginx or Tornado. Also, a bit about what cacert is.


Modelling your system

Whether you consider yourself a developer (anyone can be one) or you want people to understand your idea, you need a way to communicate what your idea is to the other people on your team. The most common way of doing this is something called UML (Unified Modelling Language).

You can try to describe the mapping of your webpage, but visually is usually the best way. There a number of useful types of UML diagrams that you can use to communicate your ideas between each other. The most important thing to have when choosing a tool to make your documentation is that it’s shareable and modifiable. Your ideas will be changing as you continue with your development.


My favourite was, but there are lots of other tools. is great because it’s free and has a lot of awesome shapes / tools, including Google Drive sync (instead of most which do Google Drive export).

The only problem is that there is a bug that is not letting me share it / collaborate on the same document. The support claims that the problem only persists if you have work accounts and school accounts open. I tried logging out of all my accounts then logged in with one, but it still failed to work.

Until the bug is fixed, I recommend using LucidChart.

Types of diagrams

Use Case

What can different types of users do? I’ll finish this later.

Data Flow

These model the flow of data using arrows that describe the data being sent. Usually they have 3 parts:

  1. Databases
  2. System
  3. Input/Output

However, I feel that’s too confusing, so I divide mine into 4 parts with each getting its own section or swimlane. It’s pretty much the same, but it’s more clear this way.

  1. Databases and Datastores
  2. External
  3. Web Application
  4. Front End

Databases & Datastores

The first thing you’re probably wondering is “what’s teh difference between databases and datastores??” A datastore is simply any place where you…store data. That includes images, videos, media, text, documents, etc. Databases are one example of a datastore that only saves text and numbers. Use databases for statistics or messages and have separate datastores dedicated to media.

In our case, we’ll store images and documents on Amazon S3 and information about the documents in a hosted MongoDB provider, called Compose.

This is useful because it clearly states how many servers you are actually managing and allows people running the business end of things to understand what expenses will be necessary.


This section is for all the websites that you don’t manage that you communicate with, i.e. whose APIs do you use not including the ones to your datastores?

Web Application

You’ll probably have one main application server. This is probably where the majority of your website is. However, in this swimlane, just focus on what is processed. Include calls to external APIs and datastores because that’s not going to happen front end. Make each process a different symbol.

Front End

What types of pages are you going to have? Which ones are going to communicate with what processes? Treat the header and footer as their own pages for now: they are pretty much on every page and the arrows are just gonna fly everywhere.


Pick a different symbol to represent an object in a different swim lane. For example, if you make the Batman symbol represent each process, every process will have the Batman symbol and a label on top with a one/two word description.

The only exception that I sometimes do is that I sometimes use a cylinder standing up for databases and a symbol lying down for datastores.

Cylinders for databases and datastores

Generally, you’re also supposed to use something circular, preferably with an arrow for processes.

Process Loop


I made an example of it all put together using a service called Gravatar which is a universal avatar service that allows you to make one avatar for every website you go on. It takes in your e-mail address and gives out the URL to the person’s avatar. In this case:

  1. When the page starts to load, Gravatar fetch will get the Gravatar URL from MongoDB.
  2. It will then embed it in the header.
  3. Lastly, the header fetches the image and embeds it.

Sample Swim Lanes


Entity Relationship

Explain how your different collections / tables in your database(s) are connected. Conceptualize each of your tables as a separate object. Here are some terms you should know:

  • Entity: the thing
  • Attribute: something that describes the thing
  • Foreign Key: when you actually store the attributes of the thing in the collection of another thing (underline these)
  • Primary Key: something the entity has to have that identifies it (bold these)
Modelling your system

GitHub Pages

Sometimes you may want to post some content that is open source and use free GitHub hosting. You’ll want to make a GitHub page. I’m going to describe here how to make a GitHub page.

  1. Follow these clear instructions to make a new “Organization” for your company. This will allow you and your team to organize your company’s projects under the team’s name instead of under your username.
  2. Under your organization, make a repository called
  3. Name your homepage “index.html”.
  4. To make project pages:
    1. In your project repository, make a branch called “gh-pages”.
    2. In there, put a page called “index.html”.
    3. Access your project page at <username><repo-name>

UsING your own domain

If you try to forward your domain to it, you may notice that it goes to a 404 page, instead of the page you made. To get around this:

  1. Put a blank text file in your repository with the name CNAME and no extension.
  2. Open CNAME and put the link of your domain in it, e.g.


GitHub Pages


Every computer has its own IP (Internet Protocol) address to differentiate where data came from and where it needs to go. The same goes for your website server. However, it’s pretty unprofessional to tell people to use your IP address to get to your website. So we use a phrase, such as

This phrase is called a domain. Unfortunately, you need to pay for a domain. Usually, it’s a good idea to pay for 3-5 domains so other people don’t buy them and fake the website. Imagine if a hacker bought and faked the front page of Facebook and you logged in. Then the hacker would have your username and password for Facebook. You wouldn’t want that happening to your users.

Domains allow the user to use your website without needing to enter your server’s IP address. This also means you don’t need to give away your IP address, which can be a deterrent for hackers.

When purchasing domain names, shop around at different websites, such as namecheap or GoDaddy. Try to get package deals on multiple domains at once.

But wait, there are still a number of cool things I wanna talk about domains when setting them up.

If you enable forwarding, your website will redirect to the link you provide it. However, that’s probably not what you want. You’ll probably want forwarding & masking, which is when you can see your website, but the address bar still says your domain. Sometimes, website builders prevent you from masking because they want you to pay for their domain services, so you have to do forwarding.

You can use subdomains, like to forward to as many addresses as you want. You’ll probably do this if you have a developer version of your site that you don’t want anyone to know about.

Also, some domains come with a free e-mail address, which is cool. You can actually forward your e-mails from that address to your regular e-mail address if you prefer everything in one e-inbox. There can be problems replying back, though, so you’ll need to add your address as an alias. Here’s how to do it on gmail (as of writing this article):

  1. Settings > Accounts and Import
  2. Look where it says “Send mail as:” and click “Add another email address you own”
  3. Follow the instructions

If you’re forwarding extra domains that forward to your main domain,  make sure you assign forwarding for subdomains @ (default, i.e. no subdomain), www, and * (wildcard, i.e. all other subdomains).

Advanced Setup

Sometimes, your domain provider will make you edit the domain records directly. In this case, it’ll be a bit harder to set up the domain. There will be a number of terms that you’ll need to learn. Here are some of them:

  • A: (Address Record) maps to an IP address. Useful if your host gives you the location of your site with just an IP address
  • CNAME: (Canonical Name)same as masking
  • HTTP Redirection: same as forwarding
  • MX: (Mail Exchange) e-mail

Unfortunately, some providers don’t allow for HTTP Redirection Record, such as CloudFlare, so you need to find alternative ways of forwarding to a page. With CloudFlare in particular, look at the instructions. I’m still trying to figure out how to get this to work.