Local CRUD API Express App with Docker in 5 min

Zayd Simjee's photo
Zayd Simjee
·Jul 27, 2021·

5 min read

Local CRUD API Express App with Docker in 5 min

A Video version of this article is available at

A CRUD API is the beating heart of all data-driven applications. In this article, I'll use a sample CRUD API provided by TinyStacks and show how to get it up and running on Docker. Then I’ll show you how you build more complex functionality on top of this base.

What’s CRUD?

CRUD stands for

  • READ

These are the basic data storage functions in an application, on top of which we can build more complex logic.

Definition of CRUD Functions


Adds a new item. The user provides the values. Typically, the system assigns a unique ID, that enables finding, updating, or deleting the resource later.


Retrieves one or more resources. To get a single resource, the user provides the unique ID of the resource, or any other relevant field they need .


Changes the values of a specific resource. The user provides all the values that should change and the ID of the resource to update.


Removes an existing item. The user provides the id of the resource; if that item exists, it is removed.

In this article, we’ll use a pe-built CRUD API application in Express created by TinyStacks that supports basic CRUD functions. You can start with this sample and modify it according to your needs.

Disclaimer: In this article, we don’t use a database. All data is saved in memory. Obviously, this isn’t how you would write a production-ready application.

But don't worry! In our upcoming videos, we’ll incorporate database storage. Today, our goal is to understand how the custom endpoints of our application work.

Step By Step Guide

Clone the repo

At a command prompt, type:

git clone

Then enter into the folder:

cd aws-docker-templates-express

To run the application without Docker, please refer to the file To run this example, you should have Node.js already installed on your system

npm install
npm run build
node built/server.js

Now, let's review the Dockerfile for this application:


# Create app directory
WORKDIR /usr/src/app

# Install app dependencies
# A wildcard is used to ensure both package.json AND package-lock.json are copied
# where available (npm@5+)
COPY package*.json ./
COPY tsconfig.json ./
COPY src ./src
RUN npm install
RUN npm run build

# Bundle app source
COPY . .

CMD [ "node", "built/server.js" ]

Let's examine this line by line.

The FROM line is to specify a Docker image as our base. In this case, we are using a node image from the public AWS container registry.

The WORKDIR, as its name suggests, is the working directory for our project/ The COPY and other commands take this as the path for the image filesystem.

Then we have 3 COPY commands:

  • COPY package*.json ./ is to copy both package.json AND package-lock.json (if that file exists).

  • COPY tsconfig.json ./ to copy the TypeScript configuration file in the image file system

  • COPY src ./src to copy the source folder

Next, we build the npm project inside the image. Please note that this has nothing to do with the build process of the Docker Image; it's just the specific build for this npm project. Let's check the two commands:

  • RUN npm install installs all of the application’s dependencies

  • RUN npm run build builds the project inside the image

Then we just copy the rest, which concludes our build.

EXPOSE is not really needed, but it's good for documenting which port we will use.

Last but not least, we use the CMD command to run the application:

CMD [ "node", "built/server.js" ]


Build the Docker image

as explained in the Readme file, let's build the image, starting from this Dockerfile

docker build -t tinystacks/express-crud-app:latest .

of course, feel free to change the tag if you want a different name for your image.

Then let's run the container:

docker run -p 8080:80 -d tinystacks/express-crud-app:latest

Test the Container

To check if the container is up and running, let’s make an HTTP request. We could make such a request from the command prompt using cUrl, but in this case, let’s use Postman, an extremely useful tool for API development and testing.

First, let’s check that the application is running.


Let's make a GET request at http://localhost:8080/ping, using Postman:


If we get an HTTP response with a 200 code, it means that our application is up and running.

Since it's working, let's test our CRUD API with Postman. First of all, let's verify that our in-memory "database" is empty:

READ ALL /item => empty array


CREATE: PUT : to create a record

To create a new resource:

image.png image.png



READ ALL (again)





Now let's try to add a custom endpoint to this existing project. In the file local-item.ts, let's add this function:

export function customItem(req: Request, res: Response) {
  res.status(200).json("OK Custom Item")

This function is just for demo purposes!

In the file server.ts, let's add the custom route and import it:

app.get('/customItem', parser, getUser);

on the line 6 of the same file, let's update the list of imported methods:

import { deleteItem, getItem, putItem, updateItem, customItem } from "./local-item";

In order to test these changes, you should rebuild the project and test the new endpoint at /customItem

A Video version of this article is available at

Share this