Most of the time, dotnet developers setup and configure a windows server and then occupy the entire server for a single project or a micro service project using web services. Then handling and maintaining the server and IIS inside the server would cost a lot of load on server maintainance.
Contianerize environment would help devops culure and development to push CI/CD in an easiest and fastest way. dotnet developers are one of the development team which will go through package managers and container based architecture as last option.
Here I tried to share some playing on docker containers to setup a dotnet project with out gui, and then another environment who has a dashboard using angularjs
.
we assume you have already installed docker and you are familiar with docker concepts. As an example, We have a project contain 2 sub-projects (service, dashboard).
We will start by creating 2 containers for each sub-projects using different port and then run together.
configure dockerfile for services
let’s create a Dockerfile
inside the project folder and name as DockerfileService
.
Since the Dockerfile might be big and you only need to update the code with in the container, so we prepare a dockerfile using stage based:
FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build-env
WORKDIR /app
COPY . ./
WORKDIR /app/services
RUN dotnet restore
RUN dotnet publish -c Release -o out
FROM mcr.microsoft.com/dotnet/core/aspnet:2.2 AS runtime
WORKDIR /app/services
COPY --from=build-env /app/services/out .
RUN mkdir -p /app/services/out/logs
ENV ASPNETCORE_ENVIRONMENT=Staging
ENV ASPNETCORE_URLS http://*:8888
EXPOSE 8888
ENTRYPOINT ["dotnet", "services.dll"]
As you can see the first image will prepare an image using dotnetcore sdk only then will restore and publish the project to prepare the DLLs and runnable files.
second image will prepare an aspnet:2.2 as webservice and then host the components and files build via previous image. The container would assign 2 variables and then expose the port on 8888.
Note: you can create Dockerfile inside each sub-project and then remove services
from the path.
Now, we can build and image by running below command:
docker build -t myservice -f DockerfileService .
It will generate a docker image called myservice
.
configure dockerfile for dashboard
Making a docker file for dashboard is a bit different since we might need to run different modules like nodejs to prepare the build and entire environment for presenting GUI.
Assume we have a portal using angular js build using gulp, bower and node.
Let’s create another Dockerfile
and name as DockerfileDashboard
.
FROM microsoft/dotnet:sdk AS dashboard
WORKDIR /app
COPY . ./
WORKDIR /app/Dashboard
RUN dotnet restore
RUN dotnet publish -c Release -o out
COPY ./Dashboard/ ./out/
ENV NODE_VERSION 8.9.4
ENV NODE_DOWNLOAD_URL https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.gz
ENV NODE_DOWNLOAD_SHA 21fb4690e349f82d708ae766def01d7fec1b085ce1f5ab30d9bda8ee126ca8fc
RUN curl -SL "$NODE_DOWNLOAD_URL" --output nodejs.tar.gz \
&& echo "$NODE_DOWNLOAD_SHA nodejs.tar.gz" | sha256sum -c - \
&& mkdir -p /usr/local/opt/nodejs8 \
&& tar -xzf "nodejs.tar.gz" -C /usr/local/opt/nodejs8 --strip-components=1 \
&& rm nodejs.tar.gz \
&& ln -f -s /usr/local/opt/nodejs8/bin/node /usr/local/bin/node \
&& ln -f -s /usr/local/opt/nodejs8/bin/node /usr/local/bin/nodejs
WORKDIR /app/Dashboard
COPY --from=dashboard /app/Dashboard/out .
RUN mkdir -p /app/Dashboard/logs
RUN curl -sL https://deb.nodesource.com/setup_8.x | bash -
RUN apt-get install -y nodejs build-essential bzip2 libkrb5-dev git
ENV ASPNETCORE_ENVIRONMENT=Staging
ENV ASPNETCORE_URLS http://*:80
RUN echo '{ "allow_root": true }' > /root/.bowerrc
RUN rm -rf node_modules && npm cache clean --force \
&& npm config set prefix /usr/local \
&& npm install -g bower gulp
RUN npm install
RUN npm install --save-dev gulp
RUN npm install --save-dev bower
RUN bower install --allow-root
RUN bower install moment --allow-root
RUN gulp clean
RUN gulp build
RUN npm link gulp
EXPOSE 3000 3001 80
CMD ["gulp", "serve"]
Here we are using an image from dotnetsdk, then we install our requirments (Node, bower and gulp) and then at the endwe expose port 80 and serve gulp on that port.
Now, we can build the second image for dashboard running below command:
docker build -t mydashboard -f DockerfileDashboard .
It will generate a docker image called mydashboard
.
2 Dockerfiles and built images are ready to be used in any package managers like Kubernetes or docker-compose.
As mentioned earlier we can put each docker file inside the folders and then route build separately or give the route to package manager.
For example let’s have a simple docker-compose
to run this 2 images plus a mysql container once:
version: '3'
services:
myservice:
build:
context: ./
dockerfile: DockerfileService
ports:
- "8888:8888"
volumes:
- ./:/var/www
container_name: myservice
environment:
- "ASPNETCORE_ENVIRONMENT=Staging"
links:
- mysqldb
restart: on-failure
depends_on:
- mysqldb
mydashboard:
build:
context: ./
dockerfile: DockerfileDashboard
ports:
- "80:80"
volumes:
- ./:/var/www
container_name: myservice
environment:
- "ASPNETCORE_ENVIRONMENT=Staging"
links:
- mysqldb
restart: on-failure
depends_on:
- mysqldb
mysqldb:
image: mysql:5.7.27
hostname: "mysqldb"
container_name: mysqldb
restart: unless-stopped
ports:
- 3306:3306
command: --init-file /data/application/init.sql --max_allowed_packet=2G
environment:
MYSQL_ROOT_USER: root
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: mysql
MYSQL_USER: devuser
MYSQL_PASSWORD: devpass
TZ: UTC
MYSQL_ROOT_HOST: "%"
volumes:
- ./dbdata/mysql/initdb.d/init.sql:/data/application/init.sql
- ./dbdata/mysql/conf.d:/etc/mysql/conf.d:ro
volumes:
dbdata:
Hope this would help to run your project faster and setup CI/CD easier Good Luck