DEV Community

Cover image for Why do Frontend and Backend developers use Docker
Ajeet Singh Raina
Ajeet Singh Raina

Posted on • Edited on • Originally published at collabnix.com

Why do Frontend and Backend developers use Docker

Imagine you're building a simple to-do list app. It seems straightforward: a frontend to display tasks and a backend to store them. But let’s dive deeper and consider the following tech stack:

Tech Stack #1

  • Frontend: Reactjs, Vite, CSS Preprocessor
  • Backend: Nodejs, API Server
  • Database: Mongo, Mongo Express

Image1

The frontend, let's say, is a React app. It requires Vite, CSS Preprocessor and a specific React version. The backend, a Nodejs app, needs Node, API Server, a database (like Mongo/Postgres), and a few libraries. These are just the basics.

Pain-Points

  • Environment inconsistencies: Different developers may have varying operating system versions, software installations, and configurations, leading to discrepancies in application behavior.
  • Dependency management challenges: Keeping track of and managing dependencies across frontend and backend can be time-consuming and error-prone.
  • Slow development cycles: Setting up new development environments for each team member can be lengthy, hindering productivity.
  • Deployment complexities: Replicating the development environment in production can be difficult due to environment-specific configurations.

Using Docker

Docker can streamline development, improve collaboration, and provide a solid base for future growth.

1. Consistent Development Environment:

  • Reproducibility: Every developer can have an identical environment by using the same Docker image. This eliminates the "works on my machine" problem.  
  • Isolation: Docker containers isolate the application from the host system, preventing conflicts with other software.  

2. Faster Development and Deployment:

  • Quick setup: New developers can quickly spin up a development environment without installing numerous dependencies.
  • Rapid deployment: Docker containers can be easily deployed to different environments (development, testing, production) with minimal configuration.  

3. Improved Collaboration:

  • Shared environment: Team members can share the Docker image, ensuring everyone works on the same codebase and dependencies.  

4. Foundation for Future Growth:

  • Scalability: While not immediately necessary for a simple to-do list, Docker provides a foundation for future scaling if the application grows in complexity.
  • Microservices architecture: If you decide to break the application into smaller services, Docker is an excellent tool for managing those services.

Clone the repository, switch to a branch called "basic" and bring up your application stack

services:
  frontend:
    build: frontend
    ports:
      - 3000:3000
    stdin_open: true
    volumes:
      - ./frontend:/usr/src/app
      - /usr/src/app/node_modules
    container_name: frontend
    restart: always
    networks:
      - react-express
    depends_on:
      - backend

  backend:
    container_name: backend
    restart: always
    build: backend
    volumes:
      - ./backend:/usr/src/app
      - /usr/src/app/node_modules
    depends_on:
      - mongo
    networks:
      - express-mongo
      - react-express
    expose: 
      - 3000
  mongo:
    container_name: mongo
    restart: always
    image: mongo:4.2.0
    volumes:
      - mongodata:/data/db
    networks:
      - express-mongo
    expose:
      - 27017

  mongoexpress:
    image: mongo-express
    restart: always
    ports:
      - 8081:8081
    environment:
      ME_CONFIG_MONGODB_URL: mongodb://mongo:27017/
    networks:
      - express-mongo

networks:
  react-express:
  express-mongo:

volumes:
  mongodata:
Enter fullscreen mode Exit fullscreen mode

Tech Stack #2

  • Frontend: Reactjs, Vite, CSS Preprocessor
  • Backend: Nodejs, API Server
  • Task Management DB: Mongo, Mongo Express
  • Image Storage: AWS S3

awslocal

Pain Points:

  • Complex environment setup: Requires setting up Node.js, database, image storage (AWS S3 or similar), and potentially other dependencies.
  • Dependency management: Managing dependencies for the application, database, and image storage can be challenging.
  • Inconsistent environments: Different developers may have different setups, leading to discrepancies.
  • Deployment complexities: Deploying to production involves configuring multiple services.

How Docker Helps

  • Consistent environment: Creates a standardized environment for development, testing, and production.
  • Simplified setup: Developers can quickly start working by pulling a Docker image.
  • Dependency management: Packages all dependencies within the container, eliminating external dependencies.
  • Efficient deployment: Containers can be easily deployed to different environments.
  • Integration with AWS S3**: Docker can be integrated with AWS to manage the image storage component.

By using Docker, you can create a self-contained environment for your to-do list application, including the image storage component. This simplifies development, deployment, and maintenance.

Clone the repo, switch to the container-first-aws branch and bring up the application stack.

services:
  server:
    build:
      context: ./server
      dockerfile: Dockerfile
    ports:
      - 5000:5000
    environment:
      - MONGODB_URI=mongodb://mongodb:27017/todo-app
      - JWT_SECRET=603b31XXXXXXX90d3b8cb62f0a585fd70a5ee0b4d
      - AWS_ACCESS_KEY_ID=AKIAXXXXXDDDX
      - AWS_SECRET_ACCESS_KEY=hSYXtvXXXXXXXO/k39FGt3u078pYWsh
      - AWS_REGION=us-east-1
      - S3_BUCKET_NAME=localbuckett
    networks:
      - localnet

  client:
    build:
      context: ./client
      dockerfile: Dockerfile
    ports:
      - 3000:3000
    depends_on:
      - server
    networks:
      - localnet

  mongodb:
    image: mongo
    volumes:
      - mongodbdata:/data/db
    ports:
      - 27017:27017
    networks:
      - localnet

volumes:
  mongodbdata:

networks:
  localnet:
Enter fullscreen mode Exit fullscreen mode

Tech Stack #3

  • Frontend: Reactjs, Vite, CSS Preprocessor
  • Backend: Nodejs, API Server
  • Task Management DB: Mongo, Mongo Express
  • Image Storage: AWS S3
  • Task Prioritisation
  • Authentication

Image22

Pain Points Without Docker

  • Complex environment setup: Requires setting up Node.js, database, image storage, authentication, and potentially additional services.
  • Dependency management: Managing dependencies for multiple components becomes challenging.
  • Environment inconsistencies: Different development environments can lead to issues.
  • Deployment complexities: Deploying to production involves coordinating multiple services.
  • Scalability challenges: Scaling individual components can be difficult without proper infrastructure.

How Docker Helps

  • Isolated environments: Creates isolated environments for each component, preventing conflicts.
  • Simplified setup: Developers can quickly start working by pulling Docker images.
  • Dependency management: Packages all dependencies within containers.
  • Efficient deployment: Containers can be easily deployed to different environments.
  • Scalability: Docker can be used with orchestration tools for easy scaling.
  • Security: Containers provide an additional layer of security.

By using Docker, you can manage the complexities of a multi-component application more effectively. Containers provide a consistent and isolated environment for each part of the system, making development, testing, and deployment smoother.

Clone the repo, switch to the container-supported branch and bring up the application stack

services:
  server:
    build:
      context: ./server
      dockerfile: Dockerfile
    ports:
      - 5000:5000
    depends_on:
      - localstack
      - mongo
    dns:
      - 10.0.2.20
    environment:
      - MONGODB_URI=mongodb://mongo:27017/todo-app
      - JWT_SECRET=XXXXX
      - AWS_ENDPOINT=http://host.docker.internal:4566
      - AWS_ACCESS_KEY_ID=test
      - AWS_SECRET_ACCESS_KEY=test
      - AWS_REGION=us-east-1
      - S3_BUCKET_NAME=sample-bucket
    networks:
      - localnet

  client:
    build:
      context: ./client
      dockerfile: Dockerfile
    ports:
      - 3000:3000
    depends_on:
      - server
    environment:
     - REACT_APP_API_URL=http://server:5000/api
    networks:
      - localnet

  mongo:
    image: mongo
    volumes:
      - mongo-data:/data/db
    ports:
      - "27017:27017"
    networks:
      - localnet

  localstack:
    container_name: "${LOCALSTACK_DOCKER_NAME:-localstack-main}"
    image: localstack/localstack
    ports:
      - "127.0.0.1:4566:4566"
      - "127.0.0.1:4510-4559:4510-4559"
    environment:
      - DEBUG=${DEBUG:-0}
      - SERVICES=s3
    volumes:
      - "${LOCALSTACK_VOLUME_DIR:-./volume}:/var/lib/localstack"
      - "/var/run/docker.sock:/var/run/docker.sock"
    networks:
      localnet:
        ipv4_address: 10.0.2.20

volumes:
  mongo-data:

networks:
  localnet:
    ipam:
      config:
        # Specify the subnet range for IP address allocation
        - subnet: 10.0.2.0/24
Enter fullscreen mode Exit fullscreen mode

As your app grows, so do the dependencies. You might add a task reminder service written in Rust, a machine learning model for task prioritization, and a real-time updates feature using WebSockets.

Imagine You, a developer on the frontend team, need to set up your local environment to test integrations. You'll need to install Node.js, npm, Reactjs, CSS, PostgreSQL, Rust, and all their dependencies. This is a daunting task. And if you're working with a team, coordinating these installations and ensuring everyone has the same environment becomes a nightmare.

Docker: The Orderly Container

Docker is like a shipping container for your applications. It packages your app and all its dependencies into a self-contained unit. This unit can be shipped and run consistently on any machine with Docker installed.

For Frontend Developers

  • Consistent Development Environment: Docker ensures everyone on the frontend team has the same - development environment. No more "it works on my machine" issues.
  • Rapid Setup: Instead of installing Node.js, npm, and other tools, you simply pull a Docker image containing your frontend environment and start working.
  • Isolation: Docker isolates your frontend from the backend, preventing conflicts and making debugging easier.
  • Collaboration: Share your development environment with other team members by sharing the Docker image.

For Backend Developers

  • Micro services Management: Docker is perfect for managing complex microservice architectures. Each service can be packaged into its own container, simplifying deployment and scaling.
  • Dependency Management: Docker handles dependencies efficiently, ensuring consistent environments for different services.
  • Environment Consistency: Developers can work on their local machines with the same environment as production, reducing discrepancies.
  • Rapid Deployment: Docker containers can be quickly deployed to different environments (development, testing, production) with minimal configuration.

A More Complex Scenario

Tech Stack #4

  • Frontend: Reactjs, Vite, CSS Preprocessor
  • Backend: Nodejs, API Server
  • Database for Text: MySQL, PhpmyAdmin
  • Database for Image: Localstack(Emulated AWS S3)
  • Task Prioritisation: ML Model
  • Task Reminder Service: Rust

localstack

Let's expand our to-do list app. We add features like geolocation-based reminders, image uploads, and user authentication. The backend now involves multiple microservices: one for task management, another for location services, a third for image storage, and a fourth for authentication.

Pain Points Without Docker

  • Complex dependency management: Coordinating dependencies for multiple microservices is challenging.
  • Environment setup: Setting up individual environments for each microservice is time-consuming.
  • Orchestration: Managing the interactions and dependencies between microservices without a tool is difficult.
  • Deployment and scaling: Deploying and scaling multiple microservices independently is complex.  

How Docker Helps

  • Isolated environments: Creates isolated environments for each microservice.  
  • Dependency management: Packages dependencies within each container.  
  • Orchestration: Tools like Docker Compose, Swarm and Kubernetes can manage multiple containers.  
  • Deployment and scaling: Docker simplifies deployment and scaling of microservices.  
  • Efficient resource utilization: Docker containers share the host OS kernel, improving resource efficiency compared to virtual machines.   Docker is an ideal tool for managing complex microservice architectures. It provides the necessary isolation, portability, and scalability to handle the challenges associated with multiple interconnected services

Without Docker, setting up this environment would be a colossal undertaking. You'd need to manage different programming languages, databases, and libraries. Dependencies would multiply, and conflicts would become inevitable.With Docker, each microservice gets its own container. The frontend can interact with these services through their respective container ports. This isolation and standardization make development, testing, and deployment significantly more efficient.

Conclusion

Docker is not just a tool; it's a game-changer. By providing a consistent, isolated, and portable environment for applications, Docker empowers both frontend and backend developers to focus on building great software without getting bogged down by infrastructure complexities.

Would you like to dive deeper into specific Docker commands or explore advanced use cases?

Top comments (0)