chatdesk-ui/postgrest_v12.2.8/nix/tools/docker/README.md

6.5 KiB

Docker image built with Nix

In order to build an optimal PostgREST Docker image, we create the image from scratch (i.e., without a parent image like debian or alpine), and only include the file that is essential for running PostgREST: the static PostgREST binary.

This is similar to what you would get with the following Dockerfile:

# `scratch` is a minimal, reserved image in Docker, see
# https://docs.docker.com/develop/develop-images/baseimages/ . It essentially
# means "don't use a parent image and start with an empty one".
FROM scratch

# The static PostgREST executable has no runtime dependencies, so it's all we
# need to include for running the application.
ADD /absolute/path/to/postgrest /bin/postgrest

EXPOSE 3000

# This is the user id that Docker will run our image under by default. Note
# that we don't actually add the user to `/etc/passwd` or `/etc/shadow`. This
# means that tools like whoami would not work properly, but we don't include
# those in the image anyway. Not adding the user has the benefit that the image
# can be run under any user you specify.
USER 1000

CMD [ "/bin/postgrest" ]

Building the Docker image with Nix

As we are building the static PostgREST executable with Nix and that's the main input to the Docker file, we can also create the Docker image directly with Nix using the dockerTools utilities. Those utilities don't actually use Dockerfiles or Docker to build Docker images, but create them directly by putting together the required json and tar files that make up an image. This is more efficient, does not rely on Docker or root permissions and results in fully reproducible builds. See nix/docker/default.nix for details how the image is built.

Building and loading the image

The Nix expression provides a helper script postgrest-docker-load that loads the optimized image into your local Docker instance (using docker load -i <image file> under the hood). You can use it by running:

# Running from the root directory of the repository:

# Build the `docker` attribute from `default.nix`, the result will be symlinked
# to `result`:
nix-build -A docker

# Run the loading script:
result/bin/postgrest-docker-load

The Docker image built with Nix always has the name "postgrest:latest" when loaded.

Inspecting the optimized image

The image does not come with the usual utilities like bash and ls.

You can, however, explore the tar file of the image by saving it with docker save postgrest:latest > image.tar.

Dive is also useful for looking at the contents of the image:

┃ ● Layers ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ │ Current Layer Contents ├────────────────────────────────────────────────────────────────────────────────
Cmp   Size  Command                                                                                        Permission     UID:GID       Size  Filetree
     14 MB  FROM 20ee65c811575d2                                                                           dr-xr-xr-x         0:0      14 MB  ├── bin
                                                                                                           -r-xr-xr-x         0:0      14 MB  │   └── postgrest
│ Layer Details ├───────────────────────────────────────────────────────────────────────────────────────── drwxr-xr-x         0:0      783 B  ├── etc
                                                                                                           -r--r--r--         0:0      783 B  │   └── postgrest.conf
Tags:   (unavailable)                                                                                      dr-xr-xr-x         0:0      23 kB  └── nix
Id:     20ee65c811575d206eb673e1887e7f7e6b7ccde902a63ccb924c5faa50b32cee                                   dr-xr-xr-x         0:0      23 kB      └── store
Digest: sha256:ece77302b83fd38fb54395dabc10c2eba06fc1d1933801d36cc2c4732d9c8f38                            dr-xr-xr-x         0:0      23 kB          └── s440jbrn94wmpzy7f8yfsp6jr2shllw5-openssl-1.1.1g-etc
Command:                                                                                                   dr-xr-xr-x         0:0      23 kB              └── etc
                                                                                                           dr-xr-xr-x         0:0      23 kB                  └── ssl
                                                                                                           -r--r--r--         0:0      412 B                      ├── ct_log_list.cnf
│ Image Details ├───────────────────────────────────────────────────────────────────────────────────────── -r--r--r--         0:0      412 B                      ├── ct_log_list.cnf.dist
                                                                                                           dr-xr-xr-x         0:0        0 B                      ├── engines-1.1
                                                                                                           -r--r--r--         0:0      11 kB                      ├── openssl.cnf
Total Image size: 14 MB                                                                                    -r--r--r--         0:0      11 kB                      └── openssl.cnf.dist
Potential wasted space: 0 B
Image efficiency score: 100 %

Count   Total Space  Path

Deriving from the optimized image

Since the docker image is minimal, it does not contain a shell or other utilities. To derive a non-minimal image, you can do the following:

# derive from any base image you want
FROM alpine:latest

# copy PostgREST over
COPY --from=postgrest/postgrest /bin/postgrest /bin

# add your other stuff