How to Create Dockerized NodeJS with MySQL Database
Tags: docker, javascript, mysql, node
Published: 2021-02-09 09:48:58

TLDR;
You can access the code here on [Github](https://github.com/frasnym/Docker-NodeJS-MySQL)
(*step by step how to run included* 🤝)

Hello 👋, This will be my first post on this forum.
I will show you guys how to create a **NodeJS**-**MySQL** database with help of **Docker**.

FYI, I just learn using docker too and I found that docker is very good to help development process faster ⚡.

## Here we go
I will assume that you already know what docker is and already installed it on your machine. I will use `docker-compose` to create this project.

1. Create MySQL Container, I'm using MySQL image to help me build this container.
2. Create `docker-compose.yaml` file. I this file we will be specifying our docker app.
```
version: '3.8'

services: 
  mysqldb:
    image: mysql
    restart: always
    env_file: ./.env
    environment:
      MYSQL_ROOT_PASSWORD: $MYSQL_ROOT_PASSWORD
      MYSQL_DATABASE: $MYSQL_DATABASE
    ports:
      - $MYSQL_LOCAL_PORT:$MYSQL_DOCKER_PORT
    volumes: 
      - db-config:/etc/mysql
      - db-data:/var/lib/mysql
      - ./db/backup/files/:/data_backup/data

volumes: 
  db-config:
  db-data:
```

### Description:
- `version: '3.8'`: This first line of code must be provided on *docker-compose.yaml* file. This will tell docker which version of docker we used
- `services: `: Inside this tag we will tell docker what service we will make
- `mysqldb:`: The first service is **mysqldb**. You're free to choose the name
- `image: mysql`: We tell docker what image we will use. **mysql** is official image for MySQL
- `restart: always`: This command will tell docker always restart the container regardless of the exit status
- `env_file: ./.env`: We specify our **.env** path
- `environment:` ON this tag we provide our MySQL connection setting
- `MYSQL_ROOT_PASSWORD:`: Specify password for root username
- `$MYSQL_ROOT_PASSWORD` is key from .env
- `MYSQL_DATABASE: $MYSQL_DATABASE`: create initial database
- `ports:`: we specify what port docker will be used. We will specify 2 port
- `$MYSQL_LOCAL_PORT`: The first one is what port on our machine will be used
- `$MYSQL_DOCKER_PORT`: The second one is what port we used inside docker container
- `volumes:`: Volume will help us to keeping our data alive though restart
- `db-config:/etc/mysql`: Volume to save config
- `db-data:/var/lib/mysql`: Volume to save database data
- `./db/backup/files/:/data_backup/data`: Mount bind backup data

> That a lot of typing already LOL 😂

## Let's continue 🚀 
3. Now we make our NodeJS app, inside of *app* folder
4. You can initialize npm as usual
5. Here we will be create a **Dockerfile**, this will help us to create image for NodeJS App
```
FROM node:14

WORKDIR /app

COPY /app/package.json .

RUN npm install

COPY /app .

EXPOSE 3000

CMD [ "npm", "start" ]
```
### Description:
- `FROM node:14`: Specify base image for node. I take official image of NodeJS
- `WORKDIR /app`: Define working directory of docker. Our app will be placed on this folder inside docker
- `COPY /app/package.json .`: Copy our *package.json* file to our working directory (declared by dot(.) code)
- `RUN npm install`: Install npm dependency as always
- `COPY /app .`: Next we will copy our rest of file to working directory
- `EXPOSE 3000`: We expose port to access via localhost
- `CMD [ "npm", "start" ]`: Specify script to run after image is builded

> Did you confused? If yes, me too when first learning this docker thing 😁

## Continue 🚀 
Back to our *docker-compose.yaml* file

6. Now we will define our NodeJS App on docker-compose
```
  app:
    build:
      context: .
      dockerfile: ./app/Dockerfile
    image: node-mysql-app
    depends_on:
      - mysqldb
    stdin_open: true
    tty: true

volumes: 
  db-config:
  db-data:
```
The command is more or less the same
### Description
- `app:`: This is our second service's name
- `build:`: For custom image we will use `build`
- `context: .`: Specify the file PATH
- `dockerfile: ./app/Dockerfile`: This will be our previous Dockerfile
- `image: node-mysql-app`: Define name to our custom image
- `depends_on: - mysqldb`: This will tell docker that the second service will depends on first service
- `stdin_open: true`: This will tell docker that keep open the terminal after complete building container
- `tty: true`: Same as above
- `volumes:`: Last, we tell docker that we have named volume inside our service
- `db-config:`: This is the name of the named volume
- `db-data:`: This is the name of the named volume

> And there we go, that's all is needed for creating our docker app 👍
> Lastly, we will execute this command to start our apps: `docker-compose up`
> After success, you can access your app on **localhost:3000** 🐳

## Summary
With this, We don't need to install MySQL locally to start development right. I think this is the power of docker "To speed up our development process"
That's all I can share with you for now 😊
If you have any question, you can post it here. I hope that I can help to answer it 💪

Or maybe you can reach me on my [Twitter](https://twitter.com/frasnym)
I love to build a new connection 😁

Until then... 🚀