Setting Up Docker for Development

December 30, 2024

Setting Up Docker for a Project with SQL Server, Backend, and Frontend

Overview

Docker simplifies the setup and management of projects that require multiple services, such as a SQL Server database, a backend API, and a frontend application. By containerizing your services, Docker ensures consistency across development, testing, and production environments, while also isolating dependencies and avoiding conflicts.

This guide explains how Docker can help you efficiently manage a project requiring:

  • SQL Server for database management.
  • Backend API running on one port.
  • Frontend application running on another port.

Benefits of Using Docker

  1. Consistency Across Environments: Docker ensures that your application runs identically across different machines (developer environments, CI/CD pipelines, and production servers).

  2. Simplified Dependency Management: Each service (SQL Server, backend, frontend) is isolated in its own container, avoiding version conflicts.

  3. Portability: The entire application stack is defined in a single docker-compose.yml file, making it easy to share or replicate the setup.

  4. Scalability: Docker enables you to scale individual services independently (e.g., scaling the backend API while keeping the database and frontend static).

  5. Quick Setup: New developers can clone the repository, run a single command, and have the full stack up and running.


Example Project Setup

Prerequisites

  1. Install Docker Desktop (includes Docker Compose).
  2. Clone the project repository.
  3. Ensure the .env file is configured with necessary environment variables (e.g., database credentials, API keys).

docker-compose.yml

The docker-compose.yml file defines the services for your project:

version: "3.8"

services:
  sqlserver:
    image: mcr.microsoft.com/mssql/server:2022-latest
    container_name: sqlserver
    environment:
      SA_PASSWORD: ${SA_PASSWORD}
      ACCEPT_EULA: "Y"
    ports:
      - "1433:1433"
    volumes:
      - ./data/init.sql:/docker-entrypoint-initdb.d/init.sql
    networks:
      - app-network

  backend:
    build:
      context: ./backend
    ports:
      - "7087:7087"
    environment:
      - ConnectionStrings__DefaultConnection=${DB_CONNECTION_STRING}
      - JWT__Issuer=http://localhost:7087
      - JWT__Audience=http://localhost:7087
      - JWT__SigningKey=${JWT_SIGNING_KEY}
    depends_on:
      - sqlserver
    networks:
      - app-network

  frontend:
    build:
      context: ./frontend
    ports:
      - "3000:80"
    depends_on:
      - backend
    networks:
      - app-network

networks:
  app-network:
    driver: bridge

How It Works

  1. SQL Server Service:

    • Runs in its own container, accessible on port 1433.
    • Includes an initialization script (init.sql) to set up your database schema or seed data.
  2. Backend Service:

    • Communicates with SQL Server using the internal Docker network (sqlserver hostname).
    • Exposes an API on port 7087.
    • Reads environment variables (e.g., connection strings, JWT keys) for configuration.
  3. Frontend Service:

    • Runs a React or other frontend framework on port 3000.
    • Communicates with the backend service at http://backend:7087 (via Docker network).

Setting Up and Running the Project

  1. Clone the Repository:

    git clone https://github.com/AshyLarryM/Finance-Tracker-React-DotNet-API.git
    
  2. Configure Environment Variables: Create a .env file in the project root:

    SA_PASSWORD=YourStrong!Password
    DB_CONNECTION_STRING=Server=sqlserver,1433;Database=MyApp;User Id=sa;Password=YourStrong!Password;
    JWT_SIGNING_KEY=YourSecretKey
    
  3. Build and Start the Containers:

    docker-compose up --build
    
  4. Access the Services:

    • SQL Server: localhost:1433
    • Backend API: http://localhost:7087
    • Frontend App: http://localhost:3000
  5. Stop the Containers:

    docker-compose down
    

Best Practices

  1. Use Volumes for Persistent Data: Mount a volume for SQL Server to ensure data persists between container restarts:

    volumes:
      - sqlserver-data:/var/opt/mssql
    
  2. Separate Environment Variables: Keep sensitive information (e.g., passwords, API keys) out of version control by using a .env file and adding it to .gitignore.

  3. Optimize Docker Images: Use smaller base images (e.g., node:alpine, mcr.microsoft.com/dotnet/aspnet:8.0-alpine) for better performance.

  4. Add Health Checks: Ensure services are ready before dependent containers start:

    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:7087/health"]
      interval: 30s
      timeout: 10s
      retries: 3
    

Conclusion

Using Docker for a project requiring a SQL Server, backend API, and frontend application streamlines setup and ensures a consistent environment across all stages of development. By defining all services in a docker-compose.yml file, you can quickly spin up your entire stack, making it easier to focus on building and deploying your application.

Back to home