How to Develop with TypeScript in Docker with Hot Reloading
Developing with TypeScript inside Docker can be a bit tricky, but for the most part, it’s not too different from local TypeScript development.
By the end, we’ll have this following project structure.
📂 typescript-express-app
┗ 📂 src
┗ 📜 index.ts
┣ 📜 .dockerignore
┣ 📜 Dockerfile
┣ 📜 nodemon.json
┣ 📜 package.json
┗ 📜 tsconfig.json
Install TypeScript Packages
We want to start by installing the relevant devDependencies
.
We’ll be using ts-node
, typescript
, and nodemon
. Be sure to install all the necessary @types/*
packages.
npm install ts-node typescript nodemon --save-dev
Create tsconfig.json
Let’s create our tsconfig.json
. We can add whatever options we’d like. The rootDir
is the location of all our TypeScript files, which is /src
in our case.
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"rootDir": "./src",
"outDir": "./build",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
}
}
Update package.json
We need to add a start script dev
in our package.json
that will be referenced in our Dockerfile
.
Here, we’ll be running our src/index.ts
to start our Express application using nodemon
.
"scripts": {
...
"dev": "nodemon -L src/index.ts",
...
}
The -L
enforces Chokidar polling, which is needed to watch for file changes in our container.
Create nodemon.json
Let’s work on our second configuration file, nodemon.json
. Our nodemon
command above will follow the configurations we specify below.
{
"watch": ["src"],
"ext": "ts, json",
"exec": "ts-node ./src/index.ts"
}
We’ll be watching for file changes inside our /src
directory.
When a change occurs, we compile everything into JavaScript, and then run our src/index.ts
again.
Create Dockerfile
Let’s create a Dockerfile
, which will copy all of our source over to a container, and then run our dev
script, which will trigger nodemon
to watch and compile when neceesary.
FROM node:14.16.0-alpine3.10
WORKDIR /usr/app
COPY package*.json ./
RUN npm install
COPY . ./
CMD ["npm", "run", "dev"]
Mount the Source
We can start this container using docker build
or with a docker-compose.yml
.
I’ll demonstrate how to mount the source using Docker Compose.
We can mount the source using the volumes
field, where we are indicating that the container’s /usr/app/src
should point directly to the host machine’s ./src
, allowing for nodemon
inside the container to see the changes on our local, host machine.
version: "3"
services:
typescript-express-app:
build:
context: .
dockerfile: Dockerfile
port:
- 5000:5000
volumes:
- ./src:/usr/app/src
Now, how can we turn all this into a production build?