Configuring Mutt for Gandi Mail (IMAP and SMTP)

Gandi is my favorite registrar for many reasons. Their motto is “No Bullshit” and they mean it. They make it super easy to manage domains, and offer tons of great services. One of the best things about buying a domain from Gandi is that they provide you with free email for the life of your domain. Setting up a mail server can be a pain in the ass, so this is really kind of awesome. mutt is an awesome MUA (Mail User Agent) that is light weight, terminal based, and highly customizable. Your local mail system can be as complex or as simple as you want it to be. There are countless guides out there on how to mutt, but a lot of them seem way to complex for my use case and can get very confusing. This guide will help you get mutt working with Gandi mail. Gandi mail is a pretty generic mail stack so this should also apply to any other IMAP/SMTP mail system that uses Dovecot, Postfix, etc… as well. My use case is this:

  1. I use Gandi mail for all of my personal email for a single address.
  2. I want to connect to Gandi using IMAP with mutt
  3. I want to send mail with mutt by connecting to Gandi with SMTP

Note that there are no local folders on my machine in this use case, so everything is happening on the mail server. A lot of the mutt guides assume that you are using mutt for just reading email and are using some external program like fetchmail to receive the mail to a local folder, and some external smtp system like msmtp to send it. This is not what we are doing here, so if you want this type of setup I would suggest looking at this guide instead. With this simple use case in mind, your .muttrc file becomes super simple.

  1. If you have not already, install mutt.
    #On Debian Based Distros  
    apt-get install mutt   
    #On Red Hat Based Distros  
    yum install mutt   
    #On Mac OS X, assuming you have Homebrew Installed 
    brew install mutt
  2. Open up a text editor and put the following in your \~/.muttrc file
    # Configure imap username and password  
    set imap_user="" 
    set imap_pass="YourPassword"  
    # Configure Default Folder and where to put Sent Mail  set folder="imaps://" 
    set spoolfile=$folder 
    set record="=Sent"  
    # Configure SMTP Settings  
    set smtp_url = "smtp://$imap_user:$" 
    set realname="Your Name" 
    set from="" 
    set use_from = yes  
    # Enable STARTTLS for Security set ssl_starttls=yes
  3. Fire up mutt, you will be logged into your Gandi inbox and you can start rocking out your mail.

This was a super simple config and it “just works”. It allows you to perform the basic functions of receiving, reading, and sending mail. You can now go read about the other 10,000 config options in the mutt manual.


Added STARTTLS to .muttrc example, thanks to Kenn for the catch.

Posted in debian, linux | 2 Comments

Hacking an Angular.JS game for Fun and (fake) Profit

Last night I came across an interesting game called Giant Shaft Enterprises. In this game you play the role of a CEO of a fictitious company and the goal is to maximize your profits and reduce costs. You do this by performing business opportunities such as “Network with business leaders”, “Push the envelope”, and “Streamline workforce”. You also can hire employees, purchase buildings, establish various departments, and motivate your workforce with seasoned upper managers. The last thing that you can do in the game is purchase upgrades such as health benefits, electric car charging ports or allow upper managers to hold useless meetings. These upgrades maximize the performance of your workforce. All of these things make more money for your company and allow you to get achievements.

This is pretty much like any other point, click, and wait game that you would find in the “Top 10 Free Games” section in an App store, but the difference is that this game does not take any real money from you. The game is very entertaining and kind of trolls the world. For example, buying more cubicles for your company provides a higher ROI than hiring additional upper managers. The game is also strangely addictive, I found myself clicking on the same button thousands of times to get more money and increase the profitability of my company.

I must have played for a few hours before I began filling a bit silly for wasting my time clicking on a button. A few hours later not only was I feeling silly I was also beginning to get an repetitive stress injury in my wrist. That is when I realized that clicking on the button to watch my company sore to greatness was not providing me with the highest ROI. Then I decided to streamline my efforts and opened up the Chrome Javascript Console to see if I could outsource me clicking this button to a simple Javascript program.

Luckily, this was pretty straightforward. The app is written in Angluar.JS and all of the various buttons that you click to do things are exposed in the DOM. Using JQuery you can access these buttons a simulate a click through the Javascript console that can be found in the Developer Tools of most browsers. For example, the button that lets you take advantage of business opportunities (and instantly raise more money) calls a function called doBusiness. You can select it, and send it a click() like this:

$('div[ng-click="doBusiness(opportunity, $event)"]').click();

You can also send it 10, 100, or 1000 clicks by wrapping this in a loop.

for ( i=0; i < 100; i++ ) { $('div[ng-click="doBusiness(opportunity, $event)"]').click(); }

All of the things that you buy in the game use the same function calledbuyStoreItem, but the individual items (such as employees, cubicles, and harware) are referenced by index. Using the similar method you can purchase things in various multiples by wrapping the function in a for loop like so:

# Buy Cubicle   for ( i=0; i < 100; i++ ) { $('div[ng-click="buyStoreItem($event, item)"]')[1].click(); }

I found that if I try to send more than 1000 clicks at once, the app tends to freeze and bomb out. Looking in htop, chrome is using up 100% of my CPU so it looks like 1000 is the magic number. Javascript is fast and it looks like it sends all 1000 clicks pretty much at once which confuses the app and makes it very sad. I realize this goes against the spirit of the game, but nonetheless it was a fun little exercise and games should reward cleverness. A full list of ~~Cheats~~ Synergistic ROI Optimizers is listed below:

# Giant Shaft Cheats   The lines below simulate clicks, to run then open up the Javascript Console (in Chrome this is Ctrl+Shift+i) and enter them. To change the amount of simulated clicks change the second value in the for loop ( i < 100 ) to something other than 100. Going above 1,000 will probably crash the app :)   

# Do Business Opportunities   
for ( i=0; i < 100; i++ ) { $('div[ng-click="doBusiness(opportunity, $event)"]').click(); }    

# Buy Minium Wage Worker   
for ( i=0; i < 100; i++ ) { $('div[ng-click="buyStoreItem($event, item)"]')[0].click(); }   

# Buy Cubicle   

for ( i=0; i < 100; i++ ) { $('div[ng-click="buyStoreItem($event, item)"]')[1].click(); }   

# Buy Salary Employee   
for ( i=0; i < 100; i++ ) { $('div[ng-click="buyStoreItem($event, item)"]')[2].click(); }   

# Buy Hardware   
for ( i=0; i < 100; i++ ) { $('div[ng-click="buyStoreItem($event, item)"]')[3].click(); }  

# Buy HR Department   
for ( i=0; i < 100; i++ ) { $('div[ng-click="buyStoreItem($event, item)"]')[4].click(); }   

# Buy Accounting Department   
for ( i=0; i < 100; i++ ) { $('div[ng-click="buyStoreItem($event, item)"]')[5].click(); }   

# Buy Benefits Package   
for ( i=0; i < 100; i++ ) { $('div[ng-click="buyStoreItem($event, item)"]')[6].click(); }   

# Buy (Useless) Upper Management   
for ( i=0; i < 100; i++ ) { $('div[ng-click="buyStoreItem($event, item)"]')[7].click(); }   

# Buy Executive   
for ( i=0; i < 100; i++ ) { $('div[ng-click="buyStoreItem($event, item)"]')[8].click(); }   

# Buy Office Building   
for ( i=0; i < 100; i++ ) { $('div[ng-click="buyStoreItem($event, item)"]')[9].click(); }

Thanks to this little hack I am the king of Giant Shaft Enterprises. Thank you to Eric Freeman for making this awesome game!

UPDATE 1:  I was curious to see what the max number of clicks I could pass through was. I enabled logging to show me when the loop made the 100th click.

for ( i=0; i < 1000; i++ ) { $('div[ng-click="doBusiness(opportunity, $event)"]').click(); if (i % 100 == 0 ) {console.log('Click #' + i)}}

It looks like the app actually does not crash … but becomes super slow after about 3000 clicks. So to optimize ROI you should only cheat with around 1000 fake clicks at a time.

UPDATE 2: The final step of this was obviously to automate the automated clicks. Using Javascripts setInterval method, we can have the script run indefinitely. For example the following code, does 100 business opportunities every 3 seconds, forever.

setInterval(function() {for ( i=0; i < 100; i++ ) { $('div[ng-click="doBusiness(opportunity, $event)"]').click(); if (i % 10 == 0 ) {console.log('Click #' + i)}}}, 3000);
Posted in programming | Leave a comment

ezBadge v2: Now in Stunning Javascript HD

If you have ever wondered what it looked like to convert an application from Python to Javascript, you are in luck. After finishing ezbadgeyesterday, I came to the realization that the entire thing could and should have been written in Javascript. There is absolutely no reason for this thing to send any requests to a server in order to process the URL and render the markdown.

So, I did just that. Introducing, ezBadge v2 After removing all of the Flask, I was able to create two Javascript functions that essentially did the same thing as the Flask app was doing for me.  The added benefit is that other than serving the initial HTTP request, I do not have to handle any additional requests and the entire thing now runs in the browser.

This was a fun little exercise, and I think the Javascript version of this application is a bit more elegant. Rather than appending the template with Jinja as I was doing before, I am now spawning a modal (after doing some form validation) and then using the Marked library to render the preview of the badge markdown. I could have done all of the UI stuff with Flask without any issues, but the fact that the entire thing now runs in the browser saves bandwidth, computing resources, and time.

You can see the transformation for yourself in the ezBadge GitHub repo. In the next iteration of ezBadge I plan on adding more choices for the types of badges that you can make. If you have any suggestions please feel free to leave a comment here or open up a github issue.

Posted in programming | Leave a comment

Introducing ezBadge

A few months ago I wrote about my struggles with Markdown Image Links. The entire reason why I was working on that before was to put cute little badges in my Github repos. Today I took this a whole step forward and wrote a small web application that just “does the needful” for you. ezBadge makes it easy to transform a regular Github Repo URL into a beautiful badge by writing the markdown for you and allowing you to just copy and paste it into your file or anywhere else where Markdown is supported. You just feed it a valid Github repo URL and it spits out the Markdown along with a preview of what you will see if you put that markdown somewhere. So far, the only type of Badge that it makes is a CircleCI badge but I plan on adding more in the near future and if there is a badge that you would like to see, please open up an issue for this project.

Posted in programming | 1 Comment

Installing Powerline in Debian

Powerline is an awesome status bar that tells you additional information about various things in bash, vim, and tmux. It comes in handy and makes your terminal look sweet. It is a little bit of a PITA to install, but it is totally worth it. I got most of the way there with this very helpful Stack Overflow answer. But I ran into an issue with vim in Debian. I was getting an error telling me that vim needs to be compiled with python support in order for powerline to work. This seemed silly to me because you should not have to recompile vim in order to use this little plugin. Luckily the solution was easy. There are like 20 different vim packages in debian. The default vim package gives you a bare bones vim install. In order to take advantage of this plugin and other goodies you should install the vim-nox package. In order to install powerline in debian you should do the following. This will install everything system wide.

  1. Install pre requisites
    sudo apt-get install vim-nox git python-pip
  2. Install Powerline
    sudo pip install git+git://
  3. Install the required fonts
    sudo mv PowerlineSymbols.otf /usr/share/fonts/ 
    sudo fc-cache -vf 
    sudo mv 10-powerline-symbols.conf /etc/fonts/conf.d/
  4. Add the following to your \~/.vimrc
    set rtp+=/usr/local/lib/python2.7/dist-packages/powerline/bindings/vim/  
    " Always show statusline 
    set laststatus=2  
    " Use 256 colours (Use this setting only if your terminal supports 256 colours) 
    set t_Co=256
  5. Add the following to your \~/.bashrc
    if [ -f /usr/local/lib/python2.7/dist-packages/powerline/bindings/bash/ ]; 
    then source /usr/local/lib/python2.7/dist-packages/powerline/bindings/bash/ 
  6. Add the following to your \~/.tmux.conf
    source /usr/local/lib/python2.7/dist-packages/powerline/bindings/tmux/powerline.conf 
    set-option -g default-terminal "screen-256color"

Restart your terminal and you should see powerline working now. Open up vim and prepare to be amazed.

Posted in debian, linux | Leave a comment

Stolen Bank Card

I tend to not think about someone stealing my credit card or identity because that “only happens to careless people”. You know, the kind of people that buy discount cigarettes from some shady company in Hong Kong that does not offer HTTPS on its checkout page. Well, that naive bubble was burst this weekend when I was in FL.

I used my card twice on my first day there. The first was at a gift shop at the hotel. It was a decent hotel so I don’t think that this is the vector where the card was stolen. The second was at a much shadier store at a mall. This is the place that I think the card number was jacked. I am not sure if the guy was in on it, or if the company he uses to process his payments is in on it, or what. All I know is that the next morning someone went on a shopping spree in Miami beach. The first charge was for $40.25 at an undisclosed location (my bank cannot even figure out what this charge is for). I think this was just a sample charge to see if I had any money in my account. The second charge was for $482 at a car rental place in Miami Beach. I guess some douchebag rented a Ferrari or something for the day. The third (and final charge) was for $398 at Armani Exchange.

This was thankfully declined by the bank and this was the charge that prompted my bank to contact me and let me know that something shady was going on with my account. Thank goodness that my bank (Navy Federal Credit Union) was on top of its stuff and the fraud team quickly got in touch with me and we were able to freeze the account. In addition, thanks to the zero liability policy at the bank I will be able to get all of this money back.

To the people who stole my card, fuck you. To everyone else who is reading this, please be careful with your card in general and especially when you are traveling. Sadly, there are some shady assholes in the world that want to steal your hard earned money to rent luxury cars and purchase overpriced polos at Armani Exchange.

One great tip that I got from the fraud team was to not use the check card at all since it is directly tied to my checking and savings account and can cause some serious damange. Instead, using the credit card that I have with the bank instead (especially when traveling) will make sure that even if people get the card somehow they cannot do too much damage to the rest of my accounts. In addition, I think that in this case someone made a copy of my card (since my actual card was not stolen).

The new Navy Federal credit cards come with a secure chip that makes duplicating the card pretty difficult. Unfortunately this is not available with the check cards yet, but I am looking forward to it so that these types of issues can be prevented in the future. In a way I am kind of glad that this happened to me since it opened my eyes a bit and I will be much more careful where I use my card in the future.

Posted in life | Leave a comment

Setting up ANTLR4 on Windows

I am using ANTLR for a Compilers course, and working on a windows box. Getting ANTLR to work is not difficult since it is just a Java jar file. The quick start instructions on the ANTLR website seem really straightforward, and they probably are if you know what you are doing. However, I had a bit of trouble getting the handy antlr4 and gruncommands to work properly in my environment. This is likely due to my Unix/Linux background and because I am not used to messing with environment variables and batch files on windows. Adding things to the PATH and creating bash aliases in Linux is a piece of cake. This is a bit trickier on Windows so I figured I would make a short tutorial to help anyone else who does not know what they are doing like me.

Download Antlr

You can get the latest ANTLR from here. Save this file to C:\Javalib


CLASSPATH is an environmental variable. In order to set an environmental variable in Windows you will need to do the following.

  1. Open Up File Explorer
  2. Right Click on This PC
  3. Select Properties
  4. On the left hand side of the new window select Advanced system settings
  5. On the bottom of this screen select Environment Variables…
  6. This is a new computer with no CLASSPATH variable so I had to add a new one. If you have used other Java Libraries it is possible that you may already have CLASSPATH defined. If you see CLASSPATH under System Variables append it with C:\Javalib\antlr-4.5.3-complete.jar; If you do not have a CLASSPATH variable defined, select **New…* and then enter CLASSPATH for the Variable Name, andC:\Javalib\antlr-4.5.3-complete.jar for the Variable value.

Create batch commands for ANTLR Tool and TestRig

In order to make ANTLR easier to run from the command line we will need to add two simple batch files somewhere in the PATH. I decided to put these in C:\Javalib in order to keep them organized and together. C:\Javalib is not in the PATH by default so we must append the existing PATH variable just like we did in the previous step.

  1. Open Up File Explorer
  2. Right Click on This PC
  3. Select Properties
  4. On the left hand side of the new window select Advanced system settings
  5. On the bottom of this screen select Environment Variables…
  6. Find the PATH variable
  7. Append ;C:\Javalib\; to the existing PATH variable

Now we need to create the batch files.

  1. Create a new file in C:\Javalib called antlr4.bat
  2. In this file enter java org.antlr.v4.Tool %*
  3. Save this file
  4. Create a new file in C:\Javalib called grun.bat
  5. In this file enter java org.antlr.v4.runtime.misc.TestRig %*
  6. Save this file

This will now allow us to enter antrl4 and grun into a command prompt and launch ANTLR or the Testing Suite respectively.

Make Sure Everything Works

To make sure that all of this worked;

  1. Open up a Command Prompt or Powershell
  2. Enter the command antlr4
  3. You should see something like this:
Output of antlr4 command

Output of antlr4 command

  1. Enter the command grun
  2. You should see somethign like this:
Output of grun command

Output of grun command

Congrats, you are ready to hack on compilers now. Next, check out The Definitive ANTLR Reference book to learn everything there is to know about ANTLR.

Posted in programming | 2 Comments

Salting your LXC Container Fleet

Saltstack is an awesome configuration management system that can make managing 10 to 10,000 servers very simple. Salt can be used to deploy, manage, configure, report around, and even troubleshoot all of your servers. It can also be used to manage a fleet of LXC containers which we will be doing in this blog post. If you have been reading this blog, you know that I love Linux Containers. I am using them for pretty much anything these days. Salt is a great way to keep track of and manage all of these containers. On my main server, I have three containers that are running various applications. In order to update the packages on these containers I would have to log into each one, and run apt-get update and apt-get upgrade. This is not so bad for three containers, but you can imagine how annoying and cumbersome this gets as your container lists grows. This is where salt comes to the rescue, with salt I can update all of these containers with a single command. The official Salt Walkthrough is a great place to start to learn about how Salt works. This short post will show you how to set up a small salt configuration on a single server that is hosting several containers. All of my containers are pretty boring because they run Ubuntu 14.04. The best part about salt is that it is really OS agnostic and can manage a diverse fleet of different versions and types of operating systems. For this post, my host and all of my LXC containers are running Ubuntu 14.04 LTS Salt works by having a master that manages a bunch of minions. Setting up salt master is a breeze. For the purpose of this blog post, we refer to the master as being your host server and the minions as being your LXC containers.

Setting up Salt Master

On your host server you will need to install salt master. First we will need to add the saltstack repo to our repository list:

sudo add-apt-repository ppa:saltstack/salt

Next we will install the salt-master:

sudo apt-get update 
sudo apt-get install salt-master

Once the Salt Master is installed it will start running right away. By default it will run on port 4505 and 4506. You can verify this by running netstat -plntu | grep python to see which port(s) it is currently running on.

Setting up your Firewall

One thing I ran into during the installation was getting the firewall working. This is all running on a Linode, and I used Linode’s Securing Your Server guide to set up my firewall. If you have a similar setup you can add the following lines to /etc/iptables.firewall.rules to allow the minions to communicate with the master.

# Allow Minions from these networks 
-I INPUT -s -p tcp -m multiport --dports 4505,4506 -j ACCEPT  

# Allow Salt to communicate with Master on the loopback interface 
-A INPUT -i lo -p tcp -m multiport --dports 4505,4506 -j ACCEPT  

# Reject everything else 
-A INPUT -p tcp -m multiport --dports 4505,4506 -j REJECT

LXC gives you a nice “Management Network” where the containers can communicate with the host using private IP addresses. The easiest way to set this up is to allow the entire range (which above is ) of this network through the firewall. For security purposes I am rejecting all other IP addresses. Once you have configured your firewall you will want to load the new firewall settings to enable them.

sudo iptables-restore < /etc/iptables.firewall.rules

Setting up your Minions

Once your master is set up, running, and allows minions through the firewall we can set up the minions. Since LXC is a pretty barebones system we will need to install a couple of prerequisites first to get everything working. First we want to log into our container. I usually run the containers in a screen session so it would look something like this.

screen -dRR container1 lxc-attach -n container1

Once we are inside of our container, intall the following things:

sudo apt-get install software-properties-common  
sudo add-apt-repository ppa:saltstack/salt  
sudo apt-get update  
sudo apt-get install salt-minion

Now our minion is installed! It will need to know where to find the master. In our case we are running everything on the management network. The easiest way to get it to find the master is to add the IP address of the master to our /etc/hosts configuration. If you are not sure what the IP address of the master is you can run ip a | grep ineton the master and look for the IP address that starts with a 10.

vim /etc/hosts  # Now add the master IP    salt

To start it up, we will simply run:

/etc/init.d/salt-minion start

Before the minion is able to communicate with the master its key must be accepted. Back on the salt-master you will need to run salt-key -Ain order to accept the key from your minion. You should see the name of your container pop up and you will want to say ‘Y’ to accept its key. You can test to see that everything is working by running:

salt '*'

Your output should look something like this:

hci:     True git:     True usel:     True

That’s it! This may seem like a bit of work, but it is totally worth it because now every time we need to do anything on these containers we will simply use salt instead of having to log into each one. You can simple repeat these steps for each additional containers until you have an entire fleet of salted minions.

Posted in linux | Leave a comment

Programming Sockets in Python

EDIT: I am sorry for derping out of control. When I initially published this post it was called “Programming Web Sockets in Python”, this is just flat out wrong. What we are making here is just a regular socket. Web Sockets and regular sockets are similar but are certainly not the same thing. I hope you will still find this useful! Sockets are pretty much the basis of how applications work on the Internet. Python makes it super easy to get started programming sockets. In this brief introduction we will create a simple server that greets the user when it receives incoming requests from the client application. Due to my recent obsession with Linux Containers we will also be implementing this inside of two containers. Containers make it really simple to simulate a network because you can create additional hosts in seconds.

Creating your Containers

I am running Ubuntu 14.04. So creating two additional containers can be achieved by running the following as the root user.

lxc-create -t download -n pyServer 

# Choose ubuntu, trusty, amd64 when prompted 
# Then clone the first container 

lxc-clone -o pyServer -n pyClient

Running the Server

Now that we have created our containers lets jump into our server container and fire up our simple server application. We can start up the container by issuing the following command as root: lxc-start -n pyServer -d, this will start the container as a daemon. Let’s go ahead and get into by attaching the container. I like to do this inside of screen so that we can easily get in and out of the container. Create a screen session screen -dRR pyServer and once inside the screen attach the container lxc-attach -n pyServer Once we are inside the container we need to install python and launch our simple server.

apt-get install python vim

Inside of vim (or your favorite text editor) we need to enter the following simple python code.

from socket import *  

serverPort = 12000  
serverSocket = socket(AF_INET, SOCK_DGRAM)  
serverSocket.bind(('', serverPort))  
print "The server is ready to rock and roll!"  

while 1:     
    name, clientAddress = serverSocket.recvfrom(2048)     
    response = "Hello " + str(name) + "! You are really good at socket programming"     
    serverSocket.sendto(response, clientAddress)

The code should be pretty straightforward. We are creating a new serverSocket that is bound to port 12000. When it receives requests (which include a name) it responds with an encouraging message. Fire up this server by running python if all goes well you should see a message that states This server is ready to rock and roll! Exit the container (and the screen session) by pressing Ctrl+a and Ctrl+d

Running the Client

Now that we have our server up and running, lets get our client working as well. Before we move forward, lets grab the IP address of our server container because we will need it soon. You can get the IP by runninglxc-ls --fancy. Launch the client container, attach it in screen, and install python in the same way that we did previously.

lxc-start -n pyClient -d screen -dRR pyClient 
lxc-attach -n pyClient 
apt-get install python 

In vim, lets create the program by entering the following code.

from socket import *  

# Replace the IP address in serverName with the IP of your container that you grabbed previously. 

serverName = '' 
serverPort = 12000 
clientSocket = socket(AF_INET, SOCK_DGRAM)  
name = raw_input('Please enter your name:')  
clientSocket.sendto(name, (serverName, serverPort)) 

response, serverAddress = clientSocket.recvfrom(2048) 
print response 

This code is also pretty straightforward. It asks the user for their name, sends it to the server, and prints the response. You can try this out now! Save the file and execute your python program by runningpython After entering your name and pressing enter you should see a response from your server with the encouraging message. This was a pretty trivial exercise, but we can quickly see that we can expand upon this basic code to create much more interesting and complex applications. We can also leverage the power and simplicity of LXC to create a simulated large network for distributed applications.

Posted in programming | Leave a comment

Proxy Everything into a Linux Container with nginx

I previously wrote about setting up Node.js + Ghost in an Ubuntu LXC container and using Apache to proxy all web requests into that container. This works pretty well for the most part, but it seems like nginx is much better tool for this since it was pretty much designed to be a proxy server. We have a server that we are using for all Bit-Monkeys projects and I recently set up gitlab, along with a development site for openfaqs inside of LXC containers. The main benefit of this approach is that you can isolate the environments, manage upgrades and updates of various pieces separately, and fix issues in one environment without bringing down your entire infrastructure. Setting this up to work with nginx is super easy. First you will need to grab the IP address of your container which you can easily get by running as the root user

lxc-ls --fancy

Once you have the IP address of the container, you will need to install nginx. We are running Ubuntu 14.04 so it is as simple as apt-get install nginx. The last step is to create a virtual host config file for your container.

vim /etc/nginx/sites-available/yoursite

The contents of this file should look something like this:

server {  

listen 80;  
location / {  
  proxy_set_header Host $host;  
  proxy_set_header X-Real-IP $remote_addr;  
  proxy_set_header X-Forwarded-for $remote_addr;  
  port_in_redirect off;  
  proxy_redirect /;  
  proxy_connect_timeout 300;  

First you should replace the server_name directive with the name of your site. Next you will want to replace the IP address in the proxy_pass and proxy_redirect arguments to the IP address of your container. We are running Flask which is why it is routing to port 5000, you should replace the port with whatever port your application is running on. After this has been completed you should make a symbolic link to the /sites-enabled directory and restart nginx.

ln -s /etc/nginx/sites-available/yoursite /etc/nginx/sites-enabled/yoursite  

service nginx restart

If all goes well, you will now be able to enter the name of your site in the browser and be served with whatever content or application is running inside of your container. This is a really great use case for container in my opinion, and nginx makes it easier than ever to get started. UPDATE: You can just as easily add a server block for 443 to proxy all HTTPS requests into the container as well. (Thanks tostmiller via reddit for the question.) Sweet, now that you have mastered nginx proxies with LXC, check out the the complete guide to nginx high performance.

Posted in linux | Leave a comment