Learning Docker - Dockerfile

Sysadmin job is no fun unless you can automate boring and repetitive tasks. All the commands we have learned so far could be automated by putting all the commands in a Dockerfile and we can use docker build command to automatically build a container.

  • Create a Dockerfile:

    1
    2
    3
    $ mkdir nginx
    cd nginx
    vim Dockerfile
  • Populate Dockerfile:

1
2
3
4
5
6
7
8
9
FROM ubuntu:16.10
MAINTAINER Ashok Gelal
RUN apt-get update && apt-get install -y nginx \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \
&& echo "daemon off;" >> /etc/nginx/nginx.conf
CMD ["nginx"]
  • Build a container from a Dockerfile:
1
docker build -t ashokgelal/nginx:0.1.0 .
1
2
3
4
5
6
docker build -f ./Dockerfile -t ashokgelal/nginx:0.1.0 ./build
# This just builds a new image, names it and tags as 0.1.0
# build => build from a Dockerfile
# -f ./Dockerfile => set the Dockerfile if it is named other than Dockerfile
# -t => tag the resulting image. We can use -t flag multiple times
# ./build => This is the "context directory"

Every command/ directive we put in the Dockerfile adds a new layer into the container adding extra space and cruft. So, it’s important to add as much data as we can into each directive, such as RUN.

Learning Docker - Everyday Use

With Docker, not only you can spin-off your own containers from a base image, but you can create your own image with some custom libraries installed. It sort of works like git.

  • After installing nginx, diff your container:
1
2
$ docker diff container_id
# see differences
  • Commit the changes
1
2
3
$ docker commit -a "Ashok Gelal" -m "Install nginx" container_name ashokgelal/nginx:0.1.0
# After this, a new image ashokgelal/nginx will be available as a base image
$ docker images
  • Run nginx from our own base image
1
$ docker run -it -p 89:80 -v $(pwd):/var/www/html ashokgelal/nginx:0.1.0 nginx

The above method runs nginx but because it is running as a daemon, Docker kills the container thinking there is nothing running. To avoid that, one thing we can do is to make nginx not run as a daemon:

1
2
3
4
5
6
7
$ docker run -it -p 89:80 -v $(pwd):/var/www/html ashokgelal/nginx:0.1.0 nginx
c$ echo 'daemon off;' >> /etc/nginx/nginx.conf
c$ exit
$ docker commit -a "Ashok Gelal" -m "Nginx runs in a non-daemon mode" container_id ashokgelal/nginx:0.2.0
# create a new image with the latest changes
$ docker run -it -p 89:80 -v $(pwd):/var/www/html ashokgelal/nginx:0.1.0 nginx

Just like git, we can check the history of an image as well:

1
$ docker history ashokgelal/nginx:0.1.0

Using toastr with Laravel Mix

I use toastr for showing alerts in my web apps. Before it was as easy as adding a script tag and a link tag from CDNJS. But with Webpack and Laravel 5.4, this no longer works. Not just toastr, I’ve found that, at least in my experience, any libraries that depend on jQuery has the same issue. The only way I could make it work is through npm. It’s a bit pain to npm every package, to be honest. …

Using Browsersync with Laravel Mix

[Update: Laravel Mix now supports Browsersync out-of-the-box.]

Laravel Mix is basically a wrapper around Webpack and even comes with few scripts out-of-the-box. This is great and I like it a lot, esp. Hot Module Replacement part. But this also means we can no longer use old Laravel Elixir plugins. The one plugin that I really missed was the Browsersync support.

At first, I thought I’d fine without it but as soon as I started working on a real project, I realized that the lack of auto-refreshing of browser made me less productive. After spending hours trying different things to make Browsersync work, I finally got it working! Turns out it is actually very easy. Here are the steps: …

Automatically setting color scheme for .leaf files in Xcode

Unlike AppCode, Xcode doesn’t allow you to associate a custom file extension with a color scheme. When using Vapor and Leaf, this means you have to go to Editor > Syntax Coloring and select HTML every time you open a .leaf file. This is annoying and to make things worse Xcode doesn’t remember this setting after you (re)build the project 😡

To fix this annoyance, I’ve made a very tiny MacOS app that automatically associates .leaf to .html file for you. All you have to download this tiny app, and double-click it. You can then close the app. No further action required! You can now open your .leaf file and Xcode will recognize it as an HTML file and automatically sets syntax coloring for you.

Download the app here: https://github.com/ashokgelal/xcode-leaf-color-schemer/releases

The source is open and on GitHub: https://github.com/ashokgelal/xcode-leaf-color-schemer

Mixing Laravel Mix with Vapor

Trying a different framework after using Laravel is anything but easy. And as I was expecting, it didn’t take me too long to realize this. Laravel is not only a solid, well-written, and well-documented framework but it also brings with it a handful of essential packages such as Cashier, Socialite, Echo, Dusk etc. These packages are officially supported and make your day to day job as a web developer much enjoyable and very productive.

The first thing I missed right away using Vapor was the lack of a good front end build tool for compiling assets such as JavaScripts and CSS. I’m sure there exists one but I didn’t find any “officially promoted” one and nothing as good as Laravel Elixir, or it’s next version - Laravel Mix.

Yes, I know there are many build tools such as Gulp, Webpack, Grunt, Rollup etc. But, for better or worse, Laravel has spoiled me. I want to be more productive writing actual code and not spent hours fiddling with configurations.

Thankfully, Laravel Mix, despite its name, seems to work well with any other kind of frameworks including Vapor. There are few Laravel specific features such as the need for a function called mix if you need versioning but nothing that should block us from using it in our own Vapor project. In this post, I’ll show you how to integrate Laravel Mix in your own Vapor project. …

Opening a new copy of an app on MacOS

Mac doesn’t like you to open multiple copies of an application. If you try to open a new copy, it will switch to the running copy. If you want to open a new copy, this is what you need to do from your terminal: …