Developers often need to install and configure different applications, technologies, and services for local project development. When there is one project and you are working, for example, with one version.NET, or if all developers work on Windows, then any problems with the project configuration are unlikely to appear.
But what if you periodically need to switch between different versions of Java, PHP, Node.js, and even one developer has Linux installed, and the other has Windows? Of course, you can write installation and configuration instructions, but this does not solve the problem of isolation of your operating system from the application environment.
After deleting the already installed version .NET, SQL Server may remain any configuration files that may lead to an error starting another installed version of the application.
To solve similar application startup problems .NET, SQL Server on different environments, you can use Docker, Docker Compose.
1. Installing Docker, Docker Compose
To install Docker, we need to open the manual for the required OS on the Install Docker Engine page.
To install Docker Compose — on the Install Docker Comrose page, also open the manual for the required OS.
We check that Docker and Docker Compose are working by executing commands in the console:
$ docker-compose -v
docker-compose version 1.28.6, build unknown
$ docker-compose --version
docker-compose version 1.28.6, build unknown
2. Creating the project directory structure
For my projects where Docker is used, I adhere to the following structure:
- src — the source code of the project
- docker:
- api directory with configuration files, docker file for image assembly.NET applications,
- db — directory with configuration files, docker file for SQL Server image assembly, migrations,
docker-compose.yml file with container launch settings.
3. Formation of Docker files for .NET, SQL Server
3.1. Configuring the image.NET Docker
For work .NET applications create a Dockerfile file in the project directory with the path docker/api/Dockerfile:
FROM mcr.microsoft.com/dotnet/aspnet:3.1-focal AS base
WORKDIR /app
EXPOSE 5000
ENV ASPNETCORE_URLS=http://+:5000
ENV ASPNETCORE_ENVIRONMENT Development
# Creates a non-root user with an explicit UID and adds permission to access the /app folder
# For more info, please refer to https://aka.ms/vscode-docker-dotnet-configure-containers
RUN adduser -u 5678 --disabled-password --gecos "" appuser && chown -R appuser /app
USER appuser
FROM mcr.microsoft.com/dotnet/sdk:3.1-focal AS build
WORKDIR /src
COPY ["./src/app.csproj", "/src"]
COPY ["./nuget.config", "./"]
RUN dotnet restore "app.csproj"
COPY ./src .
WORKDIR "/src"
RUN dotnet build "app.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "app.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "app.dll"]
3.2. Configuring the SQL Server Docker Image
For SQL Server to work, we will create a Dockerfile file in the project directory with the path docker/db/Dockerfile, the contents of which:
FROM flyway/flyway:8.0.4-alpine
COPY ./*.sql /flyway/sql/
COPY ./flyway.conf /flyway/conf/
ENTRYPOINT [ "flyway", "migrate" ]
3.3. create a configuration file /docker/db/migrations/flyway.conf with the contents:
flyway.url=jdbc:sqlserver://mssql-db
flyway.user=sa
flyway.password=Your_password123
flyway.mixed=true
3.3.1. create a migration file in the directory /docker/db/migrations/V1__DatabaseCreation.sql with the contents:
USE [master]
GO
CREATE DATABASE [TEST]
GO
USE [TEST]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE SCHEMA data AUTHORIZATION dbo;
GO
CREATE TABLE [dbo].[test](
[Id] [int] NOT NULL,
[Name] [varchar](30) NOT NULL
) ON [PRIMARY]
GO
INSERT INTO [dbo].[test] ([Id], [Name])
VALUES (1, 'User1')
GO
You can read more about working with migrations using Flyway here:
— https://flywaydb.org/documentation/,
— https://flywaydb.org/documentation/
4.Creating a docker-compose.yml file
So, all we have to do is create a docker-compose file.yml to describe all the services in it:
- db — service for MS SQL Server operation,
- db-migration — service for working with Flyway migrations,
- api service for working with a .NET application.
Let’s create a docker-compose file.yml in the project directory with the docker/docker-copmose path.yml and content:
version: "3.4"
services:
api:
build:
context: "../"
dockerfile: ./docker/api/Dockerfile
container_name: "api"
ports:
- "5000-5001:5000-5001"
depends_on:
- db
- db-migrations
networks:
- app-network
db:
build:
context: "./db"
container_name: "db"
environment:
SA_PASSWORD: "Your_password123"
ACCEPT_EULA: "Y"
ports:
- "1433:1433"
networks:
- app-network
db-migrations:
build:
context: "./db/migrations"
container_name: "db-migrations"
volumes:
- ./db/migrations:/flyway/sql
networks:
- app-network
depends_on:
- db
networks:
app-network:
driver: bridge
5. Launching the application
To launch, we need to launch Docker containers using the docker-compose command. From the project directory, we execute the command in the terminal:
cd ./docker && docker-compose up -d --force-recreate --build
after that, our application should open in the browser at the url: http://localhost:5000
We can connect to SQL Server using the command:
sqlcmd -S db -d TEST -G -U sa
by specifying a password Your_password123
Useful links
- Textbook. Containerization of the application .NET Core
- Docker images for ASP.NET Core
- The images page .NET
- Setup guide .NET and SQL Server
- Flyway Documentation: https://flywaydb.org/documentation /, https://flywaydb.org/documentation/