Prefer reading to watching? You can read the script below…
You want to try out a programming language
Let's say we want to try out a new programming language.
We'll go to the Elixir site and see what it says about getting started…
Ugh! What computer am I running… I don't want to think about this!
But you don't want to modify your developer environment
And I don't want to change my computer just to try out a programming language! I have too many old versions of programming languages already!
The language ecosystem provides a docker container
Is there a less invasive way to try this out? Can I have Elixir over for dinner without putting it up in my guest room?!
I just want to run a computer with the thing already installed! Fortunately, there's a way to run computers in my computer! They stay within their boundaries, and they go away when I'm done with them.
It's called… Docker. Docker is like a manager of pretend miniature computers. Each pretend mini computer is called a “container”.
Oh look! The Elixir site lists a demo Docker image. That's just what I want. Because a Docker image is a definition of a starting point for a container.
The thing I like about clicking on this is that it doesn't matter what computer I'm running. I can use this on my Mac. I can use this on Windows. I can use this on Linux within Windows if I want to!
Assuming I have Docker installed. Which is not trivial, but from here we assume Docker is installed and running.
This is what that looks like on Windows.
Start by checking what containers are currently running
First, I'm going to see that I have no containers running right now.
I can do that at the command line with
These are some column headings… there are no rows. No containers are running. But! I can tell that Docker is running. Otherwise this command wouldn't work.
I want to run their container.
Back on the Elixir site… We find the name of the container image in the documentation. Looks like it's called simply, “elixir”.
I don't like typing command-line options that I don't know yet.
But I know I want docker to run a container using the “elixir” image.
> docker run elixir Unable to find image 'elixir:latest' locally latest: Pulling from library/elixir
Their container is on DockerHub
Oh look! It's pulling from “library/elixir”. That means it's somewhere docker knows about… usually hub.docker.com. In fact, while this is downloading…
…let's check that out. This is DockerHub.
Let's search for Elixir.
Oh yeah, there it is.
Docker Official images, indeed!
A lot of versions are available, latest is the default.
Back to our console, see that docker says it's looking for an image named
elixir at the tag
latest. The stuff after the colon is the name of the tag.
The container runs and exits
Oh look! It finished. Oh look! It ran the image. It gave us an interactive Elixir prompt! And then it exited! What?
> docker run elixir Unable to find image 'elixir:latest' locally latest: Pulling from library/elixir 844c33c7e6ea: Pull complete ada5d61ae65d: Pull complete f8427fdf4292: Pull complete f025bafc4ab8: Pull complete 7a9577c07934: Pull complete 73d44522986b: Pull complete 67e5d74f0783: Pull complete db286e90fbac: Pull complete 50d6ee204e45: Pull complete Digest: sha256:56e8f963b496caa7b72cd9d7dc24ba30876a3074df9418e09fee3608552462e1 Status: Downloaded newer image for elixir:latest Interactive Elixir (1.9.4) - press Ctrl+C to exit (type h() ENTER for help) iex(1)> >
Why did it exit?
-it means “interactive terminal”
This is why they told us to type
docker run -it. I think of that as standing for “interactive terminal”.
This is actually two flags,
-i for interactive and
-t for TTY. That's why there's only one dash in
> docker run -i -t
But we can pass them together as
And I have no idea why you would ever use them separately.
Then we supply the image name.
This time it doesn't have to re-download the image. It already has it. And, thanks to
-it, it doesn't exit!
> docker run -it elixir Erlang/OTP 22 [erts-10.6] [source] [64-bit] [smp:2:2] [ds:2:2:10] [async-threads:1] [hipe] Interactive Elixir (1.9.4) - press Ctrl+C to exit (type h() ENTER for help) iex(1)>
Play around inside the demo container!
Now we can play with the Elixir REPL!
What is Elixir for hello world? It is
iex(1)> IO.puts("Hello jessitron!") Hello, jessitron! :ok
List the running containers
This interactive Elixir prompt is running inside a pretend mini-computer, inside a container, inside Docker, on my laptop.
In another terminal, let's list the running containers again.
> docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES bce749acd511 elixir "iex" 5 minutes ago Up 5 minutes romantic_nash
Aha! We have a container.
It has an ID.
It comes from the
It's running the
It's been up for a few minutes.
And it has a silly name.
Docker makes up names for our containers if we don't specify one.
Shut down the demo container
OK, let's say we've played around with IEX enough, and we're done.
So we exit IEX with double control-C. (That's an IEX thing, not a Docker thing.)
Now we're out of the container, and back at our computer's prompt.
Let's check to see whether the container is still running.
> docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES C:\Users\jessi >
Docker ps says no… except … here's something to know about docker ps. By default, it shows running containers. But these are not all the containers.
Note that the image is still around
If we run with -a, it says, show me all the containers, including the stopped ones.
> docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES bce749acd511 elixir "iex" 12 minutes ago Exited (0) 3 minutes ago romantic_nash 5c46173929a5 elixir "iex" 41 minutes ago Exited (0) 41 minutes ago modest_mahavira
Here are two containers that have exited! There's the one we just exited, and also the one that we ran without -it so it exited itself.
Clean up by removing the image
We don't need these stopped containers lying around taking up space on the filesystem. To get rid of them,
with either the container ID
or its catchy name.
> docker rm 5c46173929a5 > docker rm romantic_nash
Now when we run
docker ps -a, the list of containers is really empty.
> docker ps -a ...
Starting with –rm cleans up automatically
It would be nice if Docker would clean up after itself, and we didn't have to do this. It can, but we have to pass it the do-things-right flag.
This is why the instructions said to run with
because that tells Docker to delete the container after it stops.
--rm has two dashes, because it is one command-line option.
rm is its long name, sadly.
docker run -it --rm elixir
Now when I run a container from the Elixir image, and then exit
There is no container lying around afterwards.
docker ps -a
Now the next time you want to try a programming language, or tool, or whatever, you know how to run a container from a provided Docker image. You know how to see what Docker containers are running, shut them down, and clean up after yourself.