Setup Docker Development for Backend
Tags: webdev, javascript, devops, aws
Published: 2023-12-12 12:12:52

We will dockerize our app using Docker. You don’t have to do this in development mode, but if you are going to have multiple packages running at the same time, this step will help you a lot. You can see the full code [here](https://github.com/akbarnafisa/aws-devops-fullstack/tree/4-setup-docker-development-for-backend).

## Create Dockerfile

To dockerize our app, we will initialize a Dockerfile in the server app.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q6yg84tfk7wcls1yskk7.png)



Because our server code depends on packages from `validation` and `libs`, we need to copy them from the root folder and include the `apps` folder and `packages` folder, treating it as a monorepo in the image.

## Update Database Connection

We will use `.env` variables to set the configuration for the database. We will pass them from Docker Compose later on.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4wo0kf1sgptu46awt2jb.png)



## Setup Environment Variables

We will create two environment variables:

- **`.env`**: This is the environment for Docker Compose. When we initialize it, Docker Compose will read the variables from this file.
- **`.env.dev`**: These are the variables for our database connection. For the **`POSTGRES_HOST`**, we change the value from **`127.0.0.1`** to **`postgres`**. Essentially, we move the host from the local environment to the Docker environment, and the value should match the name of the database service in the Docker Compose.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jd67go9hd96tjw4030n1.png)




![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zgg6nen9t5j88317rmp5.png)



## Add Development Script

We will add two new scripts to run development mode in Docker. The first one is in the server app; we will add the **`concurrently`** package to run the server app and all the packages because we need to import the build result instead of the TypeScript code.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/64ztfuw9olvwi26nzvu0.png)



The last one is to add a script to run Docker Compose in the root **`package.json`**.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yji8obg2x81fw3xwksa1.png)




## Add Docker Compose File

In this Docker Compose, we will create two services. The first one is the server app, and the second one is the PostgreSQL database. For the server app, we will mount our local files to Docker so that we get a nice hot reload when we change our code locally. We also set up the command to run the server app in development mode. For the PostgreSQL database, we create a Docker volume to save our data in the database in Docker. So, if the container is deleted, we still have the data. We also import **`create_tables.sql`** to create the table and insert the data during initialization.

```yaml
version: "3.8"
name: my-project-dev
services:
  server:
    container_name: my-project-dev-server
    restart: unless-stopped
    build:
      context: .
      dockerfile: ./apps/server/dockerfile.dev
    ports:
      - ${SERVER_PORT}:3000
    volumes:
      - .:/main
      - /main/node_modules/
    env_file:
      - ./.env.dev
    depends_on:
      - postgres
    command: >
      sh -c "
        yarn workspace libs run build &&
        yarn workspace validation run build &&
        yarn workspace server dev:concurrently
      "
  postgres:
    image: postgres
    restart: unless-stopped
    container_name: my-project-dev-postgres
    env_file:
      - ./.env.dev
    ports:
      - ${DB_PORT}:5432
    volumes:
      - db:/var/lib/postgresql/data
      - ./apps/server/init-db/create_tables.sql:/docker-entrypoint-initdb.d/create_tables.sql
volumes:
  db:
    driver: local
```

To run the app, we need to execute the command **`yarn compose:dev up`**. This command will build and create a new container for us to run.