Os X Install Data Is Incomplete Essential System Software

Testing for Vulnerability #2 (Added 9/26/2014) If you pass the first test, use the following test to see if you're vulnerable from the second attack vector, which was discovered on Thursday. • env X='(){(a)=>' bash -c 'echo date'; cat echo; rm -f echo The Good Result If your system is fine, you'll see something like the following (without any printout of the current date and time). Date cat: echo: No such file or directory The Bad Result If your system is indeed vulnerable to the second attack vector, you'll see the following instead. Testing for Vulnerability #3/4 (Added 9/29/2014) There are no tests yet to check for these new vulnerabilities. Just follow the instructions below to update again and you should be in the clear. Is There an Update Yet?

Many Linux distros have already released patches for Shellshock (though they were mostly ), but Mac OS X has not received anything yet, and Apple hasn't even commented on the issue. There was a for Mavericks, but it has nothing pertaining to this issue. If you're worried, though, there is a way to manually update your GNU bash version to a more secure one, thanks to. Check Your Current Bash Version To see what version bash you have installed on your Mac, in a Terminal window, enter the following command (followed by the Enter key) into the shell. • bash --version If you get GNU bash, version 3.2.51(1)-release, then you'll want to manually update to the newest version of bash 3.2, which is 3.2.57.

Sep 04, 2011 If you’re a Mac user that requires the usage of Internet Explorer under Mac OS X, you’ll find your choices are generally as follows: run IE on top of. We're developing a dynamic team of qualified consultants, providing expert technical and analytical services for the data processing community — including software development, systems design and programming, educational training and management consulting — in the Michigan and Minneapolis areas.

Also, if you've already used this guide to update to 3.2.52(1)-release or 3.2.53(1)-release, then you'll want to perform everything below again to make sure you're fully protected. There are newer versions of bash out there, but Mac OS X runs off the 3.2 branch. If you're using Linux, you'll want to make sure the patch you download matches the version of bash you're using.

The latest patches for all major versions of bash (including 3.0, 3.1, 3.2, 4.0, 4.1, 4.2, and 4.3) can be found. Manually Updating Bash - Initial Requirements You can manually compile the newest bash version (3.2.57) using the below instructions, but you have to have installed on your Mac for this to work.

If you don't have it, follow the instructions in the Prerequisite Check section below. If you don't want to update bash, there is, but it hasn't been tested fully, so I wouldn't recommend it. Prerequisite Check You'll need to make sure you have Xcode installed, and have agreed to Apple's terms. For older Macs, you'll also need to make sure you have all the command line tools. You can download Xcode for free from the. If you're on an older version of Mac OS X and Xcode isn't available for you in the Mac App Store, you can download older versions by searching for the proper version number after logging into Apple's developer portal with your Apple ID.

Os X Install Data Is Incomplete Essential System Software

If you're on Mac OS X 10.7 or 10.8, search for 'Xcode 4.6.3' in the Downloads for Apple Developers search box on the left side of the page. Once you've installed Xcode, launch it from your Applications folder and agree to Apple's license agreement (the initial launch may take a while).

Os X Install Data Is Incomplete Essential System Software

After that, you'll want to confirm that you have all of the command line tools. To do so, do the following: • With Xcode open, click the Xcode menu in your top menu bar.

• Click Preferences. • Click the Downloads tab. • Click Install next to the Command Line Tools in the list of downloads. Note: If you don't see 'Command Line Tools' in the downloads tab, then that means you've already got them and are ready to go! Once done, you have everything you need to patch your system. Step 1: Download & Compile the Patches Once you've confirmed you have Xcode installed, open Terminal again and enter the following commands.

Each bullet point is one command, so make sure you copy the full line in each bullet point (minus the bullet, of course). • mkdir bash-fix • cd bash-fix • curl tar zxf - • cd bash-92/bash-3.2 • for i in $(seq -f '%03g' 52 57);do curl patch -p0; done • cd.

• xcodebuild. If the date does print out again, first check your user home directory to see if a file called 'echo' was created when you ran the test the first time. If so, delete it and run the test again. If the date still prints out, chances are you missed part of the updated Step #1 above. Change Sd Card Serial Number. If you ever think you might of messed up a command, you can always start over by deleting your bash-fix folder and starting again from Step #1.

Also note that you can delete the bash-fix folder if you're all good, too, because it's just a temporary folder. For Homebrew or Macports Users If you use Homebrew or Macports, you can get over at StackExchange. Good news is nothing you did can't be reversed.

Sounds like super user permissions may have timed out mid-build and that screwed things up. You can start over by deleting your bash-fix folder (it'll be in your user account's home directory. You should be able to find that in finder) and then open a new terminal window and follow the instructions from the beginning, with just one change. Since some part of the build needs su permissions on your system, when you get to the xcodebuild command, type sudo xcodebuild instead and enter your password when prompted. If that doesn't work, let us know what version of OS X you're using, along with what you see when you type bash --version.

I'm not certain what's causing it to error out. You might try downloading the latest version of Xcode, but I'm not sure that'll work either. You may need to wait for Apple's official patch to come out. That said, in order for this exploit to affect you, you'd have to be running a service that accepts external connections (such as ssh, telnet, or a web server), or install an app that's malicious (or accepts external connections), so it's unlikely a Mac used at home for say, browsing the web and checking email, will be targeted.

If you do run any servers, killing them for now would be prudent, but otherwise, just don't install any new apps you're not sure you can trust for the time being. As this is a very high profile bug, I suspect Apple will release an official patch soon. I had the same error. If I am not too tired and I am looking at this correctly, my problem was due to the fact that I installed an SSD in my optical drive bay and setup as my main drive (original internal HDD) as a secondary drive.

After installation, I moved all of my non-essential OS folders to the secondary drive and updated the links in the OS to point to the SSD when appropriate and the HDD when appropriate. The build would not compile correctly because the folders were being made in my user folder on the secondary drive while the 'cd.' Was going to the root for the SSD drive — at least this is far as I can surmise. Here is what I changed to get it to work: cd /Users/Shared mkdir bash-fix cd /Users/Shared/bash-fix curl tar zxf - cd /Users/Shared/bash-fix/bash-92/bash-3.2 curl patch -p0 cd. Xcodebuild That worked with no errors for my personal Mac at home after not working the first three times. My Mac at the office, which has the original build as far as drives, worked with the suggested commands in the article. Hope that helps.

The first download from opensource.apple wouldn't work, so i did the download via http, then did a mv to the bash-fix directory. When i run the second curl command from gnu.org the process stops and asks for 'File to patch:'% Total% Received% Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 3250 100 3250 0 0 3636 0 --:--:-- --:--:-- --:--:-- 3639 can't find file to patch at input line 20 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- BASH PATCH REPORT ================= Bash-Release: 3.2 Patch-ID: bash32-052 Bug-Reported-by: Stephane Chazelas Bug-Reference-ID: Bug-Reference-URL: Bug-Description: Under certain circumstances, bash will execute user code while processing the environment for exported function definitions. Patch (apply with `patch -p0'): *./bash-3.2.51/builtins/common.h 2006-03-06 09:00000 -0500 --- builtins/common.h 2014-09-16 19:00000 -0400 -------------------------- File to patch: I've already done the cp of my existing bash directories. Running 10.9.5 thanks in advance Reply.

You can download the files manually (that's all curl does), but you'll have to do the untar and patch commands separately. Should go something like this: • Download the bash-92.tar.gz file manually (using a web browser) and save it to your bash-fix folder.

• untar it with the following command: tar -zxf bash-92.tar.gz • move into that directory: cd bash-92/bash-3.2 • Download the bash32-052 patch file manually and save it to the bash-3.2 folder • Patch it with the following command: cat bash32-052.txt patch -p0 • Follow the rest of the steps above starting with cd. Did you already try getting it from the Mac App Store? For older versions of OS X, you should be able to install an older version of Xcode from an older Mac Recovery DVD as Justin noted above. That said, I can't remember if 10.8 even came with a recovery disc.

Hopefully you have one lying around somewhere from an older version of OS X (10.7 maybe?). If not, downloading Xcode from anyone other than apple is risky business. Riskier I think than leaving it unpatched for now (assuming it's not set up as a web server of sorts). Maybe best for you to keep any servers off on that system until Apple releases an official patch.

I got a hold of an older mac to test and figured out the problem some of you are running into. For those of you running into ** BUILD FAILED ** errors after typing the xcodebuild command, you're likely missing some of the dependencies. Even if you don't understand what that means, it's easy to fix. Just install them by doing the following: • Launch Xcode from your Applications folder • Click the Xcode menu in your top menu bar • Click Preferences • Click the Downloads tab • Click Install next to the Command Line Tools in the list of downloads. Once installed, quit your terminal window, delete the bash-fix folder from your user home folder, and start again from the beginning.

I've updated the article to reflect this. I left my experience above, copied here, Thanks for the post, I signed up too. I downloaded Xcode, opened it no problem, did all the steps above and updated my bash, then reset the default But I still get 'vulnerable' this i a test.

I also closed terminal rechecked the version, which is correct, and still the test says vulnerable. Edit: I ran the sudo commands to make sure about the default, this time I got request for password so I thought, great! Still vulnerable. Mavericks 10.9.5 Wondering even though it shows the newest version and it stills says vulnerable if I can simply go back through the whole process exactly the same way or if I should do some stop gap measure. Have yet to try on my snow leopard Imac Reply. That error will not effect the fix included here, but I found I could remove it (the error!) if I added the following BSD.xcconfig file in the path specified:- RCHS = $(ARCHS_STANDARD_32_64_BIT); CODE_SIGN_IDENTITY = -; CURRENT_PROJECT_VERSION = $(RC_ProjectSourceVersion); DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = dwarf-with-dsym; PREBINDING = NO; // Current Mac OS SDKROOT =; //USE_HEADERMAP = NO; VERSION_INFO_PREFIX = _; VERSIONING_SYSTEM = apple-generic; In Terminal you will first need to create the Xcode folder:- ie.

$ sudo mkdir /Applications/Xcode.app/Contents/Developer/Makefiles/CoreOS/Xcode/ Then create BSD.xcconfig as above with vi or nano or whatever, then finally change its permissions $ sudo chmod 644 /Applications/Xcode.app/Contents/Developer/Makefiles/CoreOS/Xcode/BSD.xcconfig Reply. Important note to all who have installed patch 3.2.52!!! There is a new patch out (3.2.53) that addresses an additional attack vector left open in 3.2.52. An additional step has been added to the instructions in this article to fix it. If you already ran this patch, all you have to do is delete your bash-fix folder from your user directory and follow the instructions from step 1. Many of them are the same, but the order you do them in is very important, so it's best to just copy / paste each command one at a time. Well, this is odd.

On my system (10.8.5), after installing the first-level patch:% bash --version GNU bash, version 3.2.52(1)-release (x86 64-apple-darwin12) Copyright (C) 2007 Free Software Foundation, Inc.% env X='(){(a)=>' bash -c 'echo date'; cat echo; rm -f echo date cat: echo: No such file or directory So even though I haven't yet installed the second-level patch, my 3.2.52 install of bash doesn't appear to be vulnerable per the second test (which I copy-pasted straight out of the article). How can that be? I'm working on Leopard 10.5.8, installed Xcode in order to manually update the bash, but ran into the problem that apparently for the version of Xcode compatible with 10.5.8 (I have 3.0 now, and apparently it goes up to 3.1.4) there is no 'downloads' tab and apparently no way to download the 'Command Line Tools'. I thought that maybe they were packed up inside of Xcode by default so I was like 'hey lets try it anyway'. First off the bash build doesn't download, returns with an error for some reason. Something about SSL encryption not recognizing a certificate.

Said 'off with that' and just downloaded and put the bash-92 folder into bash-fix. Then this happened. I'm on an older machine running OS 10.6.8 with Xcode v 3.0. The procedure fails for me at line 3 of step 1 with the following error: bash-fix norman$ curl tar zxf tar: Option f requires an argument Usage: List: tar -tf Extract: tar -xf Create: tar -cf filenames.

Help: tar --help% Total% Received% Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 4088k 0 16384 0 0 43020 0 0:01:37 --:--:-- 0:01:37 134k curl: (23) Failed writing body (0!= 16384) I don't know what any of this means. I can put that url in Safari which downloads 2 files: bash-92.tar M202.0 M2.1.6.04ZAV.D7210.rar I have dragged them into the bash-fix folder. Now what do I do?

A second possible problem: My version of Xcode does not have a Downloads preference. Update: Well I read further down in the instructions and manually ran tar. The file in my directory did not have the.gz extension, so I just omitted it thus: tar -zxf bash-92.tar That worked and resulted in the creation of the bash-92/bash-3.2 directory. However when I did: cd bash-92/bash-3.2 for i in $(seq -f '%03g' 52 54);do curl patch -p0; done I got: -bash: seq: command not found So I guess I'm missing the command line tool, 'seq' This appears to be the same problem Alex is having. The purpose of the `seq ` command in this case is to easily loop through all the patch file names (052 053 054) in a single curl command. I don't know when this command became available for OS X, but it certainly isn't on my fully patched Leopard system. Just issue the following command instead of the original `for; done` command: curl patch -p0 Then repeat that command with 053 instead of 052, and 054 instead of 053.

You must do them in the proper order! If there become further patches for bash 3.2 I'd presume they would be numbered 055, etc. Alex, to override the SSL issue you're getting with the `curl` command you need to include the '-k' just after the word 'curl', not at the end of the command line.

Angela Anaconda Theme Song Download on this page. So like this: curl -k Personally, I did not have any SSL certificate issue getting the patches themselves — just when pulling the base bash kit from Apple's servers. Obviously you are getting an error, so something must be different on your system (older certificate authority info in your keychain, older version of OS X, not the same OS X security patches, etc.).

I wouldn't worry about it as long as you can obtain the patches successfully using the '-k' option and you use these 'trusted' source code/patch domains. With regard to your `xcode-select —install` issue, it would be mildly interesting to know what this command shows: xcode-select -print-path For me, it shows '/Developer'. Based on the output you showed in your second screenshot, it appears that the version of xcode-select you have on your system didn't understand what '—install' means as an option. Can you tell us which version of OS X you are trying this on, and what the version of Xcode is (launch the Xcode application, then choose the 'About Xcode' option from the Xcode menu)? Hi, Ok, just checked, so first off, my version of OSX is Leopard 10.5.8 (9L31a) with the Darwin 9.8.0 kernel (according to the System Profiler).

My version of Xcode is 3.0. The -k thing before curl did work, I was able to download all the files directly from the Terminal. The -seq workaround worked as well, and I was able to download the patches directly from the Terminal too. However the build still failed. I tried a second time by redownloading all the files, starting fresh and following all the steps again, using curl -k to download patches 052 to 054, same thing, *build failed*. If you want I can paste the whole text that appears after the 'xcodebuild' line if that helps.

Is it a problem with the Xcode version that's too old? I've checked on wikipedia and the highest version of Xcode that will work on Leopard 10.5.8 is Xcode version 3.1.4. I have an Apple developer account so I can download it if necessary but my question is: should I upload and will it change anything? Edit: oh yes 'xcode-select -print-path' shows up '/Developer' as well. I didn't change the default install setup and it offered to put Xcode and its files there so I did not bother to change it.

I'm glad my curl suggestion got you further along. Unless your xcodebuild sequence fails very early on, I'm afraid that your entire log of that step could be quite large (and thus hard to go through). Perhaps you can determine from looking at the output before the build failed is reported you can see just above that a starting point of the output where things were going well, then turned bad—from that point to the end might be useful. As to Xcode 3.0, I cannot say if that is too old or not. My Leopard system has 3.1.1 and everything worked. Since you have ready access to the developer portal I'd say it cannot hurt to download the latest you can find there (that works on Leopard of course) and give it a shot.

What's a little download bandwidth and time among friends?;) I suppose it's possible that your /Developer path is corrupt or incomplete in some way and and upgrading Xcode might not catch that. If that's true you may need to (backup and then) remove the current /Developer contents so that a fresh Xcode download and installation will put everything right. Well, I've made progress: bash-3.2 norman$ man seq No manual entry for seq This confirms that the 'seq' command is not on my system. Norman, Your version of Xcode is very out-of-date for Snow Leopard. Even my old Leopard system has version 3.1.1.

Looking at Apple's developer portal, the latest Xcode for SL is 3.2.6. Since you have Xcode already installed, I'd be surprised if using the Software Update menu choice from your Apple menu wouldn't find and install that upgrade for you. Then you can try picking up in the bash fix instructions where you left things. You can signup as an Apple developer without paying anything (their paid account provides additional developer access and tools) and download 'Xcode 3.2.6 and iOS SDK 4.3 for Snow Leopard' from there so that route is available to you as well. Because of licensing, if you cannot upgrade Xcode via Software Update or download it from the Apple developer portal it wouldn't be legal for anyone else to provide Xcode to you.

Hopefully Software Update will be your friend! Since Xcode tends to require you to agree to its Terms & Conditions with every release, no matter how you get an updated Xcode be sure and launch the application before trying to use its command-line tools. I'm afraid I have dug myself a deeper hole.

Today I thought of the 3 other machines in my house, all running Mavericks on all of which I have applied the Apple patch. So I backed up bash and sh on this old machine, as described above, then copied the versions of them on one of my Mavericks machines to to.bin/ on this old machine. Unfortunately that broke everything. Launching Terminal yields: Last login: Wed Oct 1 13:51:47 on ttys000 Process completed so the terminal session shuts down completely. I tried to ssh to this machine from another on my LAN but that failed as well. I'm about try to use Finder to restore from backup.

This is hard because my backup is a disk image, and this machine can no longer mount disk images. Disk Utility spins the pinwheel of death. I guess they all rely on bash. Well, I can use the finder to open up /bin/ and I can move bash to the trash, but I don't have permissions to rename bash.old to bash.

Is there some way that I can get access to another shell on boot up? Both bash and sh are probably broken. I don't know which CVE(s) it may address, but there is now a patch 056 available dated October 2 at 22:15 (timezone unknown). If your bash-fix folder is untouched from all previous patching through patch 055, you can apply this new patch by using the following command ( be certain that you are in the same bash-3.2 folder as before!!!): curl patch -p0 Then carry on with the remainder of the original manual steps starting with the `cd.` command. I wouldn't be surprised if additional patches come out for this issue, so stay tuned.:) BTW, I really like for testing against these bash issues.

It seems to be maintained quickly and the results are in color to quickly give you a sense of your installed version of bash against the identified problems. I have a problem.

I'm running os X Tiger which only allows me to install xcode 2.5. Everything runs fine until I compile the code. I get: /Users/polarisdirect/bash-fix/bash-92/bash-3.2/lib/intl/dcigettext.c:302:36: warning: character constant too long for its type /Users/polarisdirect/bash-fix/bash-92/bash-3.2/lib/intl/dcigettext.c:302: error: invalid initializer Does anyone have an idea? There is no download command line tools under preferences and the code stated above to install them didn't work.

In this post, I’m going to explain why installing, configuring, and maintaining software in development, testing, and production environments can be a complete nightmare. After that, I’m going to show you a better way to do it using. Finally, I’ll introduce a small open source project I created called, which makes it easier to setup a productive development environment with Docker on OS X. Motivation Let’s say you just started at a new company or you discovered a handy new open source library and you’re excited to get things running. You git clone the code, search for install instructions, and come up empty. You ask your co-workers where you can find, and they laugh.

“We’re agile, we don’t waste time on documentation.” Everyone remembers that setting things up the first time was painful—a hazing ritual for new hires—but no one really remembers all the steps, and besides, the code has changed and the process is probably different now anyway. Even if you do find documentation, it’s inaccurate, out of date, and incomplete. You copy some files here and there. You install a programming language or two. You run a random shell script. You fiddle with environment variables. Eventually, you figure out that you need a specific version of some library installed, and so off you go to upgrade OS X, or to figure out how to run Python 2 side-by-side with Python 3, or to add symlinks to ensure you’re using the proper version of Java, or to download the multi-gigabyte XCode installer (seriously, why is it so freaking huge?).

And, of course, some of the requirements from one project conflict with the requirements of another project. Before you know it, you’re spending hours reading about RVM and RBEnv so you can run multiple versions of Ruby, you’re fighting with strange errors with C header files, and you’re wondering what the F#@K is Nokogiri and why does it never install correctly? Eventually, you find yourself in an infinite loop of 1) try to run the code, 2) get an obscure error message, 3) Google it, 4) try random suggestions you find on StackOverflow, 5) go back to step 1. The last straw is when you find out you have to deal with Satan himself in the form of software from Oracle. Seriously, have you ever installed Oracle DB?

It’s a multi-day process that involves formatting half your hard drive, a drug induced trip into the Himalayas to find a rare blue Orchid, and a two day session where Oracle’s lawyers beat you with reams of legal documents. And why the F# does the Oracle Java updater try to install the MOTHERF&# Ask Toolbar? Installing and configuring software is the ultimate form of. The complexity of getting software running is responsible for: • Driving many people away from programming. Most people are not masochistic enough to deal with a user experience that is equal parts out-of-date documentation, XML configuration files, arcane error messages, and frantic, rage-driven Google searches. • Wasting a huge amount of time.

Not only do you have to go through this awful installation process in your development environment, but every other developer on your team does too. • A huge percentage of bugs.

Even if you get the software running in your development environment, getting it to work the same way in the testing and production environments is the same nightmare all over again. The probability of missing a step or something going out of sync is approximately 100%. There have been many attempts to automate this process, but they all have major drawbacks.

For example, you could create custom shell scripts and lots of documentation for how to setup your code, but this is always a nightmare to maintain, update, and test. You could use Configuration Management (CM) software, such as,, and, which make it easier to automate your testing and production environments, but they are fairly useless for setting up a development environment, and incur too much overhead and cost to use for a small open source or side project. Finally, you could package your code into Virtual Machine (VM) images, which will run the same way everywhere, but VM images incur a lot of performance overhead, which causes problems in the production environment, and they use a lot of resources and are slow to start, which causes problems in the development environment. Introducing Docker This is where comes in. Docker runs your code in a container, which is like a lightweight VM.

Whereas a full VM virtualizes all the hardware and the operating system, a container runs your code directly on the host operating system and hardware, but in an isolated userspace. This way, you get all the isolation and consistency benefits of a VM, but with very little overhead. Not all operating systems support isolated userspaces. Docker, in particular, relies on the Linux kernel and the (LXC) project. If you run your code on top of Linux in production, then Docker is for you.

The easiest way to understand Docker is to walk through an example. If you have Docker installed, the first thing you need to do is to pull a Docker image: >docker pull ubuntu A Docker image defines a set of files and some instructions for running them. In this case, the image we are using is of the. The pull command will download this image (which is about 188MB) and cache it on your computer so you won’t have to download it again. Public images are stored in the, which is a bit like GitHub: it’s a collection of open source Docker images (such as Ubuntu) that anyone can download using docker pull (like git pull) and anyone can contribute to using docker push (like git push).

Now that you have the image on your computer, you can use docker run to run it: >docker run ubuntu echo 'Hello, World' Hello, World What just happened? Well, the run command fired up the ubuntu image and told it to execute the command echo 'Hello, World'. That’s right, you’re firing up the entire Ubuntu operating system just to print “Hello, World” to the terminal. How long does it take?

You can use the time command to find out: >time docker run ubuntu echo 'Hello, World' Hello, World real 0m0.183s user 0m0.009s sys 0m0.014s 0.183 seconds! This is on my Apple laptop, which runs OS X.

On a high powered Linux desktop, it would be even faster. Whereas starting up an operating system in a VM is a big operation that can take minutes, in Docker, it’s a trivial operation that takes a fraction of a second. There is no trick here. It’s the real Ubuntu OS and it is completely isolated from my host OS.

For example, here is a quick screencast of firing up bash in an Ubuntu container and running a few commands. Docker containers start and stop so quickly, and are so lightweight, that you could easily run a dozen of them on your developer work station (e.g.

One for a front-end service, one for a back-end service, one for a database, and so on). But what makes Docker even more powerful is that a Docker image will run exactly the same way no matter where you run it. So once you’ve put in the time to make your code work in a Docker image on your local computer, you can ship that image to any other computer and you can be confident that your code will still work when it gets there. One of the easiest and most effective ways to create a Docker image is to write a. Instead of configuring your tech stack through manual steps and documentation, a Dockerfile allows you to define your. For example, here is a Dockerfile that defines a Ruby on Rails stack: FROM ubuntu:14.04 # Install Ruby and Rails dependencies RUN apt-get update && apt-get install -y ruby ruby-dev build-essential libxml2-dev libxslt1-dev zlib1g-dev libsqlite3-dev nodejs # Install Rails RUN gem install rails # Create a new Rails app under /src/my-app RUN mkdir -p /src && cd /src && rails new my-app WORKDIR /src/my-app # Default command is to run a rails server on port 3000 CMD ['rails', 'server', '--binding', '0.0.0.0', '--port', '3000'] EXPOSE 3000 Let’s go through this file line by line.

The FROM ubuntu:14.04 command says that this image will run on top of Ubuntu version 14.04. Next, there are several RUN commands which will execute code in this image. The first RUN command uses apt-get, the Ubuntu package manager, to install Ruby and a bunch of dependencies for Rails (notice how many dependencies there are just for a vanilla Rails app!). The next RUN command uses gem, the Ruby package manager, to install Rails itself. After that, a RUN command creates a /src folder, another one uses rails new to create a new Rails app called my-app, and the WORKDIR command sets /src/my-app as the working directory. Finally, the CMD command will execute rails server when you use docker run on this image and the EXPOSE command makes port 3000 visible to the host OS.

You can use the docker build command to turn this Dockerfile into a Docker image: >docker build -t brikis98/my-rails-app. Once the image is created, you can use the docker images command to see all the images on your computer: >docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE ubuntu 14.04 07f8e8c5e660 2 weeks ago 188.3 MB brikis98/my-rails-app latest 2ac5d95f10cc 4 hours ago 529.4 MB You can see the ubuntu image from earlier, as well as the new my-rails-app image from running docker build. You can use the docker run command to test this new image and you’ll see that it starts up the Rails server on port 3000. You can now test your Rails app by visiting (note: on OS X, the URL for testing will be different, as I’ll discuss later). One important thing to note is that the code for this Rails app, which was generated by the rails new command, is inside of the Docker container and therefore not visible on the host OS. But what if you wanted to checkout and edit the code in the host OS (e.g.

OS X) while still being able to run the code inside the Docker container? To do that, you can mount a folder using the -v flag in docker run: >docker run -v /foo:/bar brikis98/my-rails-app The command above will take the /foo folder in the host OS and make it available in the Docker container at /bar. This way, you can use all the text editors, IDEs, and other tools you already have installed to make changes in /foo and you’ll see them reflected immediately in the Docker container in /bar. Once you get your Docker image working locally, you can share it with others. You can run docker push to publish your Docker images to the public Docker registry or to a private registry within your company. Or better yet, you can check your Dockerfile into source control and let your continuous integration environment build, test, and push the images automatically.

Once the image is published, you can use the docker run command to run that image on any computer—such as another developer’s workstation or in test or in production—and you can be sure that app will work exactly the same way everywhere without anyone having to fuss around with dependencies or configuration. Many hosting providers have first class support for Docker, such as and. Once you start using Docker, it’s addictive. It’s liberating to be able to mess around with different Linux flavors, dependencies, libraries, and configurations, all without leaving your developer workstation in a messy state. You can quickly and easily switch from one Docker image to another (e.g. When switching from one project to another), throw an image away if it isn’t working, or use to work with multiple images at the same time (e.g.

Connect an image that contains a Rails app to another image that contains a MySQL database). And you can leverage the thousands of open source images in the Docker Public Registry. For example, instead of building the my-ruby-app image from scratch and trying to figure out exactly which combination of libraries make Rails happy, you could use the pre-built which is maintained and tested by the Docker community. Docker on OS X If you’re already using Linux as your desktop operating system, Docker is a no-brainer. Unfortunately, there are you might not want to use Linux on the desktop, and prefer OS X instead. If so, there is a problem: OS X is built on top of Unix, not Linux, so you can’t run Docker on it directly.

Instead, you have to run Linux in a VM (which is why on OS X, instead of using localhost in your URLs, you need to use the IP of the VM). But wasn’t the whole point of Docker to avoid heavyweight VMs?

This in and of itself isn’t actually as big of a problem as it sounds for three reasons: • You only need the VM in the development environment, so the performance overhead does not affect production. • You only need to run a single VM no matter how many Docker containers you want to run on top of it. You pay the penalty of starting this VM just once and you leave it running in the background.

You can then run as many docker containers as you want on top of this VM, with each container starting and stopping in a fraction of a second. • Thanks to the project, you can use a stripped down version of Linux specially tailored for Docker as your VM. It runs completely in RAM, takes up only 27MB, and boots up in about 5 seconds! In other words, Boot2Docker provides a great experience for using Docker on OS X.

Except for one thing: mounted folders. By default, the Boot2Docker VM image runs inside of, a free and open source hypervisor. VirtualBox is great, but the system it uses to mount folders, called vboxsf, is agonizingly slow. For example, here is how long it takes Jekyll to compile if I don’t use any mounted folders and just include the code directly inside the Docker image itself: >docker run -it brikis98/yevgeniy-brikman-homepage bash:/src# time bundle exec jekyll build [.] real 0m7.879s user 0m7.360s sys 0m0.600s And here is the exact same Docker image, but this time, I mount the source code from OS X: >docker run -it -v $(pwd):/src brikis98/yevgeniy-brikman-homepage bash:/src# time bundle exec jekyll build [.] real 1m14.701s user 0m9.450s sys 0m3.410s 7 seconds versus 74 seconds! And that’s on a small, simple Jekyll project. With more complicated projects, using vboxsf leads to a 10-20x slowdown in compilation speed, server startup time, and just about everything else. Another major problem with vboxsf is that it breaks file watchers.

Build systems like Jekyll, SBT, Grunt, and many others listen for file changes using OS-specific technologies such as inotify on Linux and FSEvents on OS X. That way, when you change a file, those build systems get a notification about the change immediately, and can recompile it quickly so you can rapidly iterate on your code using a make-a-change-and-refresh development cycle. Unfortunately, vboxsf breaks inotify and FSEvents, so those build systems never get notifications about file changes. Your only option is to enable polling, forcing the build systems to linearly scan through all files, which consumes a lot of resources and takes a lot longer to spot a change and recompile the code. In short, vboxsf is completely unusable for active development.

I spent a few days looking for a solution. I tried to follow advice in random and.

I tried many different technologies, including Vagrant, NFS, Unison, and Samba. I made a to ask for help. After lots of trial and error, I finally found something that works great on OSX and I’ve packaged it up as a small open source project called. Docker-osx-dev The best alternative I found to using vboxsf was to use, a common Unix utility that can can sync files quickly. With rsync, I found that build performance in my Docker containers with mounted folders was on par with running the build without mounted folders, and file watch mechanisms based on inotify all work correctly. I’ve been using for a couple weeks and have been very productive as I switch between three different projects with three totally different tech stacks. To use docker-osx-dev, you must first install.

After that, just download the docker-osx-dev script and run the install command: curl -o /usr/local/bin/docker-osx-dev chmod +x /usr/local/bin/docker-osx-dev docker-osx-dev install This will setup your entire Docker development environment, including Boot2Docker, so the only thing left to do is to kick off file syncing and start running your Docker containers: >cd /foo/bar >docker-osx-dev [INFO] Performing initial sync of paths: /foo/bar [INFO] Watching: /foo/bar By default, docker-osx-dev will sync the current folder ( /foo/bar in the example above) to the Boot2Docker VM. Alternatively, you can use the -s flag to specify which folders to sync: >docker-osx-dev -s /other/path [INFO] Performing initial sync of paths: /other/path [INFO] Watching: /other/path If you are using, the docker-osx-dev script will automatically sync any folders marked as in your docker-compose.yml file: >docker-osx-dev [INFO] Using sync paths from Docker Compose file at docker-compose.yml [INFO] Performing initial sync of paths: /foo/bar [INFO] Watching: /foo/bar Now, in a separate tab, you can start and stop as many docker containers as you want and mount the /foo/bar folder in them. This will happen automatically when you run docker-compose up.

Alternatively, you can specify folders to mount manually using the -v flag of docker run: >docker run -v /foo/bar:/src -p 3000:3000 brikis98/my-rails-app You can test this Rails app by going to in your browser, as docker-osx-dev automatically configures dockerhost as a URL for your docker VM. Also, with docker-osx-dev running, you can edit any of the files in mounted folders using the tools you’re used to in OS X, and the changes should propagate instantly into the Docker container using rsync.

Moreover, your builds should be fast and all file watchers should work normally. Conclusion I hope that in the future, more and more companies will package their tech stacks as Docker images so that the on-boarding process for new-hires will be reduced to a single docker run or docker-compose up command. Similarly, I hope that more and more open source projects will be packaged as Docker images so instead of a long series of install instructions in the README, you just use docker run, and have the code working in minutes. As an experiment, I’ve created Docker images for a few of my open source projects, including,, and, which you’re reading now. I also hope that some day, the issues with vboxsf will be fixed, but in the meantime, I’ll be using for all of my coding and encourage you to give it a try. The code is new and fairly rough, so feel free to give me feedback, file bugs, and send pull requests. Finally, if you want to learn how to take your Docker containers and run them in production, check out my follow-up blog posts, and.