Publishing and Hosting Apps

    Last Updated: September 2024

    Overview

    SnapDevelop provides the following methods to publish your projects:

    • Folder: Publishes to a local folder or a network shared folder.
    • Web Server (IIS): Publishes to IIS server.
    • Docker Container Registry: Publishes to any container repository that supports Docker images.
    • Kubernetes Cluster: Publishes to a Kubernetes cluster.

    ASP.NET Core Web API supports the following publish methods:

    • Folder
    • Web Server (IIS)
    • Docker Container Registry
    • Kubernetes Cluster

    Console Apps, Class Libraries, Web Apps, Vue Projects, Worker Services, and xUnit Tests support the following publish methods:

    • Folder
    • Docker Container Registry
    • Kubernetes Cluster

    Publishing to a Folder

    This section describes how to use SnapDevelop to publish C# projects to a local folder or a network shared folder.

    Publishing a C# project

    To publish a C# project to a folder:

    Step 1: In Solution Explorer, right-click the project and select Publish.

    Step 2: In the window that appears, select the Folder tab, then click Next.

    Step 3: Select a local or network folder as the publish destination, then click Next.

    Step 4: Configure the publish profile or select an existing configuration file.

    Click the Edit publish profile icon to change the folder location and the following options and then click Save.

    Settings Description
    Configuration Selects Debug or Release mode.
    Target Framework Selects the target framework.
    Deployment Mode Self-contained -- Publishes as an application that includes the .NET Core runtime and libraries along with your application and its dependencies. Users of the application can run it on machines that have no .NET Core runtime installed. Framework-dependent -- Publishes as an application that contains only your app and its dependencies. Users of the application have to separately install the .NET Core runtime.
    Target Runtime Selects the target runtime.
    Delete all existing files prior to publish Deletes all files in target folder before publishing.
    Use this connection string at runtime When it is checked, the publishing process will change the connection string for this database in the deployed Web.config file to the value you specify in the text box.

    Step 5: Click Publish. The publishing process begins. You can view the publishing progress in the Output window.

    Publishing a JavaScript/TypeScript project

    To publish a JavaScript/TypeScript project (such as Vue) to a folder:

    Step 1: In Solution Explorer, right-click the project and select Publish.

    Step 2: In the window that appears, select the Folder tab, then click Next.

    Step 3: Select a local or network folder as the publish destination, then click Next.

    Step 4: Configure the publish profile or select an existing configuration file.

    Click the Edit publish profile icon to change the folder location and the following options and then click Save.

    Settings Description
    Configuration Selects Debug or Release mode.
    Delete existing files Deletes all files in the destination folder before publishing.

    Step 5: Click Publish. The publishing process begins. You can view the publishing progress in the Output window.

    Publishing to Docker or Kubernetes

    SnapDevelop's support for Docker and Kubernetes simplifies development, testing, and deployment of containerized applications. Container Explorer and Kubernetes Explorer provided by SnapDevelop can manage your images and containers in a more efficient and productive way than using Docker and Kubernetes commands.

    You can add two levels of container support to your project:

    • Container Support or Kubernetes Support -- Launches containers or Kubernetes support for a single project.

    • Container Orchestration Support -- Use Docker Compose or Kubernetes Compose to support multiple containers (e.g. solutions with multiple projects).

    See Publishing to Docker for how to publish to Docker and Publishing to Kubernetes for how to publish to Kubernetes.

    Publishing to IIS

    This topic describes how to publish a project to IIS with SnapDevelop. It also includes troubleshooting information for some common errors.

    Prerequisites

    Both the server and client side requirements must be met before you publish a project to IIS.

    Server Side Requirements

    • Windows Server 2022, 2019, or 2016

      If your operating system is Windows 10, you can use Folder, rather than Web Server (IIS) publish method, to publish your project to a folder.

      Make sure that your Windows is up-to-date and includes KB2999226, otherwise you might see this error when you launch a .NET Core application: The program can't start because api-ms-win-crt-runtime-1-1-0.dll is missing from your computer. Try reinstalling the program to fix this problem.

    • Web Deploy 3.6 or higher

      Download link: https://www.iis.net/downloads/microsoft/web-deploy

      When you install Web Deploy, select the Complete setup type to install.

    • Hosting Bundle

      Download link: https://dotnet.microsoft.com/download/dotnet-core

      Download and install the ASP.NET Core Hosting Bundle. Make sure that the version of ASP.NET Core Hosting Bundle is the same as the framework version your project targets. For example, if your project targets .NET Core 3.1, install the Hosting Bundle version 3.1.

    Client Side Requirements

    • Windows 10

      Make sure that your Windows is up-to-date and includes KB2999226, otherwise you might see this error when you launch a .NET Core application: The program can't start because api-ms-win-crt-runtime-1-1-0.dll is missing from your computer. Try reinstalling the program to fix this problem.

    • Web Deploy 3.6 or higher

      The Web Deploy on the client side is automatically installed when you install SnapDevelop.

    Configuring Server Side

    Configuring IIS

    To configure IIS

    Step 1: Launch the Server Manager.

    Step 2: Use the Add Roles and Features wizard from the Manage menu or the link in Server Manager. On the Server Roles page, select the Web Server (IIS) and Management Tools checkboxes.

    Step 3: On the Features page, select the .NET Framework 3.5 Features and .NET Framework 4.6 Features checkboxes.

    Step 4: Confirm the roles and features you selected, and click Install.

    Configuring Web Deploy

    You must enable the Web Management Service and Web Deployment Agent Service after installing Web Deploy.

    To enable the services

    Step 1: Launch the desktop application Services.

    Step 2: Locate Web Management Service and Web Deployment Agent Service. Right click on each of them, and select Start.

    Enabling Remote Connections

    To enable remote connections

    Step 1: Launch the IIS Manager.

    Step 2: Select your computer in the Connections panel first, and then double click Management Service on the right.

    Step 3: In the Management Service, click Stop first, then select the Enable remote connections checkbox, and click Apply.

    Adding IIS Users

    You can add IIS users of IIS Manager type or Windows type.

    Adding IIS Manager Users

    To add IIS Manager users

    Step 1: In the IIS Manager, select your computer in the Connections panel, and then double click IIS Manager Users.

    Step 2: Click Add User to add a user.

    Step 3: In the IIS Manager, right click the Sites folder in the Connections panel, and select Add Website.

    Step 4: Specify the site name, physical path, and binding information.

    Step 5: Expand the Sites folder. Select the newly created website first, and then double-click IIS Manager Permissions.

    Step 6: Click Allow User first, and then select IIS Manager in the dialog box. Click Select to select a user you added.

    Adding Windows Users

    To add Windows users

    Step 1: In the IIS Manager, right click on the Sites folder in the Connections panel, and then select Add Website.

    Step 2: Specify the site name, physical path, and binding information.

    Step 3: Expand the Sites folder. Select the newly created website first, and then double click IIS Manager Permissions.

    Step 4: Click Allow User. In the dialog box that appears, select Windows, and click Select.

    Step 5: Specify the object type, location, and enter the user name to select a user.

    Step 6: In the IIS Manager, select your site first, and then click Basic Settings.

    Step 7: Select Connect as > Specific user > Set to set the user name and password.

    Step 8: Click Test Settings in step 7 to test the connection.

    Publishing a Project to IIS

    To publish a project to IIS:

    Step 1: In the Solution Explorer, right click on the project, and select Publish.

    Step 2: In the window that appears, select the Web Server (IIS) tab, and click Next.

    Step 3: Configure the IIS connection information or click the Import icon to import connection information from a profile, and then click Next.

    Server: The domain name or IP address of the web server.

    Site Name: The name of the web server site.

    User Name: The user name to connect to the web server. Note that the user name can be either the IIS Web Deploy user name or the Windows user name.

    Password: The password to connect to the web server.

    Destination URL: The URL to view the publishing app.

    Step 4: Verify the settings.

    If you want to change the Web server connection settings, you can click the Edit publish profile icon after the Server setting.

    If you want to change the publish settings (as shown in the table below), you can click the Edit publish profile icon after the Configuration setting.

    Settings Description
    Configuration Selects Debug or Release mode.
    Target Framework Selects the target framework.
    Deployment Mode Self-contained -- Publishes as an application that includes the .NET Core runtime and libraries along with your application and its dependencies. Users of the application can run it on machines that have no .NET Core runtime installed. Framework-dependent -- Publishes as an application that contains only your app and its dependencies. Users of the application have to separately install the .NET Core runtime.
    Target Runtime Selects the target runtime.
    Remove additional files at destination Deletes the extra files in target folder before publishing.
    Use this connection string at runtime When it is checked, the publishing process will change the connection string for this database in the deployed Web.config file to the value you specify in the text box.

    Step 5: Click Publish. The publishing process begins. You can view the publishing progress in the Output window.

    Troubleshooting

    This topic describes the common errors that may occur when you publish projects to IIS.

    The site does not exist

    This error would occur if you did not select the Complete setup type of Web Deploy to install. The Web deployment agent service will be not enabled for the other setup types of Web Deploy.

    Solution:

    Uninstall your current version of Web Deploy and then install the Complete version.

    The Web server is configured to not list the contents of this directory

    Solution:

    Step 1: Launch the IIS Manager, select your site in the Connections panel, and click Directory Browsing.

    Step 2: Click Enable.

    Error concerning IIS application pool permission

    When such an error occurs, no data can be retrieved to your application and the error code 500 is returned. This is because the IIS application pool does not have permissions to log in to the database.

    Solution 1:

    Change the application pool identifier to a user who has access to the database.

    Solution 2:

    Change stdoutLogEnabled="false" to stdoutLogEnabled="true" in the web.config file that appears after the publish.

    Error indicating that files are locked when an application is published to a remote site where an application has previously been published

    Solution 1:

    Shut down and relaunch the site after the publish.

    Solution 2:

    Select the checkbox Remove additional files at destination when you configure the publish profile.

    Runtime error 500.30 when publishing .NET Core 2.2 application to IIS

    Solution:

    In the application configuration file, change "InProcess" to "OutOfProcess" in PropertyGroup, and add the ModelName property.

    Error 502.5 might occur after you change the method. If this is the case, change the .NET path of Web API to an absolute path and restart your computer.

    If Error 502.5 remains, you can check the event log. If the log indicates that the startup process fails, it might be caused by insufficient permissions. To fix the error, right click the website in the IIS Manager and select Advanced Settings. Choose Identity under Process Model, and select the Custom account to enter the local administrator's user name and password.

    Publishing and Hosting an ASP.NET Core Application on Linux

    In this topic, we create a Web API application, publish it using the File System method, and then host the app on Linux CentOS7 operating system following these steps:

    • In SnapDevelop, publish the Web API application with middleware configured to support reverse proxy

    • Copy over the Web API application from the local published folder to CentOS server

    • In CentOS, host Web API application on CentOS with reverse proxy (Apache) configured

      For more information on how to set up Apache as a reverse proxy on CentOS 7, you can further read the Microsoft article: Host ASP.NET Core on Linux with Apache.

    Prerequisites

    • SnapDevelop 2025
    • Server running CentOS 7 with a standard sudo user account
    • .NET Core Runtime is installed on CentOS 7 with the following instructions

    Install .NET Core Runtime on CentOS 7

    Before installing .NET Runtime, you need to register the Microsoft key, register the product repository, and install required dependencies. These only need to be done once per machine. Open a terminal and run the following commands:

    # Install repository configuration
    curl https://packages.microsoft.com/config/rhel/7/prod.repo > ./microsoft-prod.repo
    sudo cp ./microsoft-prod.repo /etc/yum.repos.d/
    
    # Install Microsoft's GPG public key
    curl https://packages.microsoft.com/keys/microsoft.asc > ./microsoft.asc
    sudo rpm --import ./microsoft.asc
    

    Install the latest available updates for the product, then install the .NET Runtime.

    In your terminal, run the following commands:

    # Install the latest available updates for the product
    sudo yum update
    
    # Install the ASP.NET Core 3.1 runtime
    sudo yum install aspnetcore-runtime-3.1
    

    *The previous command will install the .NET Core Runtime Bundle, which includes the .NET Core runtime and the ASP.NET Core 3.1 runtime. To install just the .NET Core runtime, use the dotnet-runtime-3.1 package. Please note that, the runtime version must be the same as the version of the .NET Framework that you want your project to target.

    Publishing an ASP.NET Core Application to Server

    Preparation for the Application

    In SnapDevelop, select File from the menu bar and then choose New > Project. In the dialog box, select ASP.NET Core Web API. Then, fill in the project information to create a .NET Core project named WebAPI1 by clicking OK.

    Some configurations for reverse proxy and Kestrel server need to be made before publishing.

    Configuration for Forwarded Headers Middleware

    Because requests are forwarded by reverse proxy, use the Forwarded Headers Middleware from the Microsoft.AspNetCore.HttpOverrides package. The middleware updates the Request.Scheme, using the X-Forwarded-Proto header, so that redirect URIs and other security policies work correctly.

    Any component that depends on the scheme, such as authentication, link generation, redirects, and geolocation, must be placed after invoking the Forwarded Headers Middleware. As a general rule, Forwarded Headers Middleware should run before other middleware except for diagnostics and error handling middleware. This running order ensures that the middleware relying on forwarded headers information can consume the header values for processing.

    Invoke the UseForwardedHeaders method in Startup.Configure before calling UseAuthentication or similar authentication scheme middleware. Configure the middleware to forward the X-Forwarded-For and X-Forwarded-Proto headers:

    app.UseForwardedHeaders(new ForwardedHeadersOptions
    {
        ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
    });
    
    app.UseAuthentication();
    

    If no ForwardedHeadersOptions are specified to the middleware, the default forwarded headers are None.

    Proxies running on loopback addresses (127.0.0.0/8, [::1]), including the standard localhost address (127.0.0.1), are trusted by default. For other trusted proxies or networks within the organization handling requests between the Internet and the web server, add them to the list of KnownProxies or KnownNetworks as options in ForwardedHeadersOptions. The following example adds a trusted proxy server at IP address 10.0.0.100 to the KnownProxies of Forwarded Headers Middleware in Startup.ConfigureServices:

    services.Configure<ForwardedHeadersOptions>(options =>
    {
        options.KnownProxies.Add(IPAddress.Parse("10.0.0.100"));
    });
    

    For more information, see Configure ASP.NET Core to work with proxy servers and load balancers.

    Configuration for Secure (HTTPS) Local Connections

    It is important for the application to make secure connections (HTTPS), configure the application to use a certificate for your development using one of the following approaches:

    • Replace the default certificate from configuration (Recommended)
    • KestrelServerOptions.ConfigureHttpsDefaults

    The configuration for the application to listen to the URLs is in applicationUrl property in the Properties/launchSettings.json file, for example, https://localhost:5001;http://localhost:5000.

    The app runs locally, so it is optional to configure the web server (Kestrel) with secure (HTTPS) local connections. You can remove https://localhost:5001 (if present) from the configuration.

    Publishing the Application to a Local Folder

    Step 1: In Solution Explorer, right-click the project and choose Publish.

    Step 2: On the popup window, select Folder.

    Step 3: Click Next until the settings overview page display. Click the Edit publish profile icon of Publish Settings.

    Step 4: Set the publish settings according to your actual needs.

    Step 5: Click Save to continue.

    Step 6: Click Publish, then check the publication status in the Output window.

    Copying the Application to the Server

    Once the Web API application is published, copy the application from the published folder to the CentOS server using a tool that integrates into the organization's workflow (for example, SCP, SFTP). It's common to locate web applications under the var directory (for example, var/www/WebAPI1).

    Hosting ASP.NET Core on CentOS with Apache

    Configuring a Proxy Server

    A reverse proxy is a common setup for serving dynamic web applications. The reverse proxy terminates the HTTP request and forwards it to the Web API application. In this example, Apache is configured as a reverse proxy, and Kestrel serves the Web API application. Apache forwards client requests to the Web API application running on Kestrel instead of fulfilling requests itself.

    Installing Apache

    Update CentOS packages to the latest stable versions:

    sudo yum update -y
    

    Install the Apache web server on CentOS with a single yum command:

    sudo yum -y install httpd mod_ssl
    

    To verify where Apache is installed, run whereis httpd from a command prompt.

    Configuring Apache

    Open the /etc/httpd/conf/httpd.conf file and set the ServerName directive globally:

    sudo nano /etc/httpd/conf/httpd.conf
    
    # Set ServerName in this configuration file
    ServerName www.example.com:80
    

    The configuration files for Apache are located in the /etc/httpd/conf.d/ directory. Any file with the .conf extension is processed in alphabetical order in addition to the module configuration files in /etc/httpd/conf.modules.d/, which contains all the necessary configuration files to load modules.

    Create a configuration file:

    sudo nano /etc/httpd/conf.d/WebAPI1.conf
    

    An example of configuration files for the application:

    <VirtualHost *:*>
        RequestHeader set "X-Forwarded-Proto" expr=$scheme
    </VirtualHost>
    
    <VirtualHost *:80>
        ProxyPreserveHost On
        ProxyPass / http://127.0.0.1:5000/
        ProxyPassReverse / http://127.0.0.1:5000/
        ServerName www.example.com
        ServerAlias *.example.com
        ErrorLog /var/log/httpd/WebAPI1-error.log
        CustomLog /var/log/httpd/WebAPI1-access.log common
    </VirtualHost>
    

    The VirtualHost block can appear multiple times in one or more files on a server. In the preceding configuration file, Apache accepts public traffic on port 80. The domain www.example.com is being served, and the *.example.com alias resolves to the same domain. See Name-based virtual host support for more information. Requests are proxied at the root to port 5000 of the server at 127.0.0.1. For bi-directional communication, ProxyPass and ProxyPassReverse are required. To change Kestrel's IP/port, see Kestrel: Endpoint configuration

    Warning: Failure to specify a proper ServerName directive in the VirtualHost block exposes your application to security vulnerabilities. Subdomain wildcard binding (for example, *.example.com) doesn't pose this security risk if you control the entire parent domain (as opposed to .com, which is vulnerable). See rfc7230 section-5.4 for more information.

    Logging can be configured per VirtualHost using ErrorLog and CustomLog directives. ErrorLog is the location where the server logs errors, and CustomLog sets the filename and format of log file. In this case, this is where request information is logged. There's one line for each request.

    Save the file and test the configuration. If everything passes, the response should be Syntax [OK].

    sudo service httpd configtest
    

    Restart Apache:

    sudo systemctl restart httpd
    sudo systemctl enable httpd
    

    Monitoring the Application

    Apache is now set up to forward requests made to http://localhost:80 to the Web API application running on Kestrel at http://127.0.0.1:5000. However, Apache isn't set up to manage the Kestrel process. Use systemd and create a service file to start and monitor the underlying web application. systemd is an init system that provides many powerful features for starting, stopping, and managing processes.

    Creating the Service File

    Create the service definition file:

    sudo nano /etc/systemd/system/kestrel-webapi1.service
    

    An example of service files for the application:

    [Unit]
    Description=Example .NET Web API application running on CentOS 7
    
    [Service]
    WorkingDirectory=/var/www/WebAPI1
    ExecStart=/usr/share/dotnet /var/www/WebAPI1/WebAPI1.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
    

    If the user apache isn't used by the configuration, the user must be created first and given proper ownership of the files.

    Use TimeoutStopSec to configure the duration of time to wait for the application to shut down after it receives the initial interrupt signal. If the application doesn't shut down in this period, SIGKILL is issued to terminate the application. Provide the value as unitless seconds (for example, 150), a time span value (for example, 2min 30s), or infinity to disable the timeout. TimeoutStopSec defaults to the value of DefaultTimeoutStopSec in the manager configuration file (systemd-system.conf, system.conf.d, systemd-user.conf, user.conf.d). The default timeout for most distributions is 90 seconds.

    # The default value is 90 seconds for most distributions.
    TimeoutStopSec=90
    

    Save the file and enable the service:

    sudo systemctl enable kestrel-webapi1.service
    

    Start the service and verify that it's running:

    # Start the service
    sudo systemctl start kestrel-webapi1.service
    
    # Verify the service
    sudo systemctl status kestrel-webapi1.service
    
     kestrel-webapi1.service - Example .NET Web API application running on CentOS 7
       Loaded: loaded (/etc/systemd/system/kestrel-webapi1.service; enabled; vendor preset: disabled)
       Active: active (running) since Tue 2019-08-06 13:46:27 CST; 5s ago
     Main PID: 46668 (dotnet)
        Tasks: 16
       CGroup: /system.slice/kestrel-webapi1.service
               └─46668 /usr/share/dotnet/dotnet /var/www/WebAPI1/WebAPI1.dll
    

    With the reverse proxy configured and Kestrel managed through systemd, the web application is fully configured and can be accessed from a browser on a local machine at http://localhost/api/sample/load. Inspecting the response headers, the Server header indicates that the Web API application is served by Kestrel:

    HTTP/1.1 200 OK
    Date: Tue, 06 Aug 2019 05:52:17 GMT
    Server: Kestrel
    Keep-Alive: timeout=5, max=100
    Connection: Keep-Alive
    Transfer-Encoding: chunked
    
    Viewing Logs

    Since the web application using Kestrel is managed using systemd, events and processes are logged to a centralized journal. However, this journal includes all of the entries for services and processes managed by systemd. View the specific items of kestrel-webapi1.service with the following command:

    sudo journalctl -fu kestrel-webapi1.service
    

    For time filtering, specify time options with the command. For example, use --since today to filter for the current day or --until 1 hour ago to see the previous hour's entries. For more information, see man page for journalctl.

    sudo journalctl -fu kestrel-webapi1.service --since "2019-08-06" --until "2019-08-06 23:00"
    

    Configuring the Reverse Proxy for Secure (HTTPS) Client Connections

    To configure Apache for HTTPS, the mod_ssl module is used. When the httpd module was installed, the mod_ssl module was also installed. If it wasn't installed, use yum to add it to the configuration.

    sudo yum install mod_ssl
    

    To enforce HTTPS, install the mod_rewrite module to enable URL rewriting:

    sudo yum install mod_rewrite
    

    Modify the /etc/httpd/conf.d/WebAPI1.conf file to enable URL rewriting and secure communication on port 443:

    <VirtualHost *:*>
        RequestHeader set "X-Forwarded-Proto" expr=$scheme
    </VirtualHost>
    
    <VirtualHost *:80>
        RewriteEngine On
        RewriteCond %{HTTPS} !=on
        RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]
    </VirtualHost>
    
    <VirtualHost *:443>
        ProxyPreserveHost On
        ProxyPass / http://127.0.0.1:5000/
        ProxyPassReverse / http://127.0.0.1:5000/
        ErrorLog /var/log/httpd/WebAPI1-error.log
        CustomLog /var/log/httpd/WebAPI1-access.log common
        SSLEngine on
        SSLProtocol all -SSLv2
        SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:!RC4+RSA:+HIGH:+MEDIUM:!LOW:!RC4
        SSLCertificateFile /etc/pki/tls/certs/localhost.crt
        SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
    </VirtualHost>
    

    This example is using a locally-generated certificate. SSLCertificateFile should be the primary certificate file for the domain name. SSLCertificateKeyFile should be the key file generated when CSR is created. SSLCertificateChainFile should be the intermediate certificate file (if present) that was supplied by the certificate authority.

    Save the file and test the configuration:

    sudo service httpd configtest
    

    Restart Apache:

    sudo systemctl restart httpd
    

    After HTTPS is fully configured, the web application can be accessed from a browser on a local machine at https://localhost/api/sample/load. Please pay attention here, it's https://....

    Attribution

    The content of this section incorporates some materials from "Host ASP.NET Core on Linux with Apache" by Shayne Boyer licensed under CC BY 2.0.

    Back to top