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
-
Consistency Across Environments: Docker ensures that your application runs identically across different machines (developer environments, CI/CD pipelines, and production servers).
-
Simplified Dependency Management: Each service (SQL Server, backend, frontend) is isolated in its own container, avoiding version conflicts.
-
Portability: The entire application stack is defined in a single
docker-compose.yml
file, making it easy to share or replicate the setup. -
Scalability: Docker enables you to scale individual services independently (e.g., scaling the backend API while keeping the database and frontend static).
-
Quick Setup: New developers can clone the repository, run a single command, and have the full stack up and running.
Example Project Setup
Prerequisites
- Install Docker Desktop (includes Docker Compose).
- Clone the project repository.
- 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
-
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.
- Runs in its own container, accessible on port
-
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.
- Communicates with SQL Server using the internal Docker network (
-
Frontend Service:
- Runs a React or other frontend framework on port
3000
. - Communicates with the backend service at
http://backend:7087
(via Docker network).
- Runs a React or other frontend framework on port
Setting Up and Running the Project
-
Clone the Repository:
git clone https://github.com/AshyLarryM/Finance-Tracker-React-DotNet-API.git
-
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
-
Build and Start the Containers:
docker-compose up --build
-
Access the Services:
- SQL Server:
localhost:1433
- Backend API:
http://localhost:7087
- Frontend App:
http://localhost:3000
- SQL Server:
-
Stop the Containers:
docker-compose down
Best Practices
-
Use Volumes for Persistent Data: Mount a volume for SQL Server to ensure data persists between container restarts:
volumes: - sqlserver-data:/var/opt/mssql
-
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
. -
Optimize Docker Images: Use smaller base images (e.g.,
node:alpine
,mcr.microsoft.com/dotnet/aspnet:8.0-alpine
) for better performance. -
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.