DEV Community

loading...
Cover image for How to Create Dockerized NodeJS with MySQL Database

How to Create Dockerized NodeJS with MySQL Database

frasnym profile image Frastyawan Nym ・3 min read

TLDR;
You can access the code here on Github
(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:
Enter fullscreen mode Exit fullscreen mode

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 🚀

  1. Now we make our NodeJS app, inside of app folder
  2. You can initialize npm as usual
  3. 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" ]
Enter fullscreen mode Exit fullscreen mode

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

  1. 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:
Enter fullscreen mode Exit fullscreen mode

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
I love to build a new connection 😁

Until then... 🚀

Discussion (4)

pic
Editor guide
Collapse
tremainebuchanan profile image
Tremaine Buchanan

Nice post. But I think for newbies, you could specific what values should be contained in the .env as this file would've left out of the repository. You can go even further to include the .env with the keys and omit the values such that newbies can fill in the blanks.

Collapse
frasnym profile image
Frastyawan Nym Author

Ah I see, thank you for your correction 🙏
I have updated the source code 🤝

Collapse
pedromirandareis profile image
Pedro Miranda • Edited

This is exactly what Im looking for, thanks for your hard work!

Mysql is working fine but json dont

Error: Cannot find module 'dotenv'
Require stack:

  • /app/index.js at Function.Module._resolveFilename (internal/modules/cjs/loader.js:880:15) at Function.Module._load (internal/modules/cjs/loader.js:725:27) at Module.require (internal/modules/cjs/loader.js:952:19) at require (internal/modules/cjs/helpers.js:88:18) at Object. (/app/index.js:1:1) at Module._compile (internal/modules/cjs/loader.js:1063:30) at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10) at Module.load (internal/modules/cjs/loader.js:928:32) at Function.Module._load (internal/modules/cjs/loader.js:769:14) at Function.executeUserEntryPoint as runMain
Collapse
frasnym profile image
Frastyawan Nym Author

Hello,

It's like that you don't install dotenv module 🤔
Can I see you package.json file? or project repo if possible?