TypeOfNaN

How to Serve a Static App with nginx in Docker

Nick Scialli March 07, 2021🚀 4 minute read

docker and nginx logos

Let’s create a static site and learn how to serve it in a Docker container using nginx. First, we’ll want to create a simple static site with some assets.

Creating a Sample Site

We can make a directory called static-site-nginx and, within that directory, let’s make an index.html file, a styles.css file, and an index.js file.

mkdir static-site-nginx
cd static-site-nginx
touch index.html styles.css index.js

Next up, put the following content in each file. This ends up being a pretty bare-bones site with a styled h1 element and a dynamic counter.

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>My Static Site</title>
    <link rel="stylesheet" href="./styles.css" />
  </head>
  <body>
    <h1>My counter app</h1>
    <p>Here's the count: <span>0</span></p>
    <button>Click me</button>
    <script src="./index.js"></script>
  </body>
</html>

styles.css

h1 {
  font-family: sans-serif;
  color: blue;
}

index.js

const count = document.querySelector('span');
const button = document.querySelector('button');
button.addEventListener('click', function () {
  count.textContent = parseInt(count.textContent) + 1;
});

Running the App (Without Docker First)

Just so we know what we’re dealing with, let’s run the app. I’m using the npm serve package as a local dev server, but any server will work fine.

If we pull the app up in a browser, we should see the following UI / functionality.

counter app

If you’ve gotten this far, great! It’s now time to dockerize the app.

One Required File

Right now, we only need one file to configure our simple static site for Docker: a Dockerfile.

touch Dockerfile

In a more complex app, we might need other files (e.g., a .dockerignore file), but the one file should serve us just fine for now.

Building Out the Dockerfile

Time to build out the Dockerfile! Our Dockerfile config will be relatively trivial: it will just need to have nginx installed, copy over the static assets, and specify the entrypoint for our container.

Todos:

  • Use an nginx image
  • Remove any default static assets from the nginx image
  • Copy our static assets over
  • Specify the entrypoint for our container to run nginx

Here’s what this looks like in the Dockerfile:

# nginx state for serving content
FROM nginx:alpine
# Set working directory to nginx asset directory
WORKDIR /usr/share/nginx/html
# Remove default nginx static assets
RUN rm -rf ./*
# Copy static assets over
COPY ./* ./
# Containers run nginx with global directives and daemon off
ENTRYPOINT ["nginx", "-g", "daemon off;"]

Now that we have assembled our Dockerfile, let’s build an image called static-nginx:

docker build -t static-nginx .

Now that our image is built, we can start a container with the following command, which will serve our app on port 8080.

docker run --rm -it -p 8080:80 static-nginx

Navigate to http://localhost:8080, and you should now see our app running!

If you'd like to support this blog by buying me a coffee I'd really appreciate it!

Nick Scialli

Nick Scialli is a software engineer at the U.S. Digital Service.