使用 heroku 部署 Vapor

Deploying Vapor with heroku

我在 main.swift 中创建了一个只有一条路线的非常简单的应用程序。它从查询字符串中读取一个城市并使用它来获取该城市的天气(通过 yahoo API)。这是路线:

drop.get("whether") { request in


    guard let city = request.data["city"]?.string else {
        return try JSON(node: ["Error": "no city given"])
    }

    return try drop.client.get("https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20weather.forecast%20where%20woeid%20in%20(select%20woeid%20from%20geo.places(1)%20where%20text%3D%22\(city)%22)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys")
}

当我在本地主机上 运行 代码运行完美,但当我使用 Heroku 部署它时出现 500 错误。

有没有我不应该推送到 heroku 的文件?我要注意,在 server.json 中,主机值为 0.0.0.0

这是我的 Heroku 日志(请注意,我重新部署了它多次。所有这些都不起作用):

2017-01-05T17:00:28.932559+00:00 heroku[router]: at=info method=POST path="/whether" host=dry-beyond-95031.herokuapp.com request_id=10bd5717-a444-4106-9479-5dda7de686d1 fwd="94.77.202.2" dyno=web.1 connect=1ms service=24ms status=500 bytes=138
2017-01-05T17:00:34.568980+00:00 heroku[router]: at=info method=GET path="/whether" host=dry-beyond-95031.herokuapp.com request_id=88277ee9-5814-4e33-a180-69e2a36a10ac fwd="94.77.202.2" dyno=web.1 connect=0ms service=2ms status=404 bytes=161
2017-01-05T17:00:50.620499+00:00 heroku[router]: at=info method=POST path="/whether" host=dry-beyond-95031.herokuapp.com request_id=e9e03939-3252-4eb2-ba05-ed06b7123fc0 fwd="94.77.202.2" dyno=web.1 connect=0ms service=20ms status=500 bytes=138
2017-01-05T17:03:30.089070+00:00 heroku[router]: at=info method=POST path="/whether" host=dry-beyond-95031.herokuapp.com request_id=d3334e79-bdaf-4f51-a6fe-198a356c2c8a fwd="94.77.202.2" dyno=web.1 connect=0ms service=31ms status=500 bytes=138
2017-01-05T17:03:41.773239+00:00 heroku[router]: at=error code=H13 desc="Connection closed without response" method=POST path="/whether" host=dry-beyond-95031.herokuapp.com request_id=cb0f1bca-7538-497b-b1f2-6af9756c80f4 fwd="94.77.202.2" dyno=web.1 connect=2ms service=6ms status=503 bytes=0
2017-01-05T17:03:41.855395+00:00 heroku[web.1]: State changed from up to crashed
2017-01-05T17:03:41.856485+00:00 heroku[web.1]: State changed from crashed to starting
2017-01-05T17:03:41.842156+00:00 heroku[web.1]: Process exited with status 132
2017-01-05T17:03:45.147623+00:00 heroku[web.1]: Starting process with command `App --env=production --workdir=./ --config:servers.default.port=25036`
2017-01-05T17:03:48.789403+00:00 heroku[web.1]: State changed from starting to up
2017-01-05T17:04:29.863680+00:00 heroku[router]: at=info method=GET path="/" host=dry-beyond-95031.herokuapp.com request_id=82133ef0-4539-4095-b3a9-e4d0c4bc709c fwd="94.77.202.2" dyno=web.1 connect=0ms service=5ms status=404 bytes=119
2017-01-05T17:04:38.544040+00:00 heroku[router]: at=info method=GET path="/whether" host=dry-beyond-95031.herokuapp.com request_id=258ab0c8-df6e-4ad2-a220-cb27f854a1bd fwd="94.77.202.2" dyno=web.1 connect=0ms service=2ms status=404 bytes=119
2017-01-05T17:05:43.705482+00:00 heroku[web.1]: Process exited with status 132
2017-01-05T17:05:43.718722+00:00 heroku[web.1]: State changed from up to crashed
2017-01-05T17:05:43.608207+00:00 heroku[router]: at=error code=H13 desc="Connection closed without response" method=POST path="/whether" host=dry-beyond-95031.herokuapp.com request_id=1a343b3b-963e-45b0-9795-1f83351b0100 fwd="94.77.202.2" dyno=web.1 connect=1ms service=6ms status=503 bytes=0
2017-01-05T17:08:54.112283+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=POST path="/whether" host=dry-beyond-95031.herokuapp.com request_id=5fcfc4a8-d8da-4e45-b8d1-99a8c14c1529 fwd="94.77.202.2" dyno= connect= service= status=503 bytes=
2017-01-05T17:10:34.292205+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=POST path="/whether" host=dry-beyond-95031.herokuapp.com request_id=75035a40-c1ca-4fc9-8cd1-10f73c5a4b84 fwd="94.77.202.2" dyno= connect= service= status=503 bytes=
2017-01-05T17:17:45.483824+00:00 heroku[slug-compiler]: Slug compilation started
2017-01-05T17:17:45.483833+00:00 heroku[slug-compiler]: Slug compilation finished
2017-01-05T17:17:45.350717+00:00 app[api]: Deploy c3d8250 by user naifdev@gmail.com
2017-01-05T17:17:45.350717+00:00 app[api]: Release v4 created by user naifdev@gmail.com
2017-01-05T17:17:45.706244+00:00 heroku[web.1]: State changed from crashed to starting
2017-01-05T17:17:48.678813+00:00 heroku[web.1]: Starting process with command `App --env=production --workdir=./ --config:servers.default.port=53088`
2017-01-05T17:17:52.352793+00:00 heroku[web.1]: State changed from starting to up
2017-01-05T17:18:25.670087+00:00 heroku[router]: at=info method=POST path="/whether" host=dry-beyond-95031.herokuapp.com request_id=9cec4496-95c5-4157-8dea-002310af4eaf fwd="94.77.202.2" dyno=web.1 connect=1ms service=27ms status=500 bytes=138
2017-01-05T17:51:55.253360+00:00 heroku[web.1]: Idling
2017-01-05T17:51:55.254766+00:00 heroku[web.1]: State changed from up to down
2017-01-05T17:51:55.780574+00:00 app[web.1]: No command supplied, defaulting to serve...
2017-01-05T17:51:55.780578+00:00 app[web.1]: Server 'default' starting at 0.0.0.0:53088
2017-01-05T17:51:55.780562+00:00 app[web.1]: Production mode enabled, disabling informational logs.
2017-01-05T17:51:55.780575+00:00 app[web.1]: No preparations.
2017-01-05T17:51:55.780579+00:00 app[web.1]: [deprecated] Mozilla certificates have been deprecated and will be removed in future releases. Using 'defaults' instead.
2017-01-05T17:51:55.774837+00:00 heroku[web.1]: Stopping all processes with SIGTERM
2017-01-05T17:51:55.895627+00:00 heroku[web.1]: Process exited with status 15
2017-01-05T18:01:48.893674+00:00 heroku[web.1]: Unidling
2017-01-05T18:01:48.893975+00:00 heroku[web.1]: State changed from down to starting
2017-01-05T18:01:53.364634+00:00 heroku[web.1]: Starting process with command `App --env=production --workdir=./ --config:servers.default.port=21483`
2017-01-05T18:01:57.090891+00:00 heroku[web.1]: State changed from starting to up
2017-01-05T18:01:58.019181+00:00 heroku[router]: at=info method=POST path="/whether" host=dry-beyond-95031.herokuapp.com request_id=ed174181-b3c9-4196-bd39-29121c343ea6 fwd="94.77.202.2" dyno=web.1 connect=0ms service=41ms status=500 bytes=138
2017-01-05T18:34:12.945697+00:00 heroku[web.1]: Idling
2017-01-05T18:34:12.946307+00:00 heroku[web.1]: State changed from up to down
2017-01-05T18:34:13.855518+00:00 app[web.1]: Production mode enabled, disabling informational logs.
2017-01-05T18:34:13.855528+00:00 app[web.1]: No command supplied, defaulting to serve...
2017-01-05T18:34:13.855529+00:00 app[web.1]: No preparations.
2017-01-05T18:34:13.855530+00:00 app[web.1]: Server 'default' starting at 0.0.0.0:21483
2017-01-05T18:34:13.855531+00:00 app[web.1]: [deprecated] Mozilla certificates have been deprecated and will be removed in future releases. Using 'defaults' instead.
2017-01-05T18:34:13.848202+00:00 heroku[web.1]: Stopping all processes with SIGTERM
2017-01-05T18:34:13.932737+00:00 heroku[web.1]: Process exited with status 15
2017-01-06T07:44:31.444744+00:00 heroku[web.1]: Unidling
2017-01-06T07:44:31.444992+00:00 heroku[web.1]: State changed from down to starting
2017-01-06T07:44:34.523300+00:00 heroku[web.1]: Starting process with command `App --env=production --workdir=./ --config:servers.default.port=31252`
2017-01-06T07:44:36.676936+00:00 heroku[web.1]: State changed from starting to up
2017-01-06T07:44:37.549125+00:00 heroku[router]: at=info method=POST path="/whether" host=dry-beyond-95031.herokuapp.com request_id=0355d39f-cda9-4f8b-888b-18082332a824 fwd="94.99.227.109" dyno=web.1 connect=0ms service=26ms status=500 bytes=138
2017-01-06T07:50:51.627447+00:00 heroku[router]: at=info method=POST path="/whether" host=dry-beyond-95031.herokuapp.com request_id=11ee0882-1bd1-43a2-a0cc-4bc1c11f74eb fwd="94.99.227.109" dyno=web.1 connect=0ms service=27ms status=500 bytes=138
2017-01-06T07:57:45.954329+00:00 heroku[router]: at=info method=POST path="/whether" host=dry-beyond-95031.herokuapp.com request_id=e4ca9186-fdc5-4cd8-b98b-cfee45c7f3b2 fwd="94.99.227.109" dyno=web.1 connect=0ms service=213ms status=500 bytes=138
2017-01-06T08:04:00.591772+00:00 heroku[router]: at=info method=POST path="/whether" host=dry-beyond-95031.herokuapp.com request_id=b664a4c2-5aef-43b8-9c9f-180dfabeb93d fwd="94.99.227.109" dyno=web.1 connect=0ms service=23ms status=500 bytes=138
2017-01-06T08:04:57.818556+00:00 heroku[router]: at=info method=GET path="/" host=dry-beyond-95031.herokuapp.com request_id=4ea215b8-a0a3-4ad0-9d8a-45fe27dbafd0 fwd="94.99.227.109" dyno=web.1 connect=0ms service=4ms status=404 bytes=119
2017-01-06T08:04:58.069106+00:00 heroku[router]: at=info method=GET path="/favicon.ico" host=dry-beyond-95031.herokuapp.com request_id=04affbf0-ded7-4eb1-845c-e569aa31107c fwd="94.99.227.109" dyno=web.1 connect=0ms service=2ms status=404 bytes=161
2017-01-06T08:05:26.089377+00:00 heroku[router]: at=info method=POST path="/whether" host=dry-beyond-95031.herokuapp.com request_id=3c5ba6df-acec-4b27-a3f4-e3c0f27941c2 fwd="94.99.227.109" dyno=web.1 connect=0ms service=400ms status=500 bytes=138
2017-01-06T08:05:32.043519+00:00 heroku[router]: at=info method=GET path="/" host=dry-beyond-95031.herokuapp.com request_id=9d35561a-633b-42c9-8fb6-6ec423bf667c fwd="94.99.227.109" dyno=web.1 connect=0ms service=2ms status=404 bytes=119
2017-01-06T08:05:40.163170+00:00 heroku[router]: at=info method=GET path="/huguh" host=dry-beyond-95031.herokuapp.com request_id=7a11db63-7644-4e42-a662-e223cb154171 fwd="94.99.227.109" dyno=web.1 connect=0ms service=2ms status=404 bytes=119
2017-01-06T08:13:43.406289+00:00 heroku[router]: at=info method=GET path="/whether" host=dry-beyond-95031.herokuapp.com request_id=f672e00b-db30-484c-a5da-01f8e57022f4 fwd="94.99.227.109" dyno=web.1 connect=0ms service=2ms status=404 bytes=161
2017-01-06T08:13:55.835147+00:00 heroku[router]: at=info method=GET path="/whether" host=dry-beyond-95031.herokuapp.com request_id=adb06e24-72cc-4b79-9d23-8a5ea127d2a3 fwd="94.99.227.109" dyno=web.1 connect=0ms service=1ms status=404 bytes=161
2017-01-06T08:45:25.599867+00:00 heroku[web.1]: Idling
2017-01-06T08:45:25.600941+00:00 heroku[web.1]: State changed from up to down
2017-01-06T08:45:26.264901+00:00 heroku[web.1]: Stopping all processes with SIGTERM
2017-01-06T08:45:26.280223+00:00 app[web.1]: Production mode enabled, disabling informational logs.
2017-01-06T08:45:26.280240+00:00 app[web.1]: No command supplied, defaulting to serve...
2017-01-06T08:45:26.280241+00:00 app[web.1]: No preparations.
2017-01-06T08:45:26.280241+00:00 app[web.1]: Server 'default' starting at 0.0.0.0:31252
2017-01-06T08:45:26.280242+00:00 app[web.1]: [deprecated] Mozilla certificates have been deprecated and will be removed in future releases. Using 'defaults' instead.
2017-01-06T08:45:26.280243+00:00 app[web.1]: [deprecated] Mozilla certificates have been deprecated and will be removed in future releases. Using 'defaults' instead.
2017-01-06T08:45:26.280244+00:00 app[web.1]: [deprecated] Mozilla certificates have been deprecated and will be removed in future releases. Using 'defaults' instead.
2017-01-06T08:45:26.280244+00:00 app[web.1]: [deprecated] Mozilla certificates have been deprecated and will be removed in future releases. Using 'defaults' instead.
2017-01-06T08:45:26.280245+00:00 app[web.1]: unable to load path
2017-01-06T08:45:26.280246+00:00 app[web.1]: [deprecated] Mozilla certificates have been deprecated and will be removed in future releases. Using 'defaults' instead.
2017-01-06T08:45:26.280246+00:00 app[web.1]: unable to load path
2017-01-06T08:45:26.369735+00:00 heroku[web.1]: Process exited with status 15
2017-01-06T18:01:52.724336+00:00 heroku[web.1]: Unidling
2017-01-06T18:01:52.724823+00:00 heroku[web.1]: State changed from down to starting
2017-01-06T18:01:56.197941+00:00 heroku[web.1]: Starting process with command `App --env=production --workdir=./ --config:servers.default.port=51652`
2017-01-06T18:01:59.779285+00:00 heroku[web.1]: State changed from starting to up
2017-01-06T18:02:00.857405+00:00 heroku[router]: at=info method=GET path="/whether" host=dry-beyond-95031.herokuapp.com request_id=39353fc7-8f70-49b4-95b0-12b4f2e0980a fwd="94.99.227.109" dyno=web.1 connect=1ms service=4ms status=404 bytes=161
2017-01-06T18:36:26.460178+00:00 heroku[web.1]: Idling
2017-01-06T18:36:26.460594+00:00 heroku[web.1]: State changed from up to down
2017-01-06T18:36:27.237564+00:00 heroku[web.1]: Stopping all processes with SIGTERM
2017-01-06T18:36:27.390324+00:00 heroku[web.1]: Process exited with status 15
2017-01-06T18:36:27.262126+00:00 app[web.1]: Production mode enabled, disabling informational logs.
2017-01-06T18:36:27.262141+00:00 app[web.1]: No command supplied, defaulting to serve...
2017-01-06T18:36:27.262142+00:00 app[web.1]: No preparations.
2017-01-06T18:36:27.262143+00:00 app[web.1]: Server 'default' starting at 0.0.0.0:51652
2017-01-06T19:13:59.497901+00:00 heroku[slug-compiler]: Slug compilation started
2017-01-06T19:13:59.497911+00:00 heroku[slug-compiler]: Slug compilation finished
2017-01-06T19:13:59.336403+00:00 app[api]: Deploy fa16ad6 by user naifdev@gmail.com
2017-01-06T19:13:59.336403+00:00 app[api]: Release v5 created by user naifdev@gmail.com
2017-01-06T19:13:59.722058+00:00 heroku[web.1]: State changed from down to starting
2017-01-06T19:14:02.835500+00:00 heroku[web.1]: Starting process with command `App --env=production --workdir=./ --config:servers.default.port=8308`
2017-01-06T19:14:06.609232+00:00 heroku[web.1]: State changed from starting to up
2017-01-06T19:14:38.480190+00:00 heroku[router]: at=info method=GET path="/whether?city=Paris" host=dry-beyond-95031.herokuapp.com request_id=26c5f8bb-eb3b-47be-8fd2-799dfc4aed66 fwd="94.99.227.109" dyno=web.1 connect=1ms service=24ms status=500 bytes=138
2017-01-06T19:17:53.744114+00:00 heroku[router]: at=info method=GET path="/whether?city=Paris" host=dry-beyond-95031.herokuapp.com request_id=8414a869-8d81-480a-8a74-51cfb3644bbf fwd="94.99.227.109" dyno=web.1 connect=1ms service=221ms status=500 bytes=138
2017-01-06T19:18:06.721140+00:00 heroku[router]: at=info method=GET path="/whether?city=Paris" host=dry-beyond-95031.herokuapp.com request_id=04a1b568-bfe1-4643-9a34-fce7b23eb325 fwd="94.99.227.109" dyno=web.1 connect=1ms service=22ms status=500 bytes=138

Slack 频道的一位用户让我了解了这个问题。:

VZSG: @animatronicgopher:在 Heroku 上进行试验很便宜,但仅仅因为这个就扩展到付费测功机是毫无意义的。它确实 not 有所不同——首先,这个错误是由 HTTP 客户端 生成的,所以你的服务器证书无关紧要,其次,即使是免费的测功机也有适当的证书(而且它们不仅仅是 letsencrypt 证书)。您可能找到的是自定义域。

实际问题是 "default" HTTPClient 不关心 dyno 的可信根证书,因此无法验证传出的 SSL 连接 -> 错误。

此外,GitHub 中有一个问题为您提供了如何使用 FoundationClient 的示例。 https://github.com/vapor/vapor/issues/699

如何在 Vapor 框架的帮助下创建 swift 后端 API。市场上还有另一种框架。但是我们选择swift蒸气。

开始吧

在你的系统中安装 vapor。

第 1 步。运行 下面的命令安装 vapor

brew 安装vapor/tap/vapor-beta

检查 vapor 是否安装 运行 下面的命令。

vapor-beta --help

这些将是 vapor 的有用命令。

仅当您在项目目录中时才执行命令。 你可以

创建了 vapor 项目

vapor new myProjectName

构建 vapor 项目

蒸气构建

运行 蒸气项目

蒸气运行

您可以配置Xcode。您应该在创建的项目目录中。

蒸气Xcode

当您在项目文件中进行更改或为更新添加新功能时,您可以使用以下命令。

蒸气Xcode

您可以运行 通过本地服务器测试API。输出将是“Hello World”

卷曲 http://localhost:8080/hello

===========================================PostgreSQL 设置============================================= ===

设置本地 PrortgeSQL。 运行 下面的命令。

Brew 安装postgresql

启动本地数据库服务器。 运行 命令下方

pg_ctl-D/usr/local/var/postgres开始

停止本地数据库服务器。 运行 下面的命令。

pg_ctl-D/usr/local/var/postgres停止

当您希望 运行 PostgreSQL 作为后台服务启动时,您可以使用 brew server。 运行 下面的命令。

brew 服务启动postgresql

让我们从这里开始 Postgres。

psql -d postgres

通过以下命令运行创建数据库:

创建数据库数据库名称

实际命令 创建数据库 ashi-app

通过 运行ning 下面的命令创建用户:- 通过 运行ning 下面的命令授予该用户所需的权限。

创建用户用户名

实际命令 创建用户 ashi-app-user

将数据库 databaseName 的所有权限授予用户名

实际命令 将数据库 ashi-app 的所有权限授予 ashi-app-user =============================================PostgreSQL设置================================================

===========================================部署新鲜Heroku 上的应用程序=============================================== =

在没有数据库的情况下在 Heroku 上部署新的 swift vapor 应用程序。

假设您已经创建了一个没有数据库的 Vapor 项目。

步骤 1. 在 cd MyApp 上导航。

cd myApp 实际命令 cd ashi-api

第 2 步。在项目根目录中创建一个 swift 版本文件。 运行 在终端下方。

echo '5.1.3' > .swift-version

第 3 步。在终端下面的根项目 directory.Run 中创建 Procfile 文件。

echo ‘web: 运行 serve --env production --port $PORT --hostname 0.0.0.0' > Procfile

第 4 步。添加文件 git 并通过以下命令提交 git 添加 .

git commit -m ‘App Setup’

第 5 步。您应该通过以下命令生成 linux 测试文件。

swift 测试 --generate-linuxmain

第6步。通过以下命令再次添加在git中修改的内容。

git 添加 .

git commit -m ‘测试设置’

步骤 7. 登录 Heroku。需要在 heroku 上创建应用程序以进行部署。所以我们登录了heruko。通过运行ning下面的命令我们可以登录。

heroku 登录

第 8 步。登录完成后创建 heroku 应用程序。名称必须是唯一的,我们最喜欢的是 app-appname。

heroku 应用程序:创建 myAppName

实际命令 heroku 应用程序:创建 ashi-api

第 9 步。为应用程序添加 swift 构建包。为了在此基础上进行编译,我们必须添加 buildback。 Heroku 不支持 swift.

的内置包

heroku buildpacks:set https://github.com/vapor-community/heroku-buildpack -a myproject

实际命令 heroku buildpacks:set https://github.com/vapor-community/heroku-buildpack -a ashi-api

第 10 步。在服务器上查找命令推送更改。

git 推送 heroku 大师

现在您的应用程序和 API 将可用于测试…

===========================================部署新鲜Heroku 上的应用程序=============================================== =

======================使用已部署的应用程序和下一版本的部署设置数据库============ ======================

第一步,进行数据库配置。将 sqlite 数据库替换为 postgreSQL。因为Heroku不支持sqlite。

在App->configure.swift中替换。并导入 Todo.h TodoController.h

导入 FluentPostgreSQL

// 配置一个PostgreSQL 数据库 让 postgreSQLConfig: PostgreSQLDatabaseConfig

if let url = Environment.get("DATABASE_URL") {
  postgreSQLConfig = PostgreSQLDatabaseConfig(url: url)!
} else {
  postgreSQLConfig = PostgreSQLDatabaseConfig(hostname: "localhost", username: "app_test")
}
let postgreSQL = PostgreSQLDatabase(config: postgreSQLConfig)

// Register the configured PostreSQL database to the database config.
var databases = DatabasesConfig()
databases.add(database: postgreSQL, as: .psql)
services.register(databases)

第 2 步。通过 运行ning 使用 home-brew 安装 heroku 命令。

brew tap heroic/brew && brew install heroku

第三步,我们可以通过运行ning命令在应用中添加postgreSQL。

heroic addons:create heroic-postgresql:hobby-dev

第 4 步。通过 运行ning 下面的命令在 git 中添加更新文件。

git 添加 .

git commit -m '已添加 PostgreSQL 文件'

第 5 步。在服务器上查找命令推送更改。

git 推送 heroku 大师

第二个版本将可用于 postgreSQL 测试。

======================使用已部署的应用程序和下一版本的部署设置数据库============ ======================

====================== 测试应用程序 API ================ ==================

Step 1. Heroku API 路径将是。你的 https://app-name.herokoapp.com/youapIURL.

Heroku 部署的应用名称

样本获取

apiURL

数据获取请求

apiURL

Post 来自 post 人的请求。

apiURL

关注link.

运行 在终端上获取命令。

卷曲apiURL

运行 post 终端命令。

curl -x POST -H “ContentType” : application/json -d ‘{“title:exaple”}’ apiURL

====================== 测试应用程序 API ================ ==================

======================其他重要的git和英雄日志命令============ ======================

  1. 将本地存储库添加到 heroku。

git 远程添加 heroku appPath

  1. 查看远程推送并获取存储库路径。

git 远程-v

  1. 查看 heroku 应用程序

heroku 应用程序

  1. 查看 heroku 应用程序日志

行数

heroku 日志-n 100

heroku 日志

heroku logs -trail

======================其他重要的git和英雄日志命令============ ======================