- Newest
- Most votes
- Most comments
I have found the answer to the above issue, that I have faced after many trails and errors. And putting my solution here so that others who are struggling, just like me, to find a solution to make the asp.net core application work in an AWS EC2 Linux instance can refer this.
To give you a little bit of context, I have 2 CloudFormation templates, one to create the AWS resources (like EC2, subnets, VPCs, IGWs etc...) and the other one to create the AWS Code Pipeline (I have only 3 stages in here, Source, Build & Deploy).
The asp.net core web application that I used in here was the sample web application that Visual Studio creates, when you create an asp.net core application from it.
To make the above application work, below are the points that you need to make sure you have it in your CloudFormation templates and other files.
- You need to have the below "UserData" in your Linux EC2 instance, to make the Apache web server installed, CodeDeploy agent installed, and ASP.NET Core runtime installed. (I have installed SSM Agent as well so that I can use the EC2 Session Manager)
UserData:
Fn::Base64:
!Sub |
#!/bin/bash -xe
sudo su
sudo yum -y update
yum install -y ruby
yum install -y aws-cli
sudo amazon-linux-extras install -y php7.2
sudo yum install httpd -y
sudo systemctl start httpd
sudo systemctl enable httpd
sudo yum install -y https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/linux_amd64/amazon-ssm-agent.rpm
# commenting test index file
# echo ?Hello World from $(hostname -f)? > /var/www/html/index.html
cd /home/ec2-user
# downloading & installing CodeDeploy Agent as per https://docs.aws.amazon.com/codepipeline/latest/userguide/tutorials-simple-s3.html#S3-create-instances
aws s3 cp s3://aws-codedeploy-${AWS::Region}/latest/install . --region ${AWS::Region}
chmod +x ./install
./install auto
sudo rpm -Uvh https://packages.microsoft.com/config/centos/7/packages-microsoft-prod.rpm
sudo yum -y install dotnet-sdk-6.0
sudo yum -y install aspnetcore-runtime-6.0
- And in the buildspec.yaml file, have the following steps in it. I have published the project in release configuration and as a self-contained application. The CodeBuild will build and use the output in the publish folder "./WebApplication1/bin/Release/net6.0/linux-x64/publish/" when publishing the application in the deploy stage. I'm also copying some bash shell scripts files and appspec.yaml file into the publish folder as well.
version: 0.2
env:
variables:
DOTNET_CORE_RUNTIME: 6.0
phases:
install:
on-failure: ABORT
runtime-versions:
dotnet: ${DOTNET_CORE_RUNTIME}
commands:
- echo install stage - started `date`
pre_build:
commands:
- echo pre build stage - stared `date`
- echo restore dependencies started `date`
- dotnet restore ./WebApplication1/WebApplication1.csproj
build:
commands:
- echo build stage - started `date`
- dotnet publish --configuration Release --runtime linux-x64 ./WebApplication1/WebApplication1.csproj --self-contained
- cp ./WebApplication1/appspec.yml ./WebApplication1/bin/Release/net6.0/linux-x64/publish/
- cp -r ./WebApplication1/shellscripts ./WebApplication1/bin/Release/net6.0/linux-x64/publish/
artifacts:
files:
- '**/*'
- appspec.yml
name: artifact-test-cham
discard-paths: no
base-directory: ./WebApplication1/bin/Release/net6.0/linux-x64/publish/
- In the appspec.yaml file, I have the following commands, in the "AfterInstall" stage, I have mentioned several shell scripts files to be executed. I have copied the application (that were built by CodeBuild) to /var/www/html folder in the EC2 instance.
version: 0.0
os: linux
files:
- source: /
destination: /var/www/html/
hooks:
AfterInstall:
- location: shellscripts/create_drcwebappconf_file.sh
timeout: 180
runas: root
- location: shellscripts/restart_and_enable_httpd.sh
timeout: 180
runas: root
- location: shellscripts/create_drcwebappservice_file.sh
timeout: 180
runas: root
- location: shellscripts/start_drcwebappservice.sh
timeout: 180
runas: root
- During the code deploy stage the above appspec.yaml file will trigger the script files mentioned there. What I perform in these script files are mentioned in the following URL, where it tells how to publish ASP.NET Core web application into a Linux server. https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/linux-apache?view=aspnetcore-7.0
I have breakdown the steps mentioned in that article, into script files so that I can automate the process of configuring the ASP.NET Core web application, rather than accessing the EC2 instances and executing the commands manually.
Below are the shell script files that I have used.
create_drcwebappconf_file.sh. In this file you can mention the ServerName and ServerAlias as well, since this is a test, I haven't included those (and I am bit confused of what those do and its usage ? if somebody can explain it, would be great)
# create the drcwebapp.conf file
#!/bin/bash
cd /etc/httpd/conf.d/
cat > drcwebapp.conf << EOF
<VirtualHost *:*>
RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}
</VirtualHost>
<VirtualHost *:80>
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:5000/
ProxyPassReverse / http://127.0.0.1:5000/
ErrorLog ${APACHE_LOG_DIR}helloapp-error.log
CustomLog ${APACHE_LOG_DIR}helloapp-access.log common
</VirtualHost>
EOF
restart_and_enable_httpd.sh
# restart and enable httpd
#!/bin/bash
sudo systemctl restart httpd
sudo systemctl enable httpd
create_drcwebappservice_file.sh. Make sure you put the correct path of the "dotnet" in the ExecStart, otherwise the service will not start, and application will fail.
#create the drcwebapp.service file
#!/bin/bash
cd /etc/systemd/system/
cat > drcwebapp.service << EOF
[Unit]
Description=Example .NET Web API App running on CentOS 7
[Service]
WorkingDirectory=/var/www/html
ExecStart=/usr/bin/dotnet /var/www/html/WebApplication1.dll
Restart=always
# Restart service after 10 seconds if the dotnet service crashes:
RestartSec=10
KillSignal=SIGINT
SyslogIdentifier=dotnet-example
User=apache
Environment=ASPNETCORE_ENVIRONMENT=Production
[Install]
WantedBy=multi-user.target
EOF
start_drcwebappservice.sh. You can use the commented command on an EC2 instance, just to check if the service has started correctly.
#start the drcwebapp.service
#!/bin/bash
sudo systemctl enable drcwebapp.service
sudo systemctl start drcwebapp.service
#to check the status of the service
#sudo systemctl status drcwebapp.service
Hope this answer will help somebody. I think I mentioned the points in detail. If you have any questions, please post in here. I will try best to answer if I know the answer.
Hi, @champer
.NET Core is not a process that automatically runs on a web server like .NET Framework is.
You have to start his web application using the dotnet command. Then use Apache or Nginx as a reverse proxy to forward requests.
(You can also publish with Kestrel without using Apache and transfer directly from ALB etc.)
Below is the official Microsoft document about running ASP.NET Core on Linux + Apache.
https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/linux-apache?view=aspnetcore-7.0
Here we are using the service file to run the dotent command. Some form of startup is required in this way.
ExecStart=/usr/local/bin/dotnet /var/www/helloapp/helloapp.dll
Relevant content
- Accepted Answerasked 4 months ago
- AWS OFFICIALUpdated 3 years ago
@iwasa: I have a code pipeline set up to get the code from CodeCommit, then build the web application using CodeBuild and then finally deploy the built application using CodeDeploy to the EC2 instances that are behind a load balancer, in multiple AZs. Does this mean even though I have the pipeline automation, I have to manually start the application? Beg your pardon for my lack of knowledge. If you can explain a little bit more, would be very grateful.
Mechanisms such as ALB and CodeDeploy are less important.
ASP.NET Core doesn't work unless you run it with the dotnet command.
And Apache doesn't automatically start the ASP.NET Core process.
You somehow launch the ASP.NET Core process with the dotnet command. Then Apache and ASP.NET Core will be able to communicate.
Apache can manage ASP.NET Core processes by implementing a service with reference to the previous link.
@iwasa: Thanks for your response. I have tested the steps in the following URL, on an AWS Linux EC2 instance, and I can confirm that my test asp.net core application is working fine. https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/linux-apache?view=aspnetcore-7.0
All the steps in the above tutorial I have entered it manually in the EC2 instance's command line. I have to now figure it out a way to automate that process. So that when my pipeline gets executed, it fetches the code from CodeCommit, build it using CodeBuild and then deploy the built application to EC2 instances using CodeDeploy and then execute those commands so that once the application is deployed the asp.net core is started automatically, and no manual intervention is needed.