Automated Deployment of .NET Application to Windows IIS Server

You are on page 1of 12

Automated deployment of .

NET application to Windows


IIS server using GitLab runner

Considerations before reading:

1. My server nickname was: “nikola.perisic”


2. My project folder was called “galactic-resistance”
3. In CI/CD jobs I have done checkout to the “development” branch
4. This was written in August 26. 2024. so may be outdated
5. My project name on GitLab was “infection-index”
Contact me at: https://linkedin.com/in/perisicnikola37
TABLE OF CONTENTS

Step 1: Install GitLab Runner on Windows IIS Server..............................................................3


Step 2: Configure GitLab Runner on the Windows IIS server................................................. 4
Step 3: Modify the “config..toml” file.........................................................................................5
Step 4: Create “.gitlab-ci.yml” file..............................................................................................5
The first stage(job)...................................................................................................................6
The second stage(job)............................................................................................................. 7
The third stage(job)..................................................................................................................8
Possible problem.......................................................................................................................10
Privilege issue........................................................................................................................10
A more complex example of pipeline code............................................................................. 11

2
Step 1: Install GitLab Runner on Windows IIS Server

1.1. Connect to your server using the provided credentials


1.2. Open your web browser(e.g., Chrome)
1.3. Navigate to the following URL: GitLab Runner for Windows Installation Guide
1.4. Click on the “64-bit” to download the GitLab Runner executable(.exe) or click
here
1.5. Navigate to the root of your “C:\” drive and there create a new folder named
“GitLab-Runner”
1.6. Move the previously downloaded .exe file into this folder
1.7. Rename the file to “gitlab-runner”
1.8. Run “gitlab-runner.exe” file. Note that a brief flash on the screen is
expected; this is normal. You need to start this service. To verify the service is
running, follow these steps:
- Type “Services” in the Windows search bar
- Locate the “gitlab-runner” service and confirm its status is set to
“Running”

3
Step 2: Configure GitLab Runner on the Windows IIS server

1.1. Open “Command Prompt” with administrator privileges


1.2. Enter the following command “cd C:\GitLab-Runner”
1.3. Enter the following command “.\gitlab-runner.exe register”

Question prompts you will get:

Enter the GitLab instance URL -> type the following:


https://git.url.rs

Enter the registration token -> type the token which you can find
here(Your GitLab repository -> Settings -> CI/CD -> Runners -> Three
dots -> Copy registration token)

Enter a description for the runner -> Type some description for the
runner

Enter tags for the runner -> Type some tags for the runner(Remember
these!)

Enter optional maintenance note for the runner -> This is optional

And at the end, you will see such output like this one:

Here you need to provide which executor you want to use. I suggest
typing “shell” here but you can modify this later.

Upon completion, you should receive a confirmation similar to:


"Configuration (with the authentication token) was saved in
'C:\\GitLab-Runner\\config.toml'."

4
Navigate to “C:\GitLab-Runner” and ensure the presence of the following
files:

You will find the following files:


- “gitlab-runner.exe”
- “config.toml”

Step 3: Modify the “config..toml” file

Open the “config.toml” file located in ”C:\GitLab-Runner”.

Update the file to include the following settings:

executor = "shell"
shell = "powershell"

Save and close the file.

Step 4: Create “.gitlab-ci.yml” file

Define 3 stages:

stages:
- update
- build
- move_files

The first one will update our code on each push.


The second one will build(publish) our application.

5
The third one will move our files to the corresponding folder in “C://Websites” to make sure IIS
can locate it.

The first stage(job)

update_repository:
stage: update
script:
- powershell -Command "if (-Not (Test-Path
'C:\\Users\\nikola.perisic\\Desktop\\infection-index')) { git clone
https://git.URL.git
C:\\Users\\nikola.perisic\\Desktop\\infection-index } else { cd
'C:\\Users\\nikola.perisic\\Desktop\\infection-index'; git fetch
--all; git reset --hard origin/development; git clean -fd }"
tags:
- ci

Explanation:

This script is part of a CI/CD pipeline that updates a local copy of a Git repository. Here's a
simplified breakdown:

Stage name: The stage is called update, indicating the purpose of this step in the pipeline.
Script: The script runs a PowerShell command that checks if a specific folder
(infection-index) exists on the user's desktop.

● If the folder doesn't exist, it clones the Git repository from the specified URL to that
location.
● If the folder already exists, it navigates to that folder, fetches all updates from the remote
repository, resets the local files to match the development branch, and cleans up any
untracked files.

Tags: The script is tagged with ci. As I said before, the tag is important to make the runner able
to detect which (continue)

The second stage(job)

6
build_application:
stage: build
script:
- powershell -Command "cd
'C:\\Users\\nikola.perisic\\Desktop\\infection-index'"
- powershell -Command "git checkout development"
- powershell -Command "dotnet publish
'C:\\Users\\nikola.perisic\\Desktop\\infection-index\\MSK.Infection
Index' -c Release -o
'C:\\Users\\nikola.perisic\\Desktop\\infection-index\\publish'"
tags:
- ci

Explanation:

This script is another part of a CI/CD pipeline, focused on building an application. Here’s a
beginner-friendly explanation:

Stage name: The stage is named build, indicating that this step handles the application's build
process.
Script: The script runs several PowerShell commands in sequence:

● It changes the directory to the local repository folder (infection-index) on the user's
desktop.
● It checks out the development branch in the Git repository, ensuring that the correct
branch is being used.
● It then runs the dotnet publish command to build the application located in the
MSK.InfectionIndex folder. The build is configured for the Release mode, and the
output is placed in the publish folder within the repository.

Tags: Like before, the script is tagged with ci.

This code automates the process of building the application from a specific branch and prepares
the compiled files for deployment.

7
The third stage(job)

move_files:
stage: move_files
script:
- powershell -Command "if (Test-Path
'C:\\Websites\\galactic-resistance.com') { Remove-Item -Path
'C:\\Websites\\galactic-resistance.com\\*' -Recurse -Force }"
- powershell -Command "New-Item -Path
'C:\\Websites\\galactic-resistance.com' -ItemType Directory -Force"
- powershell -Command "Copy-Item -Path
'C:\\Users\\nikola.perisic\\Desktop\\infection-index\\publish\\*'
-Destination 'C:\\Websites\\galactic-resistance.com' -Recurse
-Force"
- powershell -Command "Copy-Item -Path
'C:\\Users\\nikola.perisic\\Desktop\\appsettings.Development.json'
-Destination
'C:\\Websites\\galactic-resistance.com\\appsettings.Development.jso
n' -Force"
- powershell -Command "Copy-Item -Path
'C:\\Users\\nikola.perisic\\Desktop\\appsettings.json' -Destination
'C:\\Websites\\galactic-resistance.com\\appsettings.json' -Force"
- powershell -Command "Copy-Item -Path
'C:\\Users\\nikola.perisic\\Desktop\\web.config' -Destination
'C:\\Websites\\galactic-resistance.com\\web.config' -Force"
tags:
- ci

This script is part of a CI/CD pipeline, focused on moving and setting up files for deployment.
Here’s what it does:

Stage name: The stage is called move_files.

Script: The script runs several PowerShell commands:

● It checks if the folder galactic-resistance.com exists in the C:\\Websites


directory. If it does, it deletes all files and subfolders inside it.
● It creates the galactic-resistance.com folder again, ensuring it’s ready for new
files.
● It then copies the published application files from the publish folder into the
galactic-resistance.com directory.
● Additional commands copy specific configuration files
(appsettings.Development.json, appsettings.json, and web.config) from

8
the desktop to the galactic-resistance.com folder, ensuring the deployment
includes the correct settings.

Note: I configured these files once on the server and saved them on the Desktop. Of course,
you can configure them locally, and therefore publish would generate those files well, but I had
another local environment and I didn't want to mix the configuration files or run the risk of
someone changing them and accidentally pushing the wrong ones, because that would
automatically affect the production environment.

Tags: The script is tagged with ci.

This code automates the process of preparing a deployment directory by moving the necessary
application files and configurations into place.

Finally, in pipelines on GitLab, you should see similar output 😄

Final “.gitlab-ci.yml” file on Gists(advanced solution)

9
Possible problem
____________________________________________________________________________

Privilege issue

To be able to move(copy) files and folders be sure to give all the necessary permissions.

10
A more complex example of pipeline code

1. Defining variables

variables:
USERNAME: "nikola.perisic"
BASE_PATH: "C:\\Users\\${USERNAME}\\Desktop\\infection-index"
PUBLISH_PATH: "${BASE_PATH}\\publish"
WEBSITE_PATH: "C:\\Websites\\galactic-resistance.com"
APPSETTINGS_DEV:
"C:\\Users\\${USERNAME}\\Desktop\\appsettings.Development.json"
APPSETTINGS: "C:\\Users\\${USERNAME}\\Desktop\\appsettings.json"
WEB_CONFIG: "C:\\Users\\${USERNAME}\\Desktop\\web.config"

2. Defining stages(jobs)

stages:
- update
- build
- move_files

3. Defining the first job - The script checks if a specified directory (${BASE_PATH}) exists.
If it doesn't, it clones a Git repository into that directory. If the directory exists, it updates
the repository by fetching, resetting to a specific branch (development), and cleaning
untracked files.

update_repository:
stage: update
script:
- powershell -Command "if (-Not (Test-Path '${BASE_PATH}')) { git clone
https://URL.git '${BASE_PATH}' } else { cd '${BASE_PATH}'; git fetch --all; git
reset --hard origin/development; git clean -fd }"
tags:
- ci

11
4. Defining the second job - The pipeline job checks out the development branch, then
publishes a .NET application from the specified directory (${BASE_PATH}) to a release
folder (${PUBLISH_PATH}).

build_application:
stage: build
script:
- powershell -Command "cd '${BASE_PATH}'"
- powershell -Command "git checkout development"
- powershell -Command "dotnet publish '${BASE_PATH}\\MSK.InfectionIndex' -c
Release -o '${PUBLISH_PATH}'"
tags:
- ci

5. Defining the third job - The job stops the web app pool, cleans and recreates the target
directory (${WEBSITE_PATH}), copies the published files and configuration files to this
directory, and then restarts the web app pool.

move_files:
stage: move_files
script:
- powershell -Command "Import-Module WebAdministration"
- powershell -Command "Stop-WebAppPool -Name
'galactic-resistance.sitesstage.com'"
- powershell -Command "if (Test-Path '${WEBSITE_PATH}') { Remove-Item -Path
'${WEBSITE_PATH}\\*' -Recurse -Force }"
- powershell -Command "New-Item -Path '${WEBSITE_PATH}' -ItemType Directory
-Force"
- powershell -Command "Copy-Item -Path '${PUBLISH_PATH}\\*' -Destination
'${WEBSITE_PATH}' -Recurse -Force"
- powershell -Command "Copy-Item -Path '${APPSETTINGS_DEV}' -Destination
'${WEBSITE_PATH}\\appsettings.Development.json' -Force"
- powershell -Command "Copy-Item -Path '${APPSETTINGS}' -Destination
'${WEBSITE_PATH}\\appsettings.json' -Force"
- powershell -Command "Copy-Item -Path '${WEB_CONFIG}' -Destination
'${WEBSITE_PATH}\\web.config' -Force"
- powershell -Command "Start-WebAppPool -Name
'galactic-resistance.sitesstage.com'"
tags:
- ci

12

You might also like