Dockermen’s introduction to private docker hub with GitLab


Since end of May, thanks to the great efforts of the GitLab project developers, an open source authorization-layer for the docker-registry(v2) is available.
Within this article I´d like to introduce my collegues into the basic steps to work with docker and our new private docker-registry.

The so called docker-registry is like a git-repository for so called docker-images.

Enable the registry for your project

  1. Sign in to
  2. Go to your project: /namespace/projectname
  3. Click on Settings: /namespace/projectname/edit
  4. Under “Features” enable “Container registry” and save
  5. Go back to project and click on the new available “Container Registry

This is the page where you will see and manage your pushed images.
There is also a nice little help written.

Now your project-namespace is ready to use for pushing and pulling docker images.

Example of usage

On your command line:

  1. Create a docker image
  2. Name (tag) it to
  3. Login docker to our registry
  4. Push the image
  5. Now, others with project-access are able to pull it

Assuming you already have installed docker for your OS…:

…you should be able to execute the docker client on your command line.

Let´s start

Docker, as it is one big binary that is written in Golang, has different subcommands.

I will list some in a meaningful order:

docker ps # List all currently running processes (docker container)
docker images # List all images, which are the base for containers
docker run image/name # Start a container from an image

Containers are like linked clones to images. You can think of containers as running state and images as frozen state. They don´t alter the images, but are a new isolated layer upon them to make use of preinstalled software.
You can get images from, or build them locally e.g. to push later to our private registry.

A simple workflow

  1. Get an public available image from docker hub
  2. Run it locally for testing
  3. Adapt it
  4. Commit it and save it to a new image
  5. Rename the image for pushing to our registry
  6. Deleting locally and rerun/pull to verify all is as expected

I) We get this very small alternative to the official python image:

docker pull elyase/staticpython

II) For Windows you could try %CD% instead of $(pwd). Alternatively you can write the full path to the current directory. On Windows use this notation: /c/Users/

docker run -p 8000:8000 -v $(pwd):/src -w /src --rm -it elyase/staticpython sh -c 'python -m SimpleHTTPServer'


Don´t forget to check docker --help, docker subcommand --help

  • run – Subcommand to start an image
  • -p – Publish a port to the docker-host
  • -v – Mount a local directory, or a so called Volume within the container
  • -w – When starting the container use this as the working directory
  • --rm – After stoping the container, delete it. See docker ps -a for exited containers that might be used again, or just eat disk-space.
  • -it – Short for -i -t. Start an interactive terminal session
  • elyase/staticpython – The image to use
  • sh -c 'python -m SimpleHTTPServer' – All the rest is a command to run. Here we only start a little webserver

If you use docker-machine, get the docker-host-IP with docker-machine ls. Now you should be able to open a browser to see your current directory files:

Go to: http://docker-host-IP:8000
For me it´s:

Quit the Container with Ctrl-C.

III) Now we run the container again in detached mode, and run some commands inside. Note that we don’t use a shared Volume this time, as it could not be committed to an image. Also we name the container this time.

docker run -d --name charly -p 8000:8000 -w /src -it elyase/staticpython sh -c 'python -m SimpleHTTPServer' # We wrap the python command, because it didn´t respond to Ctrl-C in my tests

docker exec charly sh -c 'echo "We run webs" > index.html' # We have to wrap the command inside the sh command because of the redirection.

Now I can see the page on again.

We could do some work directly inside a shell session:

docker exec -it charly sh
/src # echo "Go on spider" >> index.html
/src # exit


docker commit -m "Some test" charly

You should see now the commit under docker images.
And could rename it later with docker tag.

Now use your GitLab credentials:

docker login

And push

docker push

You can manage the image on:

VI) As the container is still running locally and the just created image (commit) still exist, we now delete them.

docker kill charly
docker rm charly
docker rmi
docker images
docker ps


docker run --rm -it

Unable to find image '' locally
test: Pulling from namespace/project


Now we put all of this inside a build script. The so called Dockerfile.

Create two files


We run webs
Go on spider


FROM elyase/staticpython

COPY index.html /src/


CMD ["sh", "-c", "python -m SimpleHTTPServer"]
docker build -t .
docker tag


docker run -it --rm -p 8000:8000 --name charly



docker push


docker kill charly
docker rm charly
docker rmi
docker rmi
docker rmi
docker ps -a
docker images

There are buttons to delete the pushed images.


Docker push will loop to upload and finally give up on big layers.
This should be fixed in a next GitLab release: