Utilize Docker on AWS for seamless deployment and execution

After completing my React and NodeJS projects, I created a Dockerfile for each one and then a docker-compose file to generate docker images for both the frontend and backend.

I have also uploaded the images to my repository on Docker hub. Now, I want to run my Docker project on AWS EC2. I created a new EC2 instance on my AWS dashboard, installed Docker, and managed to download my images from Docker Hub...

But now I'm stuck - should I create a container to run both of them together? Or do I need to run each one separately?

Additionally, I am using Nginx to utilize port 80 instead of the default 3000.

I am feeling lost at the moment as this is my first time working with Docker and AWS. Any guidance would be greatly appreciated!

EDIT 1

This is my Dockerfile for React:

# build environment
FROM node:13.12.0-alpine as build
WORKDIR /app
ENV PATH /app/node_modules/.bin:$PATH
COPY package.json ./
COPY package-lock.json ./
RUN npm ci --silent
RUN npm install <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="d6a4b3b7b5a2fba5b5a4bfa6a2a596e5f8e2f8e7">[email protected]</a> -g --silent
COPY . ./
RUN npm run build

# production environment
FROM nginx:stable-alpine
COPY --from=build /app/build /usr/share/nginx/html
# new
COPY nginx/nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

This is my Dockerfile for Nodejs:

FROM node:8

# Create app directory
WORKDIR /usr/src/app

# Install app dependencies
# A wildcard is used to ensure both package.json AND package-lock.json are copied
COPY package*.json ./

RUN npm install

# Bundle app source
COPY . .

EXPOSE 5000

CMD [ "npm", "start" ]

And here is my Nginx configuration file:

server {

  listen 80;

  location / {
    root   /usr/share/nginx/html;
    index  index.html index.htm;
    try_files $uri $uri/ /index.html;
  }

  error_page   500 502 503 504  /50x.html;

  location = /50x.html {
    root   /usr/share/nginx/html;
  }

}

My docker-compose.yml file looks like this:

version: "2"
services:
  frontend:
    image: itaik/test-docker:frontend
    build: ./frontend
    ports:
      - "80:80"
    depends_on:
      - backend
  backend:
    image: itaik/test-docker:backend
    build: ./backend
    ports:
      - "5000:5000"

On my Windows computer, I downloaded the Docker desktop app and used the 'docker compose-up' command, which created a container with both of my images running successfully. This is the outcome I am aiming for on my AWS EC2 (Linux) setup. I hope things are clearer now.

EDIT 2

Somewhat miraculously, I was able to run both of my images in separate containers, and they are now online as desired. The commands I used were:

docker run -d -p 5000:5000 itaik/test-docker:backend

docker run -d -p 80:80 itaik/test-docker:frontend

However, my API calls to "localhost:5000" are resulting in an error:

GET http://localhost:5000/user/ net::ERR_CONNECTION_REFUSED

Could this issue be related to my React/Nodejs code or how I set up my Docker images?

Thank you for any assistance!

EDIT 3

Even after utilizing docker-compose and having both images running on the same network bridge, I am still encountering the same error.

The only solution that comes to mind is manually modifying my code to replace "localhost" with the public IP provided by AWS. Perhaps there is something crucial I am overlooking... Could it be that my network bridge is not visible to the public IP for some reason?

While I can access the public IP along with port 80 and port 5000, the API call to localhost:5000 continues to produce an error.

Answer №1

If you're looking for the quickest way to get things up and running, follow these steps:

  • Combine your frontend and backend into the same docker image since the backend is already set up to serve the bundle

  • Ensure that hosts and ports are properly configured and the container works on your machine

  • Push the image to DockerHub or AWS ECR

  • Set up a machine on AWS EC2 and install Docker (and Docker Compose if necessary)

  • Configure control groups on your machine to allow incoming traffic on the port your application will serve on (e.g., open port :80)

  • Pull the image and start the container with the port setup as 80:3000 assuming your app serves on :3000 in the container

  • In the AWS EC2 console, find your instance to see the public address of your machine

  • These are some common pitfalls to watch out for

I suggest deploying your app in a single image where Express can easily serve your frontend-app after building it into a static bundle to save time on container communication.

If you still prefer to serve your app with separate frontend (Nginx) and backend (NodeJS) components, use docker-compose ensuring proper host configurations for each component as they won't communicate over localhost.

UPD 2

Your frontend can interact with the backend using two methods while making API calls:

1st way - explicitly setting the axios baseURL to http://<host>:<port> for all API calls pointing to

http://ec2-...amazonaws.com:3000/api/some-data
.

2nd way - letting the browser locate your server where /api/some-data requests become http://yousite.com/api/some-data by assigning location.hostname as the calling host.

...

It's clear that serving content in two containers involves multiple complexities. You can opt to serve static content with express from the 'build' directory instead of using Nginx:

const app = express();
app.use('/', express.static(path.join(__dirname, 'build')));

My recommendation is to first try the explicit host:port setup and enable detailed logging for troubleshooting. Once that's working smoothly, update Nginx for proper functionality.

Best of luck!

Answer №2

If you need to communicate with another Docker service running on the same EC2 instance, there is no requirement to go through the public internet.

Additionally, your React application cannot connect to the backend service using http://localhost:5000 since the backend service is not within the same Docker container.

To access the backend service from the React Docker, try using http://backend:5000. Please verify this and let me know how it goes.

On a side note,

Is your React application meant for public use or internal purposes? If it's intended for the public, consider hosting your React application on Amazon S3, as it supports static website hosting. You can simply upload the React app to an S3 bucket and run it as a static website. This also allows you to enable SSL via CloudFront.

I hope this information proves helpful.

Reference: Learn more about setting up a static website on S3

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

In React, the clearInterval() function does not effectively clear intervals

Currently, I am implementing the following code: startInterval = () => { this.interval = setInterval(this.intervalFunction, 10000) } stopInterval = () => { clearInterval(this.interval) } However, a problem arises when I invoke the stopInte ...

Implement hex key verification during user registration

Currently, I am in the process of following a tutorial on creating a web application for user authentication purposes (signup/login): https://scotch.io/tutorials/easy-node-authentication-setup-and-local One query that I have is regarding adding validation ...

npm ci is encountering a problem with conflicting peer dependencies

I'm currently in the process of installing dependencies from a Dockerfile using the command RUN npm ci. However, I keep encountering an error that says Conflicting peer dependencies. Fix the upstream dependency conflict, or retry this command with --f ...

Zero cookies for React.js with axios

Developing a React app involves sending requests to the backend server using axios. However, I've encountered an issue where the server sends a response with a cookie, but the client does not receive a "Set-Cookie" header in the response. I have confi ...

How to use TypeScript variables in React applications

In my current project, I am attempting to customize a Fabric JS component (Dropdown) using styled-components within a React component. The specific CSS class names are defined in a file located at office-ui-fabric-react/lib/components/Dropdown/Dropdown.sc ...

Error encountered: The character '@' at position 1:0 is unexpected when executing the command @tailwind base within a Docker environment

I am currently deploying my nextJs project using tailwind build Docker, and here is a snippet of my package.json file: (And other dependencies included) { "name": "frontend", "version": "0.1.0", "pri ...

Ways to transfer a state from the child component to the app component

I have 2 different components that contain sub-components within them. In one of these components, I'm trying to figure out how to transfer the click event from the sub-component to another component so that it can render an entirely new component for ...

What is the best way to send the UserId from a payment API endpoint to a webhook endpoint?

insert image description hereI am currently integrating Firebase for user registration and authentication purposes. Additionally, I am incorporating the use of Stripe CLI in my project workflow. One specific requirement is to trigger certain events only fo ...

How can I update or upgrade transitive dependencies in NPM?

In my node server, I am currently using express v4.16.4 which includes cookie-signature v1.0.6. However, I need to upgrade cookie-signature to version 1.1.0 in order to benefit from a crucial fix. How can I accomplish this task? I am hesitant to simply r ...

Issues encountered with Nextjs 13.4 and Next-Auth 4.2 regarding the signIn("credentials", { }); functionality not functioning as expected

When using next-auth credentials in my current project, I encountered an issue with the signIn() function from next-auth/react. It appears that the redirection to the admin page persists regardless of whether the login details are correct or not. {error: n ...

While loop not yielding immediate result with asynchronous function

As a beginner in Node.js, I have successfully connected an LCD Panel and a 4x4 Membrane matrix keypad to my Raspberry Pi. Using Node.js, I have programmed them to work together. My goal is to have the LCD panel immediately display any key pressed on the ke ...

Is there a way to extract an icon from an object or array?

Currently, I am facing challenges in extracting an icon from either an object or an array for a project I am working on. My approach involves storing the icon in a variable and passing it as a prop to another component. However, the functionality is not wo ...

What could be causing the SignatureDoesNotMatch error when attempting to save thumbnail URLs using Firebase Storage Cloud Storage triggers?

Using the firebase resize extension to automatically create resized pictures, such as turning user1profile into user1profile_320x320. A trigger function is in place to update documents in firestore once the thumbnail is generated: const isThumbna ...

Explore how Next.js's getServerSideProps feature incorporates loading animations and improves

I have implemented getServerSideProps in my project's pages/post/index.js file: import React from "react"; import Layout from "../../components/Layout"; function Post({ post }) { console.log("in render", post); return ( <Layout title={pos ...

ESLint is parsing through alternative configurations

My .eslintrc file is very simple: { "extends": [ "twilio" ] } However, when I run eslint, I encounter this error message: The config "standard" was referenced from the config file in "/Users/MyAccount/Projects/my-sample-app/node_modules/cipher ...

What is the proper way to gracefully stop MongoDB using Node.js?

Currently, I have MongoDB running as a child process from my Node.js application and need to be able to shut it down and restart it on demand. I tried using Child_Process.kill("SIGINT") but this seems to leave MongoDB in a confused state that requires manu ...

Discover the best way to utilize useEffect on the server within Next.JS 14!

How can I effectively implement the useEffect functionality in Next.JS server components? I attempted to use useEffect on the server side but it was unsuccessful. Are there alternative hooks that can be utilized on the server side? If not, what is the bes ...

Encounter an error message stating "Request failed with status code 502 nginx in Next.js TypeScript."

After setting up Next.js typescript with Kubernetes NGINX Ingress, I encountered a problem where specific routes were returning a 502 error. For example, the route /test works fine, but /login does not. I'm unsure whether the issue lies with Kubernete ...

Running `bower install` in a Putty session has no effect

Currently working on configuring my project within an Amazon EC2 instance using Bitnami as the AMI. Most things have gone smoothly, however I'm encountering an issue with bower install. Strangely, it's not displaying any errors at all. Just runni ...

Pass a URL string to a different script using Node.js

Currently, I am delving into the world of Node.js, utilizing Express with Jade and Mongoose as my primary tools. Originating from a background in PHP, transitioning to Python, and embracing MVC principles through Django, my aspiration is to create a multip ...