- asp net core backend
- react frontend + vite tooling
- https self signed cert development
- backend and frontend debugging in a solution
- publish release with frontend webpacked available through server static files available directly from within backend
- step by step how this project was built by git commit
- (optional) see how this project was built for project setup from scratch
- see prerequisites to setup self signed dev cert and nginx proxy
git clone https://github.com/devel0/example-webapp.git
cd example-webapp
code .
-
choose
.NET Core Launch (web)
from run and debug then hit F5 ( this will start asp net web server on localhost:5000 ) -
start vite
cd clientapp
npm run dev
-
choose
Launch Chrome
from run and debug then click the play icon ( this will start browser ) -
app running in local development within https
- two debugger active ( asp net core + chrome )
- prepare the build
dotnet publish -c Release
results
devel0@tuf:~/opensource/example-webapp$ ls /home/devel0/opensource/example-webapp/WebApiServer/bin/Release/net8.0/publish
appsettings.Development.json Microsoft.OpenApi.dll WebApiServer.deps.json
appsettings.json Swashbuckle.AspNetCore.Swagger.dll WebApiServer.dll
clientapp Swashbuckle.AspNetCore.SwaggerGen.dll WebApiServer.pdb
Microsoft.AspNetCore.OpenApi.dll Swashbuckle.AspNetCore.SwaggerUI.dll WebApiServer.runtimeconfig.json
Microsoft.AspNetCore.SpaServices.Extensions.dll WebApiServer web.config
- if want to publish with all required runtime to run w/out installed dotnet for specific platform
dotnet publish -c Release --runtime linux-x64 --sc
- start the production on server manually to test it
$ ./WebApiServer --urls http://10.10.1.47:5000
info: Microsoft.Hosting.Lifetime[14]
Now listening on: http://10.10.1.47:5000
info: Microsoft.Hosting.Lifetime[0]
Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
Hosting environment: Production
info: Microsoft.Hosting.Lifetime[0]
Content root path: /root/publish
warn: Microsoft.AspNetCore.HttpsPolicy.HttpsRedirectionMiddleware[3]
Failed to determine the https port for redirect.
- create
/etc/systemd/system/example-webapp.service
for automatic start at server boot
[Unit]
Description=Example webapp
After=network.target
StartLimitIntervalSec=0
[Service]
Type=simple
Restart=always
RestartSec=10
User=testuser
ExecStart=/srv/WebApiServer
Environment=ASPNETCORE_URLS=http://10.10.1.47:5000
Environment=ASPNETCORE_ENVIRONMENT=Production
#EnvironmentFile=/root/secrets/WebApiServer.Production.env
[Install]
WantedBy=multi-user.target
-
enable service
systemctl enable example-webapp.service
-
start the service
service example-webapp start
-
watch service log
journalctl -u example-webapp -f
-
configure nginx server to point on the webapi server ( the lines managed by certbot are created using
certbot --nginx test.searchathing.com
)
server {
root /var/www/html;
#rewrite_log on;
#access_log /var/log/nginx/test.access.log;
#error_log /var/log/nginx/test.error.log notice;
server_name test.searchathing.com;
location /api/ {
include /etc/nginx/mime.types;
proxy_set_header Host $host;
proxy_pass http://10.10.1.47:5000/;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /app/ {
include /etc/nginx/mime.types;
proxy_set_header Host $host;
proxy_pass http://10.10.1.47:5000/app/;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/test.searchathing.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/test.searchathing.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = test.searchathing.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
server_name test.searchathing.com;
listen 80;
return 404; # managed by Certbot
}
- try browse
https://test.searchathing.com
( replace with your own )
- clone linux-scripts-utils
mkdir -p ~/opensource
cd ~/opensource
git clone git@github.com:devel0/linux-scripts-utils.git
export PATH=$PATH:~/opensource/linux-scripts-utils
mkdir -p ~/sscerts
chmod 700 ~/sscerts
- create cert parameters file
~/sscerts/searchathing.com.params
( replacesearchathing.com
with your own )
COUNTRY="IT"
STATE="Italy"
CITY="Trento"
ORGNAME="SearchAThing"
ORGUNIT="Development"
DOMAIN=localhost
DURATION_DAYS=36500 # 100 years
- create root-ca certificates
CERTPARAMS=~/sscerts/searchathing.com.params create-root-ca.sh
- generated root-ca files
file | description |
---|---|
~/sscerts/searchathing.com.crt |
root-ca certificate that you can register into the browser to trust linked certificates |
~/sscerts/searchathing.com.key |
key of the root-ca certificte ( this is NOT NEEDED anywhere, do not share ) |
- create a couple of test certificates ( note: the path uses the first certificate name, if you don't change the first name the path remain the same even you extend to add more )
CERTPARAMS=~/sscerts/searchathing.com.params create-cert.sh --add-empty webapp-test test1 test2
file | description |
---|---|
~/sscerts/webapp-test.searchathing.com/webapp-test.searchathing.com.crt |
is the certificate crt for nginx https proxy |
~/sscerts/webapp-test.searchathing.com/webapp-test.searchathing.com.key |
is the certificate key for nginx https proxy |
- install nginx
apt install nginx
- create
/etc/nginx/conf.d/test-webapp.conf
#
# DEVELOPMENT
#
server {
root /var/www/html;
rewrite_log on;
access_log /var/log/nginx/webapp-test.access.log;
error_log /var/log/nginx/webapp-test.error.log notice;
server_name webapp-test.searchathing.com;
location /swagger/ {
include /etc/nginx/mime.types;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:5000/swagger/;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /api/ {
include /etc/nginx/mime.types;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:5000/;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /app/ {
include /etc/nginx/mime.types;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:5100/app/;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
listen 443 ssl;
ssl_certificate /home/devel0/sscerts/webapp-test.searchathing.com/webapp-test.searchathing.com.crt;
ssl_certificate_key /home/devel0/sscerts/webapp-test.searchathing.com/webapp-test.searchathing.com.key;
}
server {
if ($host = webapp-test.searchathing.com) {
return 301 https://$host$request_uri;
}
server_name webapp-test.searchathing.com;
listen 80;
return 404;
}
- edit
/etc/hosts
127.0.0.1 localhost webapp-test.searchathing.com
Installing root-ca certificate imply that certificates generated within that will be consequently trusted.
-
chrome: settings/Privacy and security/Security/Manage certificates/Authorities/Import
- select
~/sscerts/searchathing.com_CA.crt
- tick
Trust this certificate for identifying websites
- select
-
firefox: settings/Privacy & Security/Certificates/View Certificates/Authorities/Import
- select
~/sscerts/searchathing.com_CA.crt
- tick
Trust this CA to identify websites
- select
-
shell
- copy
~/sscerts/searchathing.com_CA.crt
to/usr/local/share/ca-certificates
- issue
sudo update-ca-certificates
- copy
mkdir example-webapp
cd example-webapp
git init
dotnet new gitignore
dotnet new webapi -n WebApiServer
npm create vite@latest clientapp -- --template react-ts
cd clientapp
npm install --save-dev @vitejs/plugin-react
cd ..
dotnet new sln
dotnet sln add WebApiServer
dotnet build
- vscode (C-S-p: Generate assets)
- bunch of configs