Search code examples
swiftibm-cloudcloud-foundryvapor

Trying to run Swift Vapor on Bluemix - 404 Not Found: Requested route does not exist


I'm trying to figure out how to deploy in IBM Bluemix a Cloudfoundry app that uses Vapor framework.

IBM is providing facilities and guidance for using his platform for developing server side Swift apps with his framework, Kitura. I think as a Cloudfoundry provider, with the proper Swift buildpack, we must be able to deploy generic server side Swift code.

Finally, while learning bits of CF, I reached the point that with the CloudFoundry CLI:

  1. I'm connecting to the Bluemix API endpoint (api .eu-gb .bluemix .net)
  2. Login ok (after expanding the timeout setting env. var CF_DIAL_TIMEOUT to 20)
  3. Making a "cf push". It creates the app and uploads and compiles everything.
  4. The app state is "running".

But when I load the page (https://sommobilitatcore.eu-gb.mybluemix.net/) I get:

404 Not Found: Requested route ('sommobilitatcore.eu-gb.mybluemix.net') does not exist.

Can anyone help me on that? Thanks!

Some context:

The manifest.yml:

applications:
- path: .
  memory: 256M
  instances: 1
  name: SomMobilitatCore
  disk_quota: 1024M
  buildpack: https://github.com/IBM-Swift/swift-buildpack.git

The Procfile

web: App

(main.swift is in Source/App/)

No port is configured in Vapor Config files, then Vapor is trying to listen to port 80:

import Vapor
import HTTP

let drop = Droplet()

let _ = drop.config["app", "key"]?.string ?? ""

drop.get("/") { request in
    return try drop.view.make("welcome.html")
}

(...)

let port = drop.config["app", "port"]?.int ?? 80

// Print what link to visit for default port
drop.serve()

UPDATE:

Finally get it working without Procfile, the manifest.yml

- path: .
  instances: 1
  memory: 256M
  disk_quota: 1024M
  name: SomMobilitat4
  command: App --env=production --workdir="./"
  buildpack: swift_buildpack

And the /Config/production/servers.json :

{
    "production": {
        "port": "$PORT"
    }
}

I neither specify the port variable in the main.swift file. With the updated Vapor version:

import Vapor
import HTTP

let drop = Droplet()

drop.get("/") { request in
    return "hello vapor in bluemix cloudfoundry"
}


drop.run()

If you are new to Cloudfoundry or IBM Bluemix, this is a way to work:

  1. You signup in a Cloudfoundry provider (ex: bluemix)

  2. You have you Vapor project locally.

  3. Add to it a .cfignore file with this short line: Packages/ to avoid uploading Packages to the server.

  4. Add to it the mentioned manifest.yml file.

  5. Download and install the Cloudfoundry CLI: https://docs.cloudfoundry.org/cf-cli/

    With the CLI:

  6. cf api https://api.eu-gb.bluemix.net

  7. cf login

  8. cf push


Solution

  • To run a Vapor app on Bluemix:

    1. Add Config directory with servers.json (use exactly these names). servers.json should contain the following:
          {
              "myserver": {
                  "port": "$PORT"
              }
          }
        

    It will instruct Vapor to start a server named myserver on the port taken from $PORT environment variable used by Bluemix.

    1. In your Procfile, add --workDir=. parameter, so it would contain:

      web: App --workDir=.
      

      It will instruct Vapor to look for Config directory in the current directory during run time.