Step 6: Deployment

Intro

Just like in Part 4, we will need Docker to deploy our web application. This time, the application will consist of two parts, so two containers will created.

Luckily, we can fully reuse the Dockerfile from Part 4. All we need to do is to containerise the frontend application and make backend and frontend work together.

Build the Docker image for the backend app

Copy the source code of the backend application onto the server and then run this command on the server (in the backend app’s source folder):

docker build --tag sc-tutorial-part-5-be:latest .
Mind the dot in the end of the docker build command.

Dockerfile for the frontend app

Create a Dockerfile in the root of the application’s frontend with the following lines:

Dockerfile
FROM node:18.14 
WORKDIR /app
COPY . .
RUN npm ci 
RUN npm run build
ENV NODE_ENV production
EXPOSE 3000
CMD [ "npx", "serve", "build" ]

The base image will have a pre-installed Node.js inside. Then the app folder will be created in the root of the new image’s file system, our frontend application will be copied into it, and the build will be executed. Finally, when a new Docker container is started with this image, the frontend application will be served on the default port 3000.

Build the Docker image for the frontend app

Copy the source code of the frontend application (including the Dockerfile) to an environment where Docker is available (we will call it 'the server').

On the server, go to the folder with frontend app source code and update the .env file: replace 'localhost:8080' with the address of your server and port 13500 (this is the port the backend app will be listening).

For example, your .env file may now look like this:

env file (updated)
REACT_APP_API_URL=http://my-server-address.com:8080

You can also use the IP address instead of the domain name. If you deploy the backend to your local machine, then you can keep the 'localhost' part as it is (but remember to update the port number).

After that, run the following command:

docker build --tag sc-tutorial-part-5-fe:latest .

So, now both images are locally available on the server.

Docker Compose

We will start both the backend and the frontend apps in one step using the Docker Compose.

Create the following docker-compose.yml file anywhere on the server where you have just created two Docker images:

docker-compose.yml
version: '3.3'
services:
  sc-tutorial-part-5-be:
    container_name: sc-tutorial-part-5-be
    hostname: sc-tutorial-part-5-be
    image: sc-tutorial-part-5-be
    ports:
      - 13500:8080
    expose:
      - 8080
    environment:
      - APP_PORT=8080
  sc-tutorial-part-5-fe:
    container_name: sc-tutorial-part-5-fe
    hostname: sc-tutorial-part-5-fe
    image: sc-tutorial-part-5-fe
    ports:
      - 3000:3000
    expose:
      - 3000

In the folder with the docker-compose.yml file, run the following commands to start both the backend and the frontend:

docker compose up -d
docker compose logs --no-color --follow --timestamps sc-tutorial-part-5-be > ./sc-tutorial-part-5-be-$(date +%Y%m%d_%H%M%S).log &
docker compose logs --no-color --follow --timestamps sc-tutorial-part-5-fe > ./sc-tutorial-part-5-fe-$(date +%Y%m%d_%H%M%S).log &
On older versions of Docker, the 'compose' subcommand is not available. In that case, you may need to update the Docker installation. Alternatively, you can install Docker Compose as a separate binary and write docker-compose instead of docker compose in the commands above.

The first command launches two containers (services) as defined in the docker-compose.yml file. Both are launched in the background. The other two commands place the logs generated by those services into local log files - they can help a lot with debugging.

Check the result

To see the launched containers, run this command:

docker ps -a

There should be 'sc-tutorial-part-5-be' and 'sc-tutorial-part-5-be' containers with status 'Up <duration>'.

Now, try to access the web application via your browser. Open the link http://your-server-address:3000 (replace the address part with your server domain name or IP).

You should see the web application page:

A complete frontend
Figure 1. A complete frontend

When you will need to stop the containers, go to the folder with the docker-compose.yml file and run this command:

docker compose down

So, now your web application is online. Good job!