TL;DR;
If you're trying to test their knowledge of docker then your Dockerfile is already spoiled with common mistakes. If it's testing their knowledge of whatever is running inside the container created from an image built from your Dockerfile then it depends on what the application does and if you're trying to test them on their capabilities of debugging an application in general then the sky is the limit on how many hoops you can make them jump from incorrect binaries for the OS, incorrect file permissions, encoding issues, resource allocation, networking, ...
Current common mistakes
- "Split long or complex RUN statements on multiple lines separated with backslashes ..."
- Pin the version of the
apt packages that you're installing (note: this is by far the most common mistake I see)
- Don't install packages recommended by
apt that you do not need
- "When you clean up the apt cache by removing /var/lib/apt/lists it reduces the image size ..."
- "the instructions
RUN, COPY, ADD create layers" and the WORKDIR instruction will create the directory if it doesn't already exist - removing the RUN mkdir app removes a layer from the final image
- Pin the version of
gem packages
- Chain commands in the
RUN instruction to reduce the amount of layers in the final image
- Set the
ENTRYPOINT instruction in your Dockerfile
- Use JSON notation for
CMD and ENTRYPOINT arguments
Note: debain based images perform cleanup after every apt-get install but hadolint will complain if you don't explicitly remove the apt files. You can either ignore the linting error or explicitly cleanup after the install, I prefer the latter.
A hadolint'd version of your Dockerfile:
FROM ruby:2.7.1
RUN apt-get update && \
apt-get install -y --no-install-recommends \
nodejs=10.21.0~dfsg-1~deb10u1 && \
rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY Gemfile Gemfile.lock ./
RUN gem install bundler:2.1.4 && \
bundle install
COPY . ./
EXPOSE 3000
ENTRYPOINT ["entrypoint.sh"]
CMD ["bundle", "exec", "rails", "s", "-p", "3000", "-b", "'0.0.0.0'"]
Concerning the docker-compose configuration, setting the command is redundant:
version: '3.8'
services:
app:
build: .
volumes:
- .:/app
ports:
- "3000:3000"
... regarding the ports being open it really depends on what your expectations are. If you're expecting the person to advise you that mapping ports is meh and that you should proxy traffic to the service (i.e. through nginx) then yes that should be considered an issue.
Additional common mistakes
A non-exhaustive list of common mistakes I often come across:
COPY'ing a tar archive into an image then un-compressing the tar in 2 instructions
COPY files.tar.gz /
RUN tar czvf files.tar.gz
Can be replaced with ADD (removes a layer from the final image) i.e.: ADD files.tar.gz /
- Changing directories then uncompressing
tar files
RUN cd / && tar xzvf files.tar.gz
Can change directories with tar's -C option before un-compressing the file i.e. tar -C / xzvf files.tar.gz
curl'ing tar files then un-compressing them in 2 RUN's
RUN curl -Lo files.tar.gz https://example.com/files.tar.gz
RUN tar xzvf files.tar.gz
Can pipe the curl output into tar in a single RUN instruction i.e.: curl https://example.com/files.tar.gz | tar xzv
- Using
pipe's without setting SHELL options ^ should be:
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
RUN curl https://example.com/files.tar.gz | tar -C / xzv
COPY'ing things from a multi-staged build that shouldn't be copied into the final layer:
FROM debian:buster-slim as build
# build everything
FROM scratch as target
COPY --from=build /some/random/file .
COPY'ing secrets into builds (use buildkit and your ssh-agent for cloning repositories in the build)