How to set up Node and Tailwind with docker [step-by-step]

Gustavo Inzunza
5 min readJan 27, 2023

--

I was taking a course about Tailwind that was requiring Node and I didn’t want to install anything directly on my machine. For that reason, I created this project

Prerequisites

  • Docker needs to be installed and running on your computer
  • Docker basic background
  • NodeJs basic background

Setting up the docker file

First of all, you have to create a Dockerfile in your project folder with the following command:

touch Dockerfile

After creating it, you should add the following content to it:

FROM node:16

# Create app directory
WORKDIR /node
# 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 ./

RUN npm install
# If you are building your code for production
# RUN npm ci --only=production
COPY . .

EXPOSE 8080
CMD [ "node", "server.js" ]

This is the explanation of each instruction:

  • From node:16: means that we are using the node docker hub image 16.
  • WORKDIR /node: means that we are setting the app directory. In other words, inside the docker image, all our project is inside a folder called node.
  • COPY package*.json ./: means that we are copying all the files that start with the string package and finish with .json into the docker image root folder. The idea is to copy package.json and package.lock.json.
  • RUN npm install: means that we are executing the command “npm install”. The idea is to install all the npm dependencies.
  • COPY . .: means that we are copying all that we have in our current Docker build context into the docker image root folder.
  • EXPOSE 8080: means that we are going to be able to access the docker image port 8080 from our machine.
  • CMD [ “node”, “server.js” ]: means that we are defining the docker default executable. In other words, every time we run our docker image, at the end of the execution we are going to run node server.js.

Setting up node

Node will have two important files: package.json and server.js. Let’s start with the first. You have to create the file in your root project folder with the following command:

touch package.json

After creating it, you have to add the following content to it:

{
"name": "docker_web_app",
"version": "1.0.0",
"description": "Node.js on Docker",
"author": "First Last <first.last@example.com>",
"main": "server.js",
"scripts": {
"build-css": "tailwindcss build style.css -o css/style.css",
"start": "node server.js"
},
"dependencies": {
"express": "^4.16.1",
"autoprefixer": "^10.4.13",
"postcss": "^8.3.0",
"tailwindcss": "^2.1.2"
}
}

In the file above you are adding the dependencies necessary to run your nodeJS server and Tailwind.

Regarding the server you should create the file in your root project folder with the following command:

touch server.js

After creating it, you should add the following content to the file:

'use strict';

const express = require('express');

// Constants
const PORT = 8080;
const HOST = '0.0.0.0';

// App
const app = express();
app.get('/', (req, res) => {
res.send('Hello World');
});

app.listen(PORT, HOST, () => {
console.log(`Running on http://${HOST}:${PORT}`);
});

The file above contains the necessary to run our node server.

Setting up Tailwind

In this tutorial, Tailwind will have just one important file. This is just because we are configuring a simple example to get it working.

To create the file you have to execute the following command in the project root folder:

mkdir css && touch css/style.css

Inside the file you should add the following:

@tailwind base;
@tailwind components;
@tailwind utilities;

In the file above, you are importing tailwind libraries.

Building your docker image

So, because we have all the files that we need, we are able to build the docker image but before building, we are going to create a volume to store the node_modules with the following command:

docker volume create node-test-tailwindcss

Now we can build our docker file with the following command:

docker build -t ginzunza/node-tailwind-web-app . # you can replace ginzunza with your user

As you can see, you are executing all the commands that are inside your Dockerfile. To avoid using a too-large command for the next steps we are going to add this alias:

alias docker-nt="docker run -it -v ${PWD}:/node -v node-test-tailwindcss:/node_modules ginzunza/node-tailwind-web-app" # you can replace ginzunza with your username

So, after finishing you can run your image with the following command to init the Tailwind config:

docker-nt npx tailwindcss init

After executing that command you will see a new file called tailwind.config.js in your root folder. So, to start to test tailwind you could create an index.html, but to be able to include our css/style.css file transpiled we should execute this command first:

docker-nt npm run build-css 

Now we can add this to our index.html file:

<html>
<head>
<link rel="stylesheet" href="css/style.css"></link>
</head>
<body>
<div class="grid grid-cols-3 gap-5">
<div class="bg-blue-200 row-span-2 h-full">
<p>Hi</p>
</div>
<div class="bg-red-500">
<p>Hola</p>
</div>
<div class="bg-red-500">
<p>Hola 2</p>
</div>
</div>
</body>
</html>

So, in the code above you are loading your Tailwind styles in the head, and in the body, you are using the syntax. The easiest way to see the effect is by clicking your file because it will be loaded into the browser and you don’t need Node for that step.

Finally, to run your Node server you should execute the following command. Note that we are not going to use the alias because we are adding the port, but you are free to add a new alias with that inside:

docker run -it -v ${PWD}:/node  -v node-test-tailwindcss:/node_modules -p 49162:8080 ginzunza/node-tailwind-web-app

So, after executing that if you go to your browser to the following route http://localhost:49162/ you will see:

That’s it.

Conclusion

In this post, we analyzed step by step a way to set up a Node server with Tailwind without the necessity to install it on our local machine.

📥 Thanks For Reading! 📥

If you have any questions or suggestions please let me know. Don’t forget to follow me on GitHub and Twitter

--

--

Gustavo Inzunza

I'm a SR backend developer interested in scalability, algorithms and music