How to Set up Development Server Using Typescript And Docker
Get rid of the daunting task of setting up your first development server with these easy steps
Setting up your very first development server wouldn’t be an easy task. Sometimes you’re confused with so many steps that you need to follow and other unspecified requirements.
I faced this problem a while ago and the truth is I need to combine several resources to make it work. So, what if I provide another resource to help the community even further?
Background
Let’s say that you want to build an application using TypeScript. It means that you need to somewhat compile the code you’ve just written to JavaScript then run it. Okay, that sounds pretty simple.
You know that you have a remote database you can use together with all your project’s team members. But after a while of developing the application, your development database is piled up with junk data. Since you don’t like this messiness. You want to know how to set up a server and database to freely develop your application, including running your tests.
Thankfully, you come to the right place. Let’s stop this sweet talk and jump to the main content.
Setup TypeScript project
First, create a directory for your project. You can give it a name anything you want, e.g. typescript-server. After that, create a package.json
file by running:
npm init// Without any questions
npm init -y
Now, you have a package.json
inside your project’s root directory.
Next, You need to install TypeScript as a development dependency. You can do that by running
npm i typescript --save-dev
Since you have TypeScript installed, now you can create a tsconfig.json
file by running the command
npx tsc --init
Voila, you have a tsconfig.json
inside your project’s root directory. tsconfig.json
indicates your project is a TypeScript project and it contains compiler options required to compile the project. Because basically, you are writing code in TypeScript but your server is running in JavaScript.
You’ll have a bunch of options inside tsconfig.json
, but in this case, I simplify the file by only using these options.
For such a common directory structure, we need a src
folder inside the project’s root directory. So, let’s make one!
Create the src
folder and index.ts
inside it. For sanity check, you can write this inside index.ts
.
Now, compile the TypeScript code by running command
npx tsc
At this point, you see that you have a folder named build
. That’s where your JavaScript file is placed. Since we’ve specified the compiled folder to be inside build
folder (look for outDir
option in tsconfig.json
).
Now, run the JavaScript code by running
node ./build index.js
Nice, we can see “Hello World!” message printed on the terminal.
It’s better to simplify our previously used commands inside package.json
file’s scripts. Rewrite the scripts section inside package.json
into this:
As the scripts suggest, you can compile the code using npm run build
and run the code using npm run dev
.
Running our development server
Previously, we’ve written a sanity check to make sure that our code can be compiled and can be executed. Now, we’ll set up our server using Express.
Install Express by running npm install express @types/express
Change index.ts
inside src
folder into this
As before, you can compile the code using npm run build
, then run it using npm run dev
. Now, you can see our server is running on port 5000.
Define coding rules with eslint (optional)
Having predefined rules when writing code is pretty essential. It can make your code consistent, especially when you’re working in a team. But for beginners, writing with rules can become a slowdown factor. Fear not, you can skip this section and come back again after you are confident enough.
Install eslint and its extensions:
npm install eslint eslint-config-airbnb-base eslint-plugin-import @typescript-eslint/eslint-plugin @typescript-eslint/parser
Obviously, different teams or projects might have different coding rules. But you can configure it based on your needs.
Live Reload with Nodemon
Okay, we’ve made some progress. But is it tiring to terminate, compile, then run the code each time we made some changes? Let’s simplify our development experience by using nodemon.
Run npm install nodemon
Create nodemon.json
, then write this
Change the previous package.json
’s scripts into this
Note: if you don’t use eslint, remove eslint --fix --ext .ts ./src
Now, you can run your development server by running npm run dev
. Try to change your code (e.g index.ts
), you’ll see that the code is recompiling and running again.
Docker and docker-compose
At this point, you have a working development server. To achieve our previous concern in the introduction, let’s combine it with Docker.
Create a Dockerfile inside the project’s root directory and write this.
Then create a docker-compose.yaml
If you want a Postgres database service, then use this docker-compose file.
Run command docker-compose up
to run all services inside docker-compose file.
Commands with Makefile
To make our development cycle much simpler, let’s have a Makefile.
The commands we have here are pretty much self-explainable. You can build the images using make build
, to run the services using make up
(without rebuilding the images), make run
if you want to build the services first. Then make down
to drop all services’ containers.
Conclusion
We’ve been going through several steps of setting up a development server. Just like the name said, it's only for development purposes. If you are curious about how to set up a production-ready server, you can go to the resources for the detail.
Hope this article can help you perceive setting up a development server, not as a daunting task, but step by step sequence that you can follow through.
Thank you for reading and happy coding!