Our Dockerfile is now ready, and we can use it to generate the image using docker build, which has the following signature:
$ docker build [context] -f [path/to/Dockerfile]
The docker build command builds an image based on the Dockerfile and a context. The context is a directory which should contain all the files that are needed to build the image. In our case, it is also where our application code is to be copied from.
For example, if we are at the project root directory, we can run the following command to build our image, using the current working directory as the context:
$ docker build . -f ./Dockerfile
By default, if you don’t specify the location of the Dockerfile, Docker would try to find it at the root of the context. So, if you are in the root directory of the context, you can simply run the following:
$ docker build .
However, we don't want to copy all of the contents of the project, because:
- It's generally a bad idea to add things you don't need—it makes it harder for someone trying to understand the logic of the application, because there's more noise
- It adds to the size of the image
For instance, there is over 320 MB inside the .git, node_modules, and docs directories—files which we don't need inside our container to build and run our application.
$ du -ahd1 | sort -rh
323M .
202M ./.git
99M ./node_modules
21M ./docs
880K ./dist
564K ./src
340K ./coverage
176K ./.nyc_output
168K ./spec
140K ./yarn-error.log
128K ./yarn.lock
20K ./scripts
8.0K ./.vscode
8.0K ./.env.example
8.0K ./.env
4.0K ./package.json
4.0K ./.nvmrc
4.0K ./.gitmodules
4.0K ./.gitignore
4.0K ./.dockerignore
4.0K ./Dockerfile
4.0K ./.babelrc
Therefore, we can use a special file called .dockerignore, which is similar to .gitignore, and will disregard certain files from the context.
But instead of specifying which files we will ignore, we’ll be more explicit and add a rule to ignore all files, and add exceptions to this rule in subsequent lines. Add the following lines to .dockerignore:
*
!src/**
!package.json
!yarn.lock
!spec/openapi/hobnob.yaml
!.babelrc
!.env
Now, run $ docker build -t hobnob:0.1.0 . and check that the image is created by running docker images:
$ docker build -t hobnob:0.1.0 .
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hobnob 0.1.0 827ba45ed363 34 seconds ago 814MB
Although the image size is still quite large (814 MB), much of this comes from the standard node image, which is 673 MB. Without limiting the scope of the context, the hobnob image size easily goes over 1 GB.