swiftosx-servervaporperfectkitura

Point domain to a Web Application running on OS X Server (ex. Kitura, perfect, vapour server)


Using the OS X server application, I can point multiple domains to various websites. All domains can use port 80 at the same time and OS X will resolve which website to use.

When I start my kitura server (I suppose the same happens with Vapor and Perfect) I have to start it on a free port (ex. 8080). if I start it on 80 it will create a conflict with the websites and it will probably not answer my calls.

What is the correct way to setup Kitura so that port 80 is used together with other services?

I start kitura server using the following:

do {
    let controller = try Controller()
    Log.info("Server will be started on '\(controller.url)'.")
    Kitura.addHTTPServer(onPort: controller.port, with: controller.router)
    // Start Kitura-Starter server
    Kitura.run()
} catch let error {
    Log.error(error.localizedDescription)
    Log.error("Oops... something went wrong. Server did not start!")
}

And I get the following on the log:

[2017-06-27T17:57:30.635+03:00] [VERBOSE] [Router.swift:68 init(mergeParameters:)] Router initialized
[2017-06-27T17:57:36.817+03:00] [INFO] [main.swift:37 KiteSpotterServer] Server will be started on 'http://localhost:8080'.
[2017-06-27T17:57:37.588+03:00] [VERBOSE] [Kitura.swift:72 run()] Starting Kitura framework...
[2017-06-27T17:57:38.457+03:00] [VERBOSE] [Kitura.swift:82 start()] Starting an HTTP Server on port 8080...
[2017-06-27T17:57:39.190+03:00] [INFO] [HTTPServer.swift:117 listen(on:)] Listening on port 8080

Solution

  • The most common and probably easiest way to make your application reachable via port 80 on OS X (or macOS), is to configure a reverse proxy.

    This solution applies to any web application, not just Kitura.

    The OS X Server app comes with an Apache server which can be configured to act as a reverse proxy. The Apache reverse proxy can listen on port 80 for a specific domain, then forward all requests to the internal port 8080 your application listens on, and vice versa.

    How to do this properly:

    Step 1: In /Library/Server/Web/config/apache2/webapps, create a plist file called my.application.plist (for example). This plist describes a so-called webapp which can than be activated in the OS X server app.

    Example webapp plist:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <!-- Allow to include a custom Apache configuration file from Server app  -->
    <plist version="1.0">
    <dict>
        <key>includeFiles</key>
        <array>         
          <!-- Include files are activated in virtual host when webapp is started -->
          <string>/Library/Server/Web/Config/apache2/httpd_webapp_myapp.conf</string>
        </array>
    
        <key>name</key>
        <string>com.atlassian.webapp.myapp</string>
        <key>displayName</key>          <!-- Name shown in Server app -->
        <string>Reverse proxy for myapp</string>
        <key>installationIndicatorFilePath</key>        <!-- The presence of this file indicates web app is installed -->
        <string>/Library/Server/Web/Config/apache2/httpd_webapp_myapp.conf</string>
    
        <key>sslPolicy</key><!-- Determines webapp SSL behavior -->
        <integer>0</integer>
        <!-- 0: default, UseSSLWhenEnabled -->
        <!-- 1: UseSSLAlways -->
        <!-- 2: UseSSLOnlyWhenCertificateIsTrustable -->
        <!-- 3: UseSSLNever -->
        <!-- 4: UseSSLAndNonSSL -->
    </dict>
    </plist>
    

    In the above example, replace myapp by your app name.

    Step 2: Next, in /Library/Server/Web/Config/apache2, create a file with the name you selected in the plist file (httpd_webapp_myapp.conf in my example). That file will configure the reverse proxy.

    Example proxy configuration file:

    # As described at http://httpd.apache.org/docs/2.2/mod/mod_proxy.html#proxypass
    # Service proxy for myapp installation
    ProxyRequests Off
    ProxyVia Off
    <Proxy *>
         Require all granted
    </Proxy>
    ProxyPass / http://myapp.mydomain:8080/
    ProxyPassReverse / http://myapp.mydomain:8080/
    

    In the above example, replace myapp.mydomain by the domain under which you want to reach your application (and 8080 by the application's port, if it's different).

    Important: Both of these files must be created/edited using sudo nano, and they must be owned by root.

    Step 3: In the OS X Server app, go to Websites, select the domain you want to use (double-click or click the edit symbol), then click on Edit advanced settings. If all went well, your newly created webapp will appear under Make these webapps available under this website. Check the box of your webapp, then save.

    It's usually not necessary to restart the web server (the Server app will do this for you).

    Step 4: Test if you can reach your application under this domain.

    Note: It may be necessary to configure the application somehow, so it knows it runs behind a reverse proxy.

    At first glance, this may appear a bit complicated, but it isn't really, and as far as I know, it is now the only accepted way to configure a reverse proxy on OS X server.