346

I'm wondering where Docker's images are exactly stored to in my local host machine. Can I share my Docker-Image without using the Docker-Hub or a Dockerfile but the 'real' Docker-Image? And what is exactly happening when I 'push' my Docker-Image to Docker-Hub?

Altenrion
  • 764
  • 3
  • 14
  • 35
yaquawa
  • 6,690
  • 8
  • 35
  • 48
  • 5
    For future reference: a good article on [moving docker images around](https://blog.giantswarm.io/moving-docker-container-images-around/) – Mifeet Jul 01 '16 at 14:18

4 Answers4

314

Docker images are stored as filesystem layers. Every command in the Dockerfile creates a layer. You can also create layers by using docker commit from the command line after making some changes (via docker run probably).

These layers are stored by default under /var/lib/docker. While you could (theoretically) cherry pick files from there and install it in a different docker server, is probably a bad idea to play with the internal representation used by Docker.

When you push your image, these layers are sent to the registry (the docker hub registry, by default… unless you tag your image with another registry prefix) and stored there. When pulling, the layer id is used to check if you already have the layer locally or it needs to be downloaded. You can use docker history to peek at which layers (other images) are used (and, to some extent, which command created the layer).

As for options to share an image without pushing to the docker hub registry, your best options are:

  • docker save an image or docker export a container. This will output a tar file to standard output, so you will like to do something like docker save 'dockerizeit/agent' > dk.agent.latest.tar. Then you can use docker load or docker import in a different host.

  • Host your own private registry. - Outdated, see comments See the docker registry image. We have built an s3 backed registry which you can start and stop as needed (all state is kept on the s3 bucket of your choice) which is trivial to setup. This is also an interesting way of watching what happens when pushing to a registry

  • Use another registry like quay.io (I haven't personally tried it), although whatever concerns you have with the docker hub will probably apply here too.

Abel Muiño
  • 7,611
  • 3
  • 24
  • 15
  • 6
    For future reference, the link to the docker registry image is outdated. You should now use [Docker Registry 2.0](https://docs.docker.com/registry/) and the code on [github/docker/distribution](https://github.com/docker/distribution) – RoelAdriaans Jun 06 '15 at 17:31
  • 1
    I'm not sure it's clear that Registry 2.0 is a ready for use replacement for the original one. It seems to miss some basic functionality such as search http://stackoverflow.com/questions/30113726/docker-registry-2-0-api-v2 – JoshRivers Jun 16 '15 at 19:06
  • 2
    Question about `docker save`: when I push an image that derives from another image (let's say `python:2.7`) to a registry, the parent image doesn't need to be uploaded more than once unless it changes. Can I save partial images to achieve a similar file size optimization? I'm jumping through these hoops because I'm a hobbyist with multiple images and I don't want to pay for a private registry. – Pieter Feb 14 '16 at 09:03
  • 5
    Could you not just pull src files from a git repo, including a Dockerfile, and `docker build` on the host? – toficofi Feb 24 '16 at 03:38
  • 1
    @Jishaxe part of my build is to `npm install`... I can't build on my host because it has very little memory and this step always fails (see: https://github.com/npm/npm/issues/5021) – Soft Bullets Mar 20 '17 at 11:29
96

Based on this blog, one could share a docker image without a docker registry by executing:

docker save --output latestversion-1.0.0.tar dockerregistry/latestversion:1.0.0

Once this command has been completed, one could copy the image to a server and import it as follows:

docker load --input latestversion-1.0.0.tar
030
  • 10,842
  • 12
  • 78
  • 123
  • I guess this way you lose caching/reusing not changed layers? Cause you would always upload full image even if only small thing changed? – Andrius Jan 24 '21 at 16:06
  • Once on local, you just call it exactly like if it comes from the registry: `docker run [flags] foo.bar.com//:latest ` – RicHincapie Feb 25 '23 at 03:52
56

Sending a docker image to a remote server can be done in 3 simple steps:

  1. Locally, save docker image as a .tar:
docker save -o <path for created tar file> <image name>
  1. Locally, use scp to transfer .tar to remote

  2. On remote server, load image into docker:

docker load -i <path to docker image tar file>
Demitri
  • 13,134
  • 4
  • 40
  • 41
JSON C11
  • 11,272
  • 7
  • 78
  • 65
10

[Update]

More recently, there is Amazon AWS ECR (Elastic Container Registry), which provides a Docker image registry to which you can control access by means of the AWS IAM access management service. ECR can also run a CVE (vulnerabilities) check on your image when you push it.

Once you create your ECR, and obtain the "URL" you can push and pull as required, subject to the permissions you create: hence making it private or public as you wish.

Pricing is by amount of data stored, and data transfer costs.

https://aws.amazon.com/ecr/

[Original answer]

If you do not want to use the Docker Hub itself, you can host your own Docker repository under Artifactory by JFrog:

https://www.jfrog.com/confluence/display/RTF/Docker+Repositories

which will then run on your own server(s).

Other hosting suppliers are available, eg CoreOS:

http://www.theregister.co.uk/2014/10/30/coreos_enterprise_registry/

which bought quay.io

MikeW
  • 5,504
  • 1
  • 34
  • 29
  • Also available on Google cloud console although I've not tried sharing outside the organisation – sam Dec 21 '21 at 19:03