Guide. Note that Dockerfile doesn’t have a file extension, simply create a file named “Dockerfile” in the same folder that package.json lives in.

The instructions in a Dockerfile are almost identical to their Linux counterparts. By convention they’re all in UPPER CASE.

Step By Step

FROM

Start with your Base Image. For most, this is an off the shelf image like Python or a Linux distro. Syntax: FROM baseImage:tag Ex:

FROM python:3.12

WORKDIR and COPY

Next need to set up the working directory or file system within the container, this depends on the use case. Ex:

# set a directory for the app and `cd` into it
WORKDIR /usr/src/app
 
# copy all the files to the container
COPY . .

Best to do this when you’re in your app’s root.

Ignoring Files

If there are files that you don’t want to copy such as node_modules folder (AKA the heaviest object in the known universe) include them in a .dockerignore file just like we do with .gitignore.

RUN

This command lets us run any Linux commands, the way we would in a terminal.

Ex: to install your app’s dependencies.

# install dependencies
RUN pip install --no-cache-dir -r requirements.txt

This runs as root user, but to run as another…

USER

Allows us to create another user that’s non-root user. Ex:

RUN useradd --create-home appuser
USER appuser

EXPOSE (ports)

If your app runs on a specific port, then expose that port.

EXPOSE 9000

ENV

To set ENV variables for the container to use.

ENV API_KEY=VALUE

CMD

This instruction tells Docker what commands you want to run when starting up the container. Each container’s dockerfile may only have one CMD instruction. Syntax: CMD ["executable","param1","param2" ...]

Ex: for a Python app it’s something like

CMD ["python3", "./app.py", "37"]

RUN vs CMD

The RUN keyword is used to build the image for the container, whereas the CMD keyword is what docker uses to start the container.

ENTRYPOINT

This instruction lets us pass arguments to the CMD instruction. Ex:

ENTRYPOINT ["python3", "-m", "http.server"]
CMD ["8000"]

With that, your Dockerfile is ready and you can build the Image.

More Instructions

VOLUME

This lets us mount some persistent storage to store data that will be used later on, or perhaps by multiple containers. Ex:

VOLUME /stuff/data

Dockerignore file

The .dockerignore files basically works like .gitignore it tells docker which files to ignore while copying using the COPY keyword. This is great for ignoring .env and node_modules and the like…

Building the Image

There’s plenty of docs on how to build here. For simple stuff use the command `docker build -t username/appname .

The -t option is used to specify the name and tag of the Image.

Running the Container

To run the container:

  1. Navigate to the project containing the dockerfile.
  2. Type and execute: docker run -p 9000:9000 username/appname

The -p flag is used for port forwarding, which assigns the ports that the host OS (left) and the container (right) will communicate on. // Sorta like a bridge into the container.