About
If you're looking to host an ASP.NET application on an Apache server, this post provides a quick guide with a working configuration. By the end of this setup, your ASP.NET app should be up and running smoothly behind an Apache proxy.
A big shoutout to Adam from the Enhance support for his helpful insights on making this possible!
Prerequisites
- ASP.NET Application: Ensure you have your ASP.NET project ready.
- Apache Server: Enabled on Enhance for Server.
Creating and Managing a Systemd Service for a .NET Application
This documentation explains how to create a custom .service
file for a .NET application, enable and start the service, and manage it with systemctl
.
Steps to Create and Start a Systemd Service
1. Create the .service
File
- Open a terminal on your server.
- Use a text editor to create a new
.service
file in the /etc/systemd/system/
directory:
sudo nano /etc/systemd/system/yourprojectname.service
Paste the following content into the file, updating [YourServerPublicIP]
, [YourWebsiteGuid]
, [YourProjectName]
and [YourKestrelPort]
with your actual values:
- [YourKestrelPort] can be any available port on the server. Two projects cannot share the same port, so make sure they are unique, for example: 5000, 5001, 5002, etc.
- [YourWebsiteGuid] can be found in the URL bar when you select your website inside the Enhance web panel. For example: https://yourserver.com/websites/a62a33d5-bf08-4f6c-95cc-4dgdf7408120 In this case,
a62a33d5-bf08-4f6c-95cc-4dgdf7408120
is your WebsiteGuid.
[Service]
WorkingDirectory=/var/www/[YourWebsiteGuid]/public_html
ExecStart=/usr/bin/dotnet /var/www/[YourWebsiteGuid]/public_html/[YourProjectName].dll
Restart=always
# Restart service after 10 seconds if the dotnet service crashes:
RestartSec=10
KillSignal=SIGINT
SyslogIdentifier=[YourProjectName]
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false
Environment=ASPNETCORE_URLS=http://[YourServerPublicIP]:[YourKestrelPort]
[Install]
WantedBy=multi-user.target
Save the file and exit the editor (CTRL+O
, Enter
, CTRL+X
for Nano).
2. Reload the Systemd Daemon
After creating the .service
file, reload the systemd
daemon to recognize the new service:
sudo systemctl daemon-reload
3. Start the Service
To start the service, use:
sudo systemctl start yourprojectname.service
4. Enable the Service to Start on Boot
To ensure the service starts automatically after a reboot:
sudo systemctl enable yourprojectname.service
Additional Commands
Check Service Status
To check if the service is running:
sudo systemctl status yourprojectname.service
Restart the Service
To restart the service (e.g., after updating / redeploying the project and .dll
file):
sudo systemctl restart yourprojectname.service
Stop the Service
To stop the service:
sudo systemctl stop yourprojectname.service
Disable the Service
To disable the service from starting on boot:**
sudo systemctl disable yourprojectname.service
Logging and Debugging
Logs for the service can be viewed using journalctl
:
sudo journalctl -u yourprojectname.service
Use tail
to view real-time logs:
sudo journalctl -u yourprojectname.service -f
Configurations for Apache
To set up Apache as a reverse proxy for your ASP.NET application, create/update your virtual host configuration file (e.g., /var/local/enhance/apache/vhost_includes/[yourdomain.com]
.conf) with the following:
RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}
ProxyPreserveHost On
ProxyPass / http://[YourServerPublicIP]:[YourKestrelPort]/
ProxyPassReverse / http://[YourServerPublicIP]:[YourKestrelPort]/
If your ASP.NET project uses Blazor or SignalR, also add this to the end of the file:
RewriteEngine On
RewriteCond %{HTTP:Upgrade} =websocket [NC]
RewriteRule /(.*) ws://[YourServerPublicIP]:[YourKestrelPort]/$1 [P,L]
Configurations for ASP.NET Projects
1. Forwarding Headers
To correctly forward headers in your ASP.NET application, add the following code to your Program.cs
file:
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});
Explanation:
ForwardedHeaders.XForwardedFor
: This forwards the X-Forwarded-For
header, which indicates the originating IP address of a client connecting through a proxy.
ForwardedHeaders.XForwardedProto
: This forwards the X-Forwarded-Proto
header, which indicates the protocol (HTTP or HTTPS) used by the client.
2. Configuring Maximum Receive Message Size (Blazor)
If you are using Blazor in your project, you might encounter limitations on the size of incoming messages. To increase the maximum receive message size, add the following code in your Program.cs
:
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents()
.AddHubOptions(options => options.MaximumReceiveMessageSize = 10 * 1024 * 1024);
Explanation:
AddHubOptions
: Configures options for SignalR hubs.
MaximumReceiveMessageSize
: Sets the maximum size (in bytes) for incoming messages. In this example, it is set to 10 MB.
3. Adjusting the Base Href in Blazor
If your project dynamically sets the base href (e.g., <base href="@NavigationManager.BaseUri" />
), change it to a static value of "/"
to avoid potential routing issues.
Example:
Replace:
<base href="@NavigationManager.BaseUri" />
With:
<base href="/" />
Why Change This?
Blazor applications sometimes dynamically generate the base href using the NavigationManager
. However, this can cause issues with routing and resource loading in certain deployment scenarios. Setting it explicitly to "/"
ensures consistency.
Now, publish your ASP.NET project to your website's public HTML directory. Once that's done, restart the service and navigate to your website. That's itโyouโre all set! ๐