1、在本地开发环境中,基于 Laravel Sail 已经部署完毕。打开网址:http://weibo.test/ ,响应 200。如图1

图1

2、注册一个 Heroku 账号,使用 @163.com ,发现不被允许,最后使用 @gmail.com,才注册成功。如图2

图2

3、在邮箱 @gmail.com 中点击链接以激活帐户。如图3

图3

4、参考网址:https://devcenter.heroku.com/articles/heroku-cli 。Heroku 命令行界面 (CLI) 使直接从终端创建和管理 Heroku 应用程序变得容易。 这是使用 Heroku 的重要组成部分。

5、在 WSL2 中的 Ubuntu 系统中,从终端运行以下命令。报错:error: cannot communicate with server: Post http://localhost/v2/snaps/heroku: dial unix /run/snapd.socket: connect: no such file or directory。如图4

图4

wangqiang@DESKTOP-QLPK8QM:/mnt/e/wwwroot/weibo$ sudo snap install --classic heroku
error: cannot communicate with server: Post http://localhost/v2/snaps/heroku: dial unix /run/snapd.socket: connect: no such file or directory

6、最终决定使用 Windows 下的软件。为您的 Windows 安装下载合适的安装程序。如图5

图5

7、安装过程中报错:Error opening file for writing。如图6

图6

Error opening file for writing:

D:\Program Files\heroku\client\bin\node.exe

Click Abort to stop the installation,
Retry to try again, or
Ignore to skip this file.

8、重新安装,以管理员身份运行,不再报错。

9、验证您的安装,要验证您的 CLI 安装,请使用 heroku –version 命令。已经成功安装。如图7

图7

PS C:\Users\Lenovo> heroku --version
 »   Warning: Our terms of service have changed: https://dashboard.heroku.com/terms-of-service
heroku/7.53.0 win32-x64 node-v12.21.0
PS C:\Users\Lenovo>

10、安装 CLI 后,运行 heroku login 命令。 系统会提示您输入任意键以转到 Web 浏览器以完成登录。 然后 CLI 会自动让您登录。如图8

图8

PS C:\Users\Lenovo> heroku login
heroku: Press any key to open up the browser to login or q to exit:
Opening browser to https://cli-auth.heroku.com/auth/cli/browser/056bdba3-dbeb-43ee-9ffc-9556ce91ee23?requestor=SFMyNTY.g2gDbQAAAA42Ni4xNzUuMjE2LjIzOW4GAMhVMuV9AWIAAVGA.7UEaCXMegvnax1AIZ5H_XignHykfVPEHFYcOP0NL2uI
Logging in... done
Logged in as shuijingwanwq@gmail.com
PS C:\Users\Lenovo>

11、参考网址:https://devcenter.heroku.com/articles/getting-started-with-php 。因为文档假设 PHP 与 Composer 安装在本地。由于本地环境的 PHP 版本与 Laravel Sail 环境中的版本不一致,决定先将本地环境的 PHP 版本升级至 PHP 8.1。如图9、图10

图9

 

图10

本地环境的版本号:

PS C:\Users\Lenovo> php -v
PHP 7.4.27 (cli) (built: Dec 14 2021 19:52:13) ( ZTS Visual C++ 2017 x64 )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
PS C:\Users\Lenovo> composer -V
Composer version 2.1.14 2021-11-30 10:51:43
PS C:\Users\Lenovo>

Laravel Sail 环境的版本号:

# php -v
PHP 8.1.0 (cli) (built: Nov 25 2021 20:22:22) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.1.0, Copyright (c) Zend Technologies
    with Zend OPcache v8.1.0, Copyright (c), by Zend Technologies
    with Xdebug v3.1.1, Copyright (c) 2002-2021, by Derick Rethans
# composer -V
Composer version 2.1.14 2021-11-30 10:51:43
#

12、升级后的本地环境的 PHP 版本,PHP 8.1.1。

PS C:\Users\Lenovo> php -v
PHP 8.1.1 (cli) (built: Dec 15 2021 10:31:43) (ZTS Visual C++ 2019 x64)
Copyright (c) The PHP Group
Zend Engine v4.1.1, Copyright (c) Zend Technologies
PS C:\Users\Lenovo>

13、进入程序根目录,使用 heroku create 命令在 Heroku 上创建一个新应用。secret-stream-72395 是 Heroku 随机为应用生成的默认名称,每个人生成的名称都不相同。而 https://secret-stream-72395.herokuapp.com/ 则是应用的线上地址。如图11

图11

PS E:\wwwroot> cd .\weibo\
PS E:\wwwroot\weibo> heroku create
 »   Warning: heroku update available from 7.53.0 to 7.59.2.
Creating app... done, ⬢ secret-stream-72395
https://secret-stream-72395.herokuapp.com/ | https://git.heroku.com/secret-stream-72395.git
PS E:\wwwroot\weibo>

14、Heroku 平台支持多种语言,在进行应用部署时,Heroku 会自动检查应用的代码是用什么语言写的,然后再接着执行一系列针对该语言的操作来准备好程序运行环境。Laravel 应用默认会包含 package.json 文件,但当 Heroku 检查到该文件时,它会认为此应用是用 Node.js 写的,因此我们需要对应用的 buildpack 进行声明,告诉 Heroku 说我们的应用是用 PHP 写的。如图12

图12

PS E:\wwwroot\weibo> heroku buildpacks:set heroku/php
 »   Warning: heroku update available from 7.53.0 to 7.59.2.
Buildpack set. Next release on secret-stream-72395 will use heroku/php.
Run git push heroku main to create a new release using this buildpack.
PS E:\wwwroot\weibo>

15、将代码推送和部署到 Heroku 上。如图13

图13

PS E:\wwwroot\weibo> git status
On branch main
Your branch is up to date with 'origin/main'.

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   docker-compose.yml

PS E:\wwwroot\weibo> git push heroku main
Enumerating objects: 195, done.
Counting objects: 100% (195/195), done.
Delta compression using up to 4 threads
Compressing objects: 100% (169/169), done.
Writing objects: 100% (195/195), 651.34 KiB | 1.41 MiB/s, done.
Total 195 (delta 47), reused 0 (delta 0), pack-reused 0
remote: Compressing source files... done.
remote: Building source:
remote:
remote: -----> Building on the Heroku-20 stack
remote: -----> Using buildpack: heroku/php
remote: -----> PHP app detected
remote: -----> Bootstrapping...
remote: -----> Installing platform packages...
remote:        - php (8.1.1)
remote:        - ext-mbstring (bundled with php)
remote:        - composer (2.1.14)
remote:        - apache (2.4.51)
remote:        - nginx (1.20.2)
remote: -----> Installing dependencies...
remote:        Composer version 2.1.14 2021-11-30 10:51:43
remote:        Installing dependencies from lock file
remote:        Verifying lock file contents can be installed on current platform.
remote:        Package operations: 70 installs, 0 updates, 0 removals
remote:          - Downloading doctrine/inflector (2.0.4)
remote:          - Downloading doctrine/lexer (1.2.1)
remote:          - Downloading symfony/polyfill-ctype (v1.23.0)
remote:          - Downloading webmozart/assert (1.10.0)
remote:          - Downloading dragonmantank/cron-expression (v3.1.0)
remote:          - Downloading symfony/polyfill-php80 (v1.23.1)
remote:          - Downloading symfony/polyfill-php73 (v1.23.0)
remote:          - Downloading symfony/polyfill-mbstring (v1.23.1)
remote:          - Downloading symfony/deprecation-contracts (v3.0.0)
remote:          - Downloading symfony/http-foundation (v5.4.1)
remote:          - Downloading psr/event-dispatcher (1.0.0)
remote:          - Downloading symfony/event-dispatcher-contracts (v3.0.0)
remote:          - Downloading symfony/event-dispatcher (v6.0.1)
remote:          - Downloading symfony/var-dumper (v5.4.1)
remote:          - Downloading psr/log (2.0.0)
remote:          - Downloading symfony/error-handler (v5.4.1)
remote:          - Downloading symfony/http-kernel (v5.4.1)
remote:          - Downloading voku/portable-ascii (1.5.6)
remote:          - Downloading phpoption/phpoption (1.8.1)
remote:          - Downloading graham-campbell/result-type (v1.0.4)
remote:          - Downloading vlucas/phpdotenv (v5.4.1)
remote:          - Downloading symfony/css-selector (v6.0.1)
remote:          - Downloading tijsverkoyen/css-to-inline-styles (2.2.4)
remote:          - Downloading symfony/routing (v5.4.0)
remote:          - Downloading symfony/process (v5.4.0)
remote:          - Downloading symfony/polyfill-php72 (v1.23.0)
remote:          - Downloading symfony/polyfill-intl-normalizer (v1.23.0)
remote:          - Downloading symfony/polyfill-intl-idn (v1.23.0)
remote:          - Downloading symfony/mime (v5.4.0)
remote:          - Downloading symfony/finder (v5.4.0)
remote:          - Downloading symfony/polyfill-intl-grapheme (v1.23.1)
remote:          - Downloading symfony/string (v6.0.1)
remote:          - Downloading psr/container (1.1.2)
remote:          - Downloading symfony/service-contracts (v2.4.1)
remote:          - Downloading symfony/console (v5.4.1)
remote:          - Downloading symfony/polyfill-iconv (v1.23.0)
remote:          - Downloading egulias/email-validator (2.1.25)
remote:          - Downloading swiftmailer/swiftmailer (v6.3.0)
remote:          - Downloading symfony/polyfill-php81 (v1.23.0)
remote:          - Downloading ramsey/collection (1.2.2)
remote:          - Downloading brick/math (0.9.3)
remote:          - Downloading ramsey/uuid (4.2.3)
remote:          - Downloading psr/simple-cache (1.0.1)
remote:          - Downloading opis/closure (3.6.2)
remote:          - Downloading symfony/translation-contracts (v3.0.0)
remote:          - Downloading symfony/translation (v6.0.1)
remote:          - Downloading nesbot/carbon (2.55.2)
remote:          - Downloading monolog/monolog (2.3.5)
remote:          - Downloading league/mime-type-detection (1.9.0)
remote:          - Downloading league/flysystem (1.1.9)
remote:          - Downloading nette/utils (v3.2.6)
remote:          - Downloading nette/schema (v1.2.2)
remote:          - Downloading dflydev/dot-access-data (v3.0.1)
remote:          - Downloading league/config (v1.1.1)
remote:          - Downloading league/commonmark (2.1.0)
remote:          - Downloading laravel/serializable-closure (v1.0.5)
remote:          - Downloading laravel/framework (v8.76.2)
remote:          - Downloading asm89/stack-cors (v2.0.3)
remote:          - Downloading fruitcake/laravel-cors (v2.0.4)
remote:          - Downloading psr/http-message (1.0.1)
remote:          - Downloading psr/http-client (1.0.1)
remote:          - Downloading ralouphie/getallheaders (3.0.3)
remote:          - Downloading psr/http-factory (1.0.1)
remote:          - Downloading guzzlehttp/psr7 (2.1.0)
remote:          - Downloading guzzlehttp/promises (1.5.1)
remote:          - Downloading guzzlehttp/guzzle (7.4.1)
remote:          - Downloading laravel/sanctum (v2.13.0)
remote:          - Downloading nikic/php-parser (v4.13.2)
remote:          - Downloading psy/psysh (v0.10.12)
remote:          - Downloading laravel/tinker (v2.6.3)
remote:          - Installing doctrine/inflector (2.0.4): Extracting archive
remote:          - Installing doctrine/lexer (1.2.1): Extracting archive
remote:          - Installing symfony/polyfill-ctype (v1.23.0): Extracting archive
remote:          - Installing webmozart/assert (1.10.0): Extracting archive
remote:          - Installing dragonmantank/cron-expression (v3.1.0): Extracting archive
remote:          - Installing symfony/polyfill-php80 (v1.23.1): Extracting archive
remote:          - Installing symfony/polyfill-php73 (v1.23.0): Extracting archive
remote:          - Installing symfony/polyfill-mbstring (v1.23.1): Extracting archive
remote:          - Installing symfony/deprecation-contracts (v3.0.0): Extracting archive
remote:          - Installing symfony/http-foundation (v5.4.1): Extracting archive
remote:          - Installing psr/event-dispatcher (1.0.0): Extracting archive
remote:          - Installing symfony/event-dispatcher-contracts (v3.0.0): Extracting archive
remote:          - Installing symfony/event-dispatcher (v6.0.1): Extracting archive
remote:          - Installing symfony/var-dumper (v5.4.1): Extracting archive
remote:          - Installing psr/log (2.0.0): Extracting archive
remote:          - Installing symfony/error-handler (v5.4.1): Extracting archive
remote:          - Installing symfony/http-kernel (v5.4.1): Extracting archive
remote:          - Installing voku/portable-ascii (1.5.6): Extracting archive
remote:          - Installing phpoption/phpoption (1.8.1): Extracting archive
remote:          - Installing graham-campbell/result-type (v1.0.4): Extracting archive
remote:          - Installing vlucas/phpdotenv (v5.4.1): Extracting archive
remote:          - Installing symfony/css-selector (v6.0.1): Extracting archive
remote:          - Installing tijsverkoyen/css-to-inline-styles (2.2.4): Extracting archive
remote:          - Installing symfony/routing (v5.4.0): Extracting archive
remote:          - Installing symfony/process (v5.4.0): Extracting archive
remote:          - Installing symfony/polyfill-php72 (v1.23.0): Extracting archive
remote:          - Installing symfony/polyfill-intl-normalizer (v1.23.0): Extracting archive
remote:          - Installing symfony/polyfill-intl-idn (v1.23.0): Extracting archive
remote:          - Installing symfony/mime (v5.4.0): Extracting archive
remote:          - Installing symfony/finder (v5.4.0): Extracting archive
remote:          - Installing symfony/polyfill-intl-grapheme (v1.23.1): Extracting archive
remote:          - Installing symfony/string (v6.0.1): Extracting archive
remote:          - Installing psr/container (1.1.2): Extracting archive
remote:          - Installing symfony/service-contracts (v2.4.1): Extracting archive
remote:          - Installing symfony/console (v5.4.1): Extracting archive
remote:          - Installing symfony/polyfill-iconv (v1.23.0): Extracting archive
remote:          - Installing egulias/email-validator (2.1.25): Extracting archive
remote:          - Installing swiftmailer/swiftmailer (v6.3.0): Extracting archive
remote:          - Installing symfony/polyfill-php81 (v1.23.0): Extracting archive
remote:          - Installing ramsey/collection (1.2.2): Extracting archive
remote:          - Installing brick/math (0.9.3): Extracting archive
remote:          - Installing ramsey/uuid (4.2.3): Extracting archive
remote:          - Installing psr/simple-cache (1.0.1): Extracting archive
remote:          - Installing opis/closure (3.6.2): Extracting archive
remote:          - Installing symfony/translation-contracts (v3.0.0): Extracting archive
remote:          - Installing symfony/translation (v6.0.1): Extracting archive
remote:          - Installing nesbot/carbon (2.55.2): Extracting archive
remote:          - Installing monolog/monolog (2.3.5): Extracting archive
remote:          - Installing league/mime-type-detection (1.9.0): Extracting archive
remote:          - Installing league/flysystem (1.1.9): Extracting archive
remote:          - Installing nette/utils (v3.2.6): Extracting archive
remote:          - Installing nette/schema (v1.2.2): Extracting archive
remote:          - Installing dflydev/dot-access-data (v3.0.1): Extracting archive
remote:          - Installing league/config (v1.1.1): Extracting archive
remote:          - Installing league/commonmark (2.1.0): Extracting archive
remote:          - Installing laravel/serializable-closure (v1.0.5): Extracting archive
remote:          - Installing laravel/framework (v8.76.2): Extracting archive
remote:          - Installing asm89/stack-cors (v2.0.3): Extracting archive
remote:          - Installing fruitcake/laravel-cors (v2.0.4): Extracting archive
remote:          - Installing psr/http-message (1.0.1): Extracting archive
remote:          - Installing psr/http-client (1.0.1): Extracting archive
remote:          - Installing ralouphie/getallheaders (3.0.3): Extracting archive
remote:          - Installing psr/http-factory (1.0.1): Extracting archive
remote:          - Installing guzzlehttp/psr7 (2.1.0): Extracting archive
remote:          - Installing guzzlehttp/promises (1.5.1): Extracting archive
remote:          - Installing guzzlehttp/guzzle (7.4.1): Extracting archive
remote:          - Installing laravel/sanctum (v2.13.0): Extracting archive
remote:          - Installing nikic/php-parser (v4.13.2): Extracting archive
remote:          - Installing psy/psysh (v0.10.12): Extracting archive
remote:          - Installing laravel/tinker (v2.6.3): Extracting archive
remote:        Package swiftmailer/swiftmailer is abandoned, you should avoid using it. Use symfony/mailer instead.
remote:        Generating optimized autoload files
remote:        > Illuminate\Foundation\ComposerScripts::postAutoloadDump
remote:        > @php artisan package:discover --ansi
remote:        Discovered Package: fruitcake/laravel-cors
remote:        Discovered Package: laravel/sanctum
remote:        Discovered Package: laravel/tinker
remote:        Discovered Package: nesbot/carbon
remote:        Package manifest generated successfully.
remote:        49 packages you are using are looking for funding.
remote:        Use the `composer fund` command to find out more!
remote: -----> Preparing runtime environment...
remote:        NOTICE: No Procfile, using 'web: heroku-php-apache2'.
remote: -----> Checking for additional extensions to install...
remote: -----> Discovering process types
remote:        Procfile declares types -> web
remote:
remote: -----> Compressing...
remote:        Done: 19.8M
remote: -----> Launching...
remote:        Released v3
remote:        https://secret-stream-72395.herokuapp.com/ deployed to Heroku
remote:
remote: Verifying deploy... done.
To https://git.heroku.com/secret-stream-72395.git
 * [new branch]      main -> main
PS E:\wwwroot\weibo>

16、应用程序现已部署。 确保至少有一个应用实例正在运行,现在通过应用程序名称生成的 URL 访问该应用程序。 作为一个方便的快捷方式,您可以按如下方式打开网站。如图14

图14

PS E:\wwwroot\weibo> heroku ps:scale web=1
 »   Warning: heroku update available from 7.53.0 to 7.59.2.
Scaling dynos... done, now running web at 1:Free
PS E:\wwwroot\weibo> heroku open
 »   Warning: heroku update available from 7.53.0 to 7.59.2.
PS E:\wwwroot\weibo>

17、但是,在浏览器中自动打开网站:https://secret-stream-72395.herokuapp.com/ ,响应 403。如图15

图15

Forbidden
You don't have permission to access this resource.

18、在步骤 15 中提示:No Procfile, using ‘web: heroku-php-apache2’。Laravel 项目下新建一个 Procfile 文件,通过配置该文件来告诉 Heroku 应当使用什么命令来启动 Web 服务器。接着还需要将该文件纳入到 Git 版本控制中。报错:Push failed: cannot parse Procfile.。如图16

图16

PS E:\wwwroot\weibo> echo web: vendor/bin/heroku-php-apache2 public/ > Procfile
PS E:\wwwroot\weibo> git add -A
PS E:\wwwroot\weibo> git commit -m "Procfile for Heroku"
[main 64256ed] Procfile for Heroku
 2 files changed, 6 insertions(+), 6 deletions(-)
 create mode 100644 Procfile
PS E:\wwwroot\weibo> git push heroku main
Enumerating objects: 6, done.
Counting objects: 100% (6/6), done.
Delta compression using up to 4 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 496 bytes | 496.00 KiB/s, done.
Total 4 (delta 2), reused 0 (delta 0), pack-reused 0
remote: Compressing source files... done.
remote: Building source:
remote:
remote: -----> Building on the Heroku-20 stack
remote: -----> Using buildpack: heroku/php
remote: -----> PHP app detected
remote: -----> Bootstrapping...
remote: -----> Installing platform packages...
remote:        - php (8.1.1)
remote:        - ext-mbstring (bundled with php)
remote:        - composer (2.1.14)
remote:        - apache (2.4.51)
remote:        - nginx (1.20.2)
remote: -----> Installing dependencies...
remote:        Composer version 2.1.14 2021-11-30 10:51:43
remote:        Installing dependencies from lock file
remote:        Verifying lock file contents can be installed on current platform.
remote:        Package operations: 70 installs, 0 updates, 0 removals
remote:          - Installing doctrine/inflector (2.0.4): Extracting archive
remote:          - Installing doctrine/lexer (1.2.1): Extracting archive
remote:          - Installing symfony/polyfill-ctype (v1.23.0): Extracting archive
remote:          - Installing webmozart/assert (1.10.0): Extracting archive
remote:          - Installing dragonmantank/cron-expression (v3.1.0): Extracting archive
remote:          - Installing symfony/polyfill-php80 (v1.23.1): Extracting archive
remote:          - Installing symfony/polyfill-php73 (v1.23.0): Extracting archive
remote:          - Installing symfony/polyfill-mbstring (v1.23.1): Extracting archive
remote:          - Installing symfony/deprecation-contracts (v3.0.0): Extracting archive
remote:          - Installing symfony/http-foundation (v5.4.1): Extracting archive
remote:          - Installing psr/event-dispatcher (1.0.0): Extracting archive
remote:          - Installing symfony/event-dispatcher-contracts (v3.0.0): Extracting archive
remote:          - Installing symfony/event-dispatcher (v6.0.1): Extracting archive
remote:          - Installing symfony/var-dumper (v5.4.1): Extracting archive
remote:          - Installing psr/log (2.0.0): Extracting archive
remote:          - Installing symfony/error-handler (v5.4.1): Extracting archive
remote:          - Installing symfony/http-kernel (v5.4.1): Extracting archive
remote:          - Installing voku/portable-ascii (1.5.6): Extracting archive
remote:          - Installing phpoption/phpoption (1.8.1): Extracting archive
remote:          - Installing graham-campbell/result-type (v1.0.4): Extracting archive
remote:          - Installing vlucas/phpdotenv (v5.4.1): Extracting archive
remote:          - Installing symfony/css-selector (v6.0.1): Extracting archive
remote:          - Installing tijsverkoyen/css-to-inline-styles (2.2.4): Extracting archive
remote:          - Installing symfony/routing (v5.4.0): Extracting archive
remote:          - Installing symfony/process (v5.4.0): Extracting archive
remote:          - Installing symfony/polyfill-php72 (v1.23.0): Extracting archive
remote:          - Installing symfony/polyfill-intl-normalizer (v1.23.0): Extracting archive
remote:          - Installing symfony/polyfill-intl-idn (v1.23.0): Extracting archive
remote:          - Installing symfony/mime (v5.4.0): Extracting archive
remote:          - Installing symfony/finder (v5.4.0): Extracting archive
remote:          - Installing symfony/polyfill-intl-grapheme (v1.23.1): Extracting archive
remote:          - Installing symfony/string (v6.0.1): Extracting archive
remote:          - Installing psr/container (1.1.2): Extracting archive
remote:          - Installing symfony/service-contracts (v2.4.1): Extracting archive
remote:          - Installing symfony/console (v5.4.1): Extracting archive
remote:          - Installing symfony/polyfill-iconv (v1.23.0): Extracting archive
remote:          - Installing egulias/email-validator (2.1.25): Extracting archive
remote:          - Installing swiftmailer/swiftmailer (v6.3.0): Extracting archive
remote:          - Installing symfony/polyfill-php81 (v1.23.0): Extracting archive
remote:          - Installing ramsey/collection (1.2.2): Extracting archive
remote:          - Installing brick/math (0.9.3): Extracting archive
remote:          - Installing ramsey/uuid (4.2.3): Extracting archive
remote:          - Installing psr/simple-cache (1.0.1): Extracting archive
remote:          - Installing opis/closure (3.6.2): Extracting archive
remote:          - Installing symfony/translation-contracts (v3.0.0): Extracting archive
remote:          - Installing symfony/translation (v6.0.1): Extracting archive
remote:          - Installing nesbot/carbon (2.55.2): Extracting archive
remote:          - Installing monolog/monolog (2.3.5): Extracting archive
remote:          - Installing league/mime-type-detection (1.9.0): Extracting archive
remote:          - Installing league/flysystem (1.1.9): Extracting archive
remote:          - Installing nette/utils (v3.2.6): Extracting archive
remote:          - Installing nette/schema (v1.2.2): Extracting archive
remote:          - Installing dflydev/dot-access-data (v3.0.1): Extracting archive
remote:          - Installing league/config (v1.1.1): Extracting archive
remote:          - Installing league/commonmark (2.1.0): Extracting archive
remote:          - Installing laravel/serializable-closure (v1.0.5): Extracting archive
remote:          - Installing laravel/framework (v8.76.2): Extracting archive
remote:          - Installing asm89/stack-cors (v2.0.3): Extracting archive
remote:          - Installing fruitcake/laravel-cors (v2.0.4): Extracting archive
remote:          - Installing psr/http-message (1.0.1): Extracting archive
remote:          - Installing psr/http-client (1.0.1): Extracting archive
remote:          - Installing ralouphie/getallheaders (3.0.3): Extracting archive
remote:          - Installing psr/http-factory (1.0.1): Extracting archive
remote:          - Installing guzzlehttp/psr7 (2.1.0): Extracting archive
remote:          - Installing guzzlehttp/promises (1.5.1): Extracting archive
remote:          - Installing guzzlehttp/guzzle (7.4.1): Extracting archive
remote:          - Installing laravel/sanctum (v2.13.0): Extracting archive
remote:          - Installing nikic/php-parser (v4.13.2): Extracting archive
remote:          - Installing psy/psysh (v0.10.12): Extracting archive
remote:          - Installing laravel/tinker (v2.6.3): Extracting archive
remote:        Package swiftmailer/swiftmailer is abandoned, you should avoid using it. Use symfony/mailer instead.
remote:        Generating optimized autoload files
remote:        > Illuminate\Foundation\ComposerScripts::postAutoloadDump
remote:        > @php artisan package:discover --ansi
remote:        Discovered Package: fruitcake/laravel-cors
remote:        Discovered Package: laravel/sanctum
remote:        Discovered Package: laravel/tinker
remote:        Discovered Package: nesbot/carbon
remote:        Package manifest generated successfully.
remote:        49 packages you are using are looking for funding.
remote:        Use the `composer fund` command to find out more!
remote: -----> Preparing runtime environment...
remote: -----> Checking for additional extensions to install...
remote: -----> Discovering process types
remote:
remote:  !     Push failed: cannot parse Procfile.
remote:  !     Please try pushing again.
remote:  !     If the problem persists, see https://help.heroku.com/ and provide Request ID f09b381f-8217-327d-d121-119f1e8d0c31.
remote:
remote:
remote: Verifying deploy...
remote:
remote: !       Push rejected to secret-stream-72395.
remote:
To https://git.heroku.com/secret-stream-72395.git
 ! [remote rejected] main -> main (pre-receive hook declined)
error: failed to push some refs to 'https://git.heroku.com/secret-stream-72395.git'
PS E:\wwwroot\weibo>

19、查看文件 Procfile 的内容,如图17

图17

web:
vendor/bin/heroku-php-apache2
public/

20、参考 Getting Started with Laravel on Heroku:https://devcenter.heroku.com/articles/getting-started-with-laravel 。查看文件 Procfile 的内容,如图18

图18

PS E:\wwwroot\weibo> echo "web: vendor/bin/heroku-php-apache2 public/" > Procfile
PS E:\wwwroot\weibo> git add .
PS E:\wwwroot\weibo> git commit -m "Procfile for Heroku"
[main a30f3dd] Procfile for Heroku
 1 file changed, 0 insertions(+), 0 deletions(-)

21、设置 Laravel 加密密钥,使用 Laravel 自带的 artisan 命令来生成 App Key。如图19

图19

PS E:\wwwroot\weibo> php artisan key:generate --show
base64:qtlcYLZF38gHDz/XhCE/cc0Q+BwByRygnVpfWwtRipA=
PS E:\wwwroot\weibo>

22、基于生成的 App Key ,运行该命令行来完成配置。如图20

图20

PS E:\wwwroot\weibo> heroku config:set APP_KEY=base64:qtlcYLZF38gHDz/XhCE/cc0Q+BwByRygnVpfWwtRipA=
 »   Warning: heroku update available from 7.53.0 to 7.59.2.
Setting APP_KEY and restarting ⬢ secret-stream-72395... done, v4
APP_KEY: base64:qtlcYLZF38gHDz/XhCE/cc0Q+BwByRygnVpfWwtRipA=
PS E:\wwwroot\weibo>

23、推送时,仍然报错:Push failed: cannot parse Procfile.

PS E:\wwwroot\weibo> git push heroku main:main
Enumerating objects: 19, done.
Counting objects: 100% (19/19), done.
Delta compression using up to 4 threads
Compressing objects: 100% (17/17), done.
Writing objects: 100% (17/17), 1.59 KiB | 542.00 KiB/s, done.
Total 17 (delta 8), reused 0 (delta 0), pack-reused 0
remote: Compressing source files... done.
remote: Building source:
remote:
remote: -----> Building on the Heroku-20 stack
remote: -----> Using buildpack: heroku/php
remote: -----> PHP app detected
remote: -----> Bootstrapping...
remote: -----> Installing platform packages...
remote:        - php (8.1.1)
remote:        - ext-mbstring (bundled with php)
remote:        - composer (2.1.14)
remote:        - apache (2.4.51)
remote:        - nginx (1.20.2)
remote: -----> Installing dependencies...
remote:        Composer version 2.1.14 2021-11-30 10:51:43
remote:        Installing dependencies from lock file
remote:        Verifying lock file contents can be installed on current platform.
remote:        Package operations: 70 installs, 0 updates, 0 removals
remote:          - Installing doctrine/inflector (2.0.4): Extracting archive
remote:          - Installing doctrine/lexer (1.2.1): Extracting archive
remote:          - Installing symfony/polyfill-ctype (v1.23.0): Extracting archive
remote:          - Installing webmozart/assert (1.10.0): Extracting archive
remote:          - Installing dragonmantank/cron-expression (v3.1.0): Extracting archive
remote:          - Installing symfony/polyfill-php80 (v1.23.1): Extracting archive
remote:          - Installing symfony/polyfill-php73 (v1.23.0): Extracting archive
remote:          - Installing symfony/polyfill-mbstring (v1.23.1): Extracting archive
remote:          - Installing symfony/deprecation-contracts (v3.0.0): Extracting archive
remote:          - Installing symfony/http-foundation (v5.4.1): Extracting archive
remote:          - Installing psr/event-dispatcher (1.0.0): Extracting archive
remote:          - Installing symfony/event-dispatcher-contracts (v3.0.0): Extracting archive
remote:          - Installing symfony/event-dispatcher (v6.0.1): Extracting archive
remote:          - Installing symfony/var-dumper (v5.4.1): Extracting archive
remote:          - Installing psr/log (2.0.0): Extracting archive
remote:          - Installing symfony/error-handler (v5.4.1): Extracting archive
remote:          - Installing symfony/http-kernel (v5.4.1): Extracting archive
remote:          - Installing voku/portable-ascii (1.5.6): Extracting archive
remote:          - Installing phpoption/phpoption (1.8.1): Extracting archive
remote:          - Installing graham-campbell/result-type (v1.0.4): Extracting archive
remote:          - Installing vlucas/phpdotenv (v5.4.1): Extracting archive
remote:          - Installing symfony/css-selector (v6.0.1): Extracting archive
remote:          - Installing tijsverkoyen/css-to-inline-styles (2.2.4): Extracting archive
remote:          - Installing symfony/routing (v5.4.0): Extracting archive
remote:          - Installing symfony/process (v5.4.0): Extracting archive
remote:          - Installing symfony/polyfill-php72 (v1.23.0): Extracting archive
remote:          - Installing symfony/polyfill-intl-normalizer (v1.23.0): Extracting archive
remote:          - Installing symfony/polyfill-intl-idn (v1.23.0): Extracting archive
remote:          - Installing symfony/mime (v5.4.0): Extracting archive
remote:          - Installing symfony/finder (v5.4.0): Extracting archive
remote:          - Installing symfony/polyfill-intl-grapheme (v1.23.1): Extracting archive
remote:          - Installing symfony/string (v6.0.1): Extracting archive
remote:          - Installing psr/container (1.1.2): Extracting archive
remote:          - Installing symfony/service-contracts (v2.4.1): Extracting archive
remote:          - Installing symfony/console (v5.4.1): Extracting archive
remote:          - Installing symfony/polyfill-iconv (v1.23.0): Extracting archive
remote:          - Installing egulias/email-validator (2.1.25): Extracting archive
remote:          - Installing swiftmailer/swiftmailer (v6.3.0): Extracting archive
remote:          - Installing symfony/polyfill-php81 (v1.23.0): Extracting archive
remote:          - Installing ramsey/collection (1.2.2): Extracting archive
remote:          - Installing brick/math (0.9.3): Extracting archive
remote:          - Installing ramsey/uuid (4.2.3): Extracting archive
remote:          - Installing psr/simple-cache (1.0.1): Extracting archive
remote:          - Installing opis/closure (3.6.2): Extracting archive
remote:          - Installing symfony/translation-contracts (v3.0.0): Extracting archive
remote:          - Installing symfony/translation (v6.0.1): Extracting archive
remote:          - Installing nesbot/carbon (2.55.2): Extracting archive
remote:          - Installing monolog/monolog (2.3.5): Extracting archive
remote:          - Installing league/mime-type-detection (1.9.0): Extracting archive
remote:          - Installing league/flysystem (1.1.9): Extracting archive
remote:          - Installing nette/utils (v3.2.6): Extracting archive
remote:          - Installing nette/schema (v1.2.2): Extracting archive
remote:          - Installing dflydev/dot-access-data (v3.0.1): Extracting archive
remote:          - Installing league/config (v1.1.1): Extracting archive
remote:          - Installing league/commonmark (2.1.0): Extracting archive
remote:          - Installing laravel/serializable-closure (v1.0.5): Extracting archive
remote:          - Installing laravel/framework (v8.76.2): Extracting archive
remote:          - Installing asm89/stack-cors (v2.0.3): Extracting archive
remote:          - Installing fruitcake/laravel-cors (v2.0.4): Extracting archive
remote:          - Installing psr/http-message (1.0.1): Extracting archive
remote:          - Installing psr/http-client (1.0.1): Extracting archive
remote:          - Installing ralouphie/getallheaders (3.0.3): Extracting archive
remote:          - Installing psr/http-factory (1.0.1): Extracting archive
remote:          - Installing guzzlehttp/psr7 (2.1.0): Extracting archive
remote:          - Installing guzzlehttp/promises (1.5.1): Extracting archive
remote:          - Installing guzzlehttp/guzzle (7.4.1): Extracting archive
remote:          - Installing laravel/sanctum (v2.13.0): Extracting archive
remote:          - Installing nikic/php-parser (v4.13.2): Extracting archive
remote:          - Installing psy/psysh (v0.10.12): Extracting archive
remote:          - Installing laravel/tinker (v2.6.3): Extracting archive
remote:        Package swiftmailer/swiftmailer is abandoned, you should avoid using it. Use symfony/mailer instead.
remote:        Generating optimized autoload files
remote:        > Illuminate\Foundation\ComposerScripts::postAutoloadDump
remote:        > @php artisan package:discover --ansi
remote:        Discovered Package: fruitcake/laravel-cors
remote:        Discovered Package: laravel/sanctum
remote:        Discovered Package: laravel/tinker
remote:        Discovered Package: nesbot/carbon
remote:        Package manifest generated successfully.
remote:        49 packages you are using are looking for funding.
remote:        Use the `composer fund` command to find out more!
remote: -----> Preparing runtime environment...
remote: -----> Checking for additional extensions to install...
remote: -----> Discovering process types
remote:
remote:  !     Push failed: cannot parse Procfile.
remote:  !     Please try pushing again.
remote:  !     If the problem persists, see https://help.heroku.com/ and provide Request ID 691561db-a116-53f5-a4e5-0100a3777ce9.
remote:
remote:
remote:  !
remote:  ! ## Warning - The same version of this code has already been built: a30f3dde79d674408b2fb440cda5f9dbeb2204fe
remote:  !
remote:  ! We have detected that you have triggered a build from source code with version a30f3dde79d674408b2fb440cda5f9dbeb2204fe
remote:  ! at least twice. One common cause of this behavior is attempting to deploy code from a different branch.
remote:  !
remote:  ! If you are developing on a branch and deploying via git you must run:
remote:  !
remote:  !     git push heroku <branchname>:main
remote:  !
remote:  ! This article goes into details on the behavior:
remote:  !   https://devcenter.heroku.com/articles/duplicate-build-version
remote:
remote: Verifying deploy...
remote:
remote: !       Push rejected to secret-stream-72395.
remote:
To https://git.heroku.com/secret-stream-72395.git
 ! [remote rejected] main -> main (pre-receive hook declined)
error: failed to push some refs to 'https://git.heroku.com/secret-stream-72395.git'
PS E:\wwwroot\weibo>

24、将文件编码另存为 UTF-8 。如图21

图21

25、推送成功,且打开网址:https://secret-stream-72395.herokuapp.com/ ,响应 200。如图22

图22

PS E:\wwwroot\weibo> git add .
PS E:\wwwroot\weibo> git commit -m "Procfile for Heroku"
[main 362c878] Procfile for Heroku
 1 file changed, 0 insertions(+), 0 deletions(-)
PS E:\wwwroot\weibo> git push heroku main
Enumerating objects: 22, done.
Counting objects: 100% (22/22), done.
Delta compression using up to 4 threads
Compressing objects: 100% (19/19), done.
Writing objects: 100% (20/20), 1.84 KiB | 470.00 KiB/s, done.
Total 20 (delta 9), reused 0 (delta 0), pack-reused 0
remote: Compressing source files... done.
remote: Building source:
remote:
remote: -----> Building on the Heroku-20 stack
remote: -----> Using buildpack: heroku/php
remote: -----> PHP app detected
remote: -----> Bootstrapping...
remote: -----> Installing platform packages...
remote:        - php (8.1.1)
remote:        - ext-mbstring (bundled with php)
remote:        - composer (2.1.14)
remote:        - apache (2.4.51)
remote:        - nginx (1.20.2)
remote: -----> Installing dependencies...
remote:        Composer version 2.1.14 2021-11-30 10:51:43
remote:        Installing dependencies from lock file
remote:        Verifying lock file contents can be installed on current platform.
remote:        Package operations: 70 installs, 0 updates, 0 removals
remote:          - Installing doctrine/inflector (2.0.4): Extracting archive
remote:          - Installing doctrine/lexer (1.2.1): Extracting archive
remote:          - Installing symfony/polyfill-ctype (v1.23.0): Extracting archive
remote:          - Installing webmozart/assert (1.10.0): Extracting archive
remote:          - Installing dragonmantank/cron-expression (v3.1.0): Extracting archive
remote:          - Installing symfony/polyfill-php80 (v1.23.1): Extracting archive
remote:          - Installing symfony/polyfill-php73 (v1.23.0): Extracting archive
remote:          - Installing symfony/polyfill-mbstring (v1.23.1): Extracting archive
remote:          - Installing symfony/deprecation-contracts (v3.0.0): Extracting archive
remote:          - Installing symfony/http-foundation (v5.4.1): Extracting archive
remote:          - Installing psr/event-dispatcher (1.0.0): Extracting archive
remote:          - Installing symfony/event-dispatcher-contracts (v3.0.0): Extracting archive
remote:          - Installing symfony/event-dispatcher (v6.0.1): Extracting archive
remote:          - Installing symfony/var-dumper (v5.4.1): Extracting archive
remote:          - Installing psr/log (2.0.0): Extracting archive
remote:          - Installing symfony/error-handler (v5.4.1): Extracting archive
remote:          - Installing symfony/http-kernel (v5.4.1): Extracting archive
remote:          - Installing voku/portable-ascii (1.5.6): Extracting archive
remote:          - Installing phpoption/phpoption (1.8.1): Extracting archive
remote:          - Installing graham-campbell/result-type (v1.0.4): Extracting archive
remote:          - Installing vlucas/phpdotenv (v5.4.1): Extracting archive
remote:          - Installing symfony/css-selector (v6.0.1): Extracting archive
remote:          - Installing tijsverkoyen/css-to-inline-styles (2.2.4): Extracting archive
remote:          - Installing symfony/routing (v5.4.0): Extracting archive
remote:          - Installing symfony/process (v5.4.0): Extracting archive
remote:          - Installing symfony/polyfill-php72 (v1.23.0): Extracting archive
remote:          - Installing symfony/polyfill-intl-normalizer (v1.23.0): Extracting archive
remote:          - Installing symfony/polyfill-intl-idn (v1.23.0): Extracting archive
remote:          - Installing symfony/mime (v5.4.0): Extracting archive
remote:          - Installing symfony/finder (v5.4.0): Extracting archive
remote:          - Installing symfony/polyfill-intl-grapheme (v1.23.1): Extracting archive
remote:          - Installing symfony/string (v6.0.1): Extracting archive
remote:          - Installing psr/container (1.1.2): Extracting archive
remote:          - Installing symfony/service-contracts (v2.4.1): Extracting archive
remote:          - Installing symfony/console (v5.4.1): Extracting archive
remote:          - Installing symfony/polyfill-iconv (v1.23.0): Extracting archive
remote:          - Installing egulias/email-validator (2.1.25): Extracting archive
remote:          - Installing swiftmailer/swiftmailer (v6.3.0): Extracting archive
remote:          - Installing symfony/polyfill-php81 (v1.23.0): Extracting archive
remote:          - Installing ramsey/collection (1.2.2): Extracting archive
remote:          - Installing brick/math (0.9.3): Extracting archive
remote:          - Installing ramsey/uuid (4.2.3): Extracting archive
remote:          - Installing psr/simple-cache (1.0.1): Extracting archive
remote:          - Installing opis/closure (3.6.2): Extracting archive
remote:          - Installing symfony/translation-contracts (v3.0.0): Extracting archive
remote:          - Installing symfony/translation (v6.0.1): Extracting archive
remote:          - Installing nesbot/carbon (2.55.2): Extracting archive
remote:          - Installing monolog/monolog (2.3.5): Extracting archive
remote:          - Installing league/mime-type-detection (1.9.0): Extracting archive
remote:          - Installing league/flysystem (1.1.9): Extracting archive
remote:          - Installing nette/utils (v3.2.6): Extracting archive
remote:          - Installing nette/schema (v1.2.2): Extracting archive
remote:          - Installing dflydev/dot-access-data (v3.0.1): Extracting archive
remote:          - Installing league/config (v1.1.1): Extracting archive
remote:          - Installing league/commonmark (2.1.0): Extracting archive
remote:          - Installing laravel/serializable-closure (v1.0.5): Extracting archive
remote:          - Installing laravel/framework (v8.76.2): Extracting archive
remote:          - Installing asm89/stack-cors (v2.0.3): Extracting archive
remote:          - Installing fruitcake/laravel-cors (v2.0.4): Extracting archive
remote:          - Installing psr/http-message (1.0.1): Extracting archive
remote:          - Installing psr/http-client (1.0.1): Extracting archive
remote:          - Installing ralouphie/getallheaders (3.0.3): Extracting archive
remote:          - Installing psr/http-factory (1.0.1): Extracting archive
remote:          - Installing guzzlehttp/psr7 (2.1.0): Extracting archive
remote:          - Installing guzzlehttp/promises (1.5.1): Extracting archive
remote:          - Installing guzzlehttp/guzzle (7.4.1): Extracting archive
remote:          - Installing nikic/php-parser (v4.13.2): Extracting archive
remote:          - Installing psy/psysh (v0.10.12): Extracting archive
remote:          - Installing laravel/tinker (v2.6.3): Extracting archive
remote:        Package swiftmailer/swiftmailer is abandoned, you should avoid using it. Use symfony/mailer instead.
remote:        Generating optimized autoload files
remote:        > Illuminate\Foundation\ComposerScripts::postAutoloadDump
remote:        > @php artisan package:discover --ansi
remote:        Discovered Package: fruitcake/laravel-cors
remote:        Discovered Package: laravel/sanctum
remote:        Discovered Package: laravel/tinker
remote:        Discovered Package: nesbot/carbon
remote:        Package manifest generated successfully.
remote:        49 packages you are using are looking for funding.
remote:        Use the `composer fund` command to find out more!
remote: -----> Preparing runtime environment...
remote: -----> Checking for additional extensions to install...
remote: -----> Discovering process types
remote:        Procfile declares types -> web
remote:
remote: -----> Compressing...
remote:        Done: 19.8M
remote: -----> Launching...
remote:        Released v6
remote:        https://secret-stream-72395.herokuapp.com/ deployed to Heroku
remote:
remote: Verifying deploy... done.
To https://git.heroku.com/secret-stream-72395.git
   e72b466..362c878  main -> main
PS E:\wwwroot\weibo> heroku open
 »   Warning: heroku update available from 7.53.0 to 7.59.2.
PS E:\wwwroot\weibo>

26、但是,在提交表单,写入数据至 MySQL 时,响应 500 服务器错误,原因在于数据库还不存在。如图23

图23

27、在 Heroku 上使用 PostgreSQL 来作为我们应用的数据库。安装 PostgreSQL 扩展。Heroku 将为我们生成一个唯一的数据库 URL – DATABASE_URL,我们可以通过命令:heroku config 查看 Heroku 的所有配置信息。如图24

图24

PS E:\wwwroot\weibo> heroku addons:add heroku-postgresql:hobby-dev
 »   Warning: heroku update available from 7.53.0 to 7.59.2.
Creating heroku-postgresql:hobby-dev on ⬢ secret-stream-72395... free
Database has been created and is available
 ! This database is empty. If upgrading, you can transfer
 ! data from another database with pg:copy
Created postgresql-parallel-13694 as DATABASE_URL
Use heroku addons:docs heroku-postgresql to view documentation
PS E:\wwwroot\weibo> heroku config
 »   Warning: heroku update available from 7.53.0 to 7.59.2.
=== secret-stream-72395 Config Vars
APP_KEY:      base64:TXoum9anbYcE/VGilCjxrSQQ5E4cR5UVb+55SjIsbg0=
DATABASE_URL: postgres://eayusxxdstiniz:31d9e092c4c8d1740380641299d36711b04e72b98e2f92b9be4253153087bbea@ec2-52-200-28-255.compute-1.amazonaws.com:5432/d9nb3l2ot2cutp
PS E:\wwwroot\weibo>

28、在本地开发中,我们使用了 MySQL 来作为数据库储存,但在 Heroku 环境上我们要改为使用 PostgreSQL 来作为数据库储存。因此在进行数据库设置时,我们需要对当前环境进行判断。如果环境为本地环境,则使用 MySQL 数据库,若为 Heroku 环境,则使用 PostgreSQL 数据库。我们可以通过为 Heroku 新增一个 IS_IN_HEROKU 配置项来判断应用是否运行在 Heroku 上。一般来说,应用的数据库都在 config/database.php 中进行配置,因此我们需要针对该配置文件,来为不同环境的数据库连接方式定义一个帮助方法,以便根据应用不同的运行环境来指定数据库配置信息,我们需要新建一个 helpers.php 文件并写入以下内容:

<?php

function get_db_config()
{
    if (getenv('IS_IN_HEROKU')) {
        $url = parse_url(getenv("DATABASE_URL"));

        return $db_config = [
            'connection' => 'pgsql',
            'host' => $url["host"],
            'database'  => substr($url["path"], 1),
            'username'  => $url["user"],
            'password'  => $url["pass"],
        ];
    } else {
        return $db_config = [
            'connection' => env('DB_CONNECTION', 'mysql'),
            'host' => env('DB_HOST', 'localhost'),
            'database'  => env('DB_DATABASE', 'forge'),
            'username'  => env('DB_USERNAME', 'forge'),
            'password'  => env('DB_PASSWORD', ''),
        ];
    }
}

29、新增 helpers.php 文件之后,还需要在项目根目录下 composer.json 文件中的 autoload 选项里 files 字段加入该文件。如图25

图25

    "autoload": {
        "psr-4": {
            "App\\": "app/",
            "Database\\Factories\\": "database/factories/",
            "Database\\Seeders\\": "database/seeders/"
        },
        "files": [
            "app/helpers.php"
        ]
    },

30、修改保存后运行以下命令进行重新加载文件即可,如果有可能影响到本地环境的程序运行,建议在 Sail 环境中执行相应命令。如图26

图26

wangqiang@DESKTOP-QLPK8QM:/mnt/e/wwwroot/weibo$ sail composer dump-autoload
Generating optimized autoload files
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
> @php artisan package:discover --ansi
Discovered Package: facade/ignition
Discovered Package: fruitcake/laravel-cors
Discovered Package: laravel/sail
Discovered Package: laravel/sanctum
Discovered Package: laravel/tinker
Discovered Package: laravel/ui
Discovered Package: nesbot/carbon
Discovered Package: nunomaduro/collision
Discovered Package: overtrue/laravel-lang
Package manifest generated successfully.
Generated optimized autoload files containing 5027 classes
wangqiang@DESKTOP-QLPK8QM:/mnt/e/wwwroot/weibo$

31、现在,让我们使用刚刚定义好的 get_db_config 方法对数据库进行配置。调整数据库配置文件,总计就 2 处改动。如图28

图28

<?php

use Illuminate\Support\Str;

$db_config = get_db_config();

return [

    /*
    |--------------------------------------------------------------------------
    | Default Database Connection Name
    |--------------------------------------------------------------------------
    |
    | Here you may specify which of the database connections below you wish
    | to use as your default connection for all database work. Of course
    | you may use many connections at once using the Database library.
    |
    */
    'default' => $db_config['connection'],

32、改动的代码进行提交,并推送到 GitHub 和 Heroku 上。

wangqiang@DESKTOP-QLPK8QM:/mnt/e/wwwroot/weibo$ git push
Enumerating objects: 12, done.
Counting objects: 100% (12/12), done.
Delta compression using up to 4 threads
Compressing objects: 100% (7/7), done.
Writing objects: 100% (7/7), 936 bytes | 58.00 KiB/s, done.
Total 7 (delta 5), reused 0 (delta 0)
remote: Resolving deltas: 100% (5/5), completed with 5 local objects.
To https://github.com/shuijingwan/weibo.git
   876eb29..173fc8d  sign-up -> sign-up
wangqiang@DESKTOP-QLPK8QM:/mnt/e/wwwroot/weibo$ git checkout main
Switched to branch 'main'
Your branch is up to date with 'origin/main'.
wangqiang@DESKTOP-QLPK8QM:/mnt/e/wwwroot/weibo$ git merge sign-up
Merge made by the 'recursive' strategy.
 app/helpers.php     | 24 ++++++++++++++++++++++++
 composer.json       |  5 ++++-
 config/database.php |  4 +++-
 3 files changed, 31 insertions(+), 2 deletions(-)
 create mode 100644 app/helpers.php
wangqiang@DESKTOP-QLPK8QM:/mnt/e/wwwroot/weibo$ git push
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 4 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 300 bytes | 33.00 KiB/s, done.
Total 2 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
To https://github.com/shuijingwan/weibo.git
   cd4e270..1e23962  main -> main
wangqiang@DESKTOP-QLPK8QM:/mnt/e/wwwroot/weibo$
PS E:\wwwroot\weibo> git status
On branch main
Your branch is up to date with 'origin/main'.

nothing to commit, working tree clean
PS E:\wwwroot\weibo> git push heroku main
Enumerating objects: 19, done.
Counting objects: 100% (15/15), done.
Delta compression using up to 4 threads
Compressing objects: 100% (9/9), done.
Writing objects: 100% (9/9), 1.13 KiB | 576.00 KiB/s, done.
Total 9 (delta 6), reused 0 (delta 0), pack-reused 0
remote: Compressing source files... done.
remote: Building source:
remote:
remote: -----> Building on the Heroku-20 stack
remote: -----> Using buildpack: heroku/php
remote: -----> PHP app detected
remote: -----> Bootstrapping...
remote: -----> Installing platform packages...
remote:        - php (8.1.1)
remote:        - ext-mbstring (bundled with php)
remote:        - composer (2.1.14)
remote:        - apache (2.4.51)
remote:        - nginx (1.20.2)
remote: -----> Installing dependencies...
remote:        Composer version 2.1.14 2021-11-30 10:51:43
remote:        Installing dependencies from lock file
remote:        Verifying lock file contents can be installed on current platform.
remote:        Package operations: 72 installs, 0 updates, 0 removals
remote:          - Installing doctrine/inflector (2.0.4): Extracting archive
remote:          - Installing doctrine/lexer (1.2.1): Extracting archive
remote:          - Installing symfony/polyfill-ctype (v1.23.0): Extracting archive
remote:          - Installing webmozart/assert (1.10.0): Extracting archive
remote:          - Installing dragonmantank/cron-expression (v3.1.0): Extracting archive
remote:          - Installing symfony/polyfill-php80 (v1.23.1): Extracting archive
remote:          - Installing symfony/polyfill-php73 (v1.23.0): Extracting archive
remote:          - Installing symfony/polyfill-mbstring (v1.23.1): Extracting archive
remote:          - Installing symfony/deprecation-contracts (v3.0.0): Extracting archive
remote:          - Installing symfony/http-foundation (v5.4.1): Extracting archive
remote:          - Installing psr/event-dispatcher (1.0.0): Extracting archive
remote:          - Installing symfony/event-dispatcher-contracts (v3.0.0): Extracting archive
remote:          - Installing symfony/event-dispatcher (v6.0.1): Extracting archive
remote:          - Installing symfony/var-dumper (v5.4.1): Extracting archive
remote:          - Installing psr/log (2.0.0): Extracting archive
remote:          - Installing symfony/error-handler (v5.4.1): Extracting archive
remote:          - Installing symfony/http-kernel (v5.4.1): Extracting archive
remote:          - Installing voku/portable-ascii (1.5.6): Extracting archive
remote:          - Installing phpoption/phpoption (1.8.1): Extracting archive
remote:          - Installing graham-campbell/result-type (v1.0.4): Extracting archive
remote:          - Installing vlucas/phpdotenv (v5.4.1): Extracting archive
remote:          - Installing symfony/css-selector (v6.0.1): Extracting archive
remote:          - Installing tijsverkoyen/css-to-inline-styles (2.2.4): Extracting archive
remote:          - Installing symfony/routing (v5.4.0): Extracting archive
remote:          - Installing symfony/process (v5.4.0): Extracting archive
remote:          - Installing symfony/polyfill-php72 (v1.23.0): Extracting archive
remote:          - Installing symfony/polyfill-intl-normalizer (v1.23.0): Extracting archive
remote:          - Installing symfony/polyfill-intl-idn (v1.23.0): Extracting archive
remote:          - Installing symfony/mime (v5.4.0): Extracting archive
remote:          - Installing symfony/finder (v5.4.0): Extracting archive
remote:          - Installing symfony/polyfill-intl-grapheme (v1.23.1): Extracting archive
remote:          - Installing symfony/string (v6.0.1): Extracting archive
remote:          - Installing psr/container (1.1.2): Extracting archive
remote:          - Installing symfony/service-contracts (v2.4.1): Extracting archive
remote:          - Installing symfony/console (v5.4.1): Extracting archive
remote:          - Installing symfony/polyfill-iconv (v1.23.0): Extracting archive
remote:          - Installing egulias/email-validator (2.1.25): Extracting archive
remote:          - Installing swiftmailer/swiftmailer (v6.3.0): Extracting archive
remote:          - Installing symfony/polyfill-php81 (v1.23.0): Extracting archive
remote:          - Installing ramsey/collection (1.2.2): Extracting archive
remote:          - Installing brick/math (0.9.3): Extracting archive
remote:          - Installing ramsey/uuid (4.2.3): Extracting archive
remote:          - Installing psr/simple-cache (1.0.1): Extracting archive
remote:          - Installing opis/closure (3.6.2): Extracting archive
remote:          - Installing symfony/translation-contracts (v3.0.0): Extracting archive
remote:          - Installing symfony/translation (v6.0.1): Extracting archive
remote:          - Installing nesbot/carbon (2.55.2): Extracting archive
remote:          - Installing monolog/monolog (2.3.5): Extracting archive
remote:          - Installing league/mime-type-detection (1.9.0): Extracting archive
remote:          - Installing league/flysystem (1.1.9): Extracting archive
remote:          - Installing nette/utils (v3.2.6): Extracting archive
remote:          - Installing nette/schema (v1.2.2): Extracting archive
remote:          - Installing dflydev/dot-access-data (v3.0.1): Extracting archive
remote:          - Installing league/config (v1.1.1): Extracting archive
remote:          - Installing league/commonmark (2.1.0): Extracting archive
remote:          - Installing laravel/serializable-closure (v1.0.5): Extracting archive
remote:          - Installing laravel/framework (v8.76.2): Extracting archive
remote:          - Installing asm89/stack-cors (v2.0.3): Extracting archive
remote:          - Installing fruitcake/laravel-cors (v2.0.4): Extracting archive
remote:          - Installing psr/http-message (1.0.1): Extracting archive
remote:          - Installing psr/http-client (1.0.1): Extracting archive
remote:          - Installing ralouphie/getallheaders (3.0.3): Extracting archive
remote:          - Installing psr/http-factory (1.0.1): Extracting archive
remote:          - Installing guzzlehttp/psr7 (2.1.0): Extracting archive
remote:          - Installing guzzlehttp/promises (1.5.1): Extracting archive
remote:          - Installing guzzlehttp/guzzle (7.4.1): Extracting archive
remote:          - Installing laravel/sanctum (v2.13.0): Extracting archive
remote:          - Installing nikic/php-parser (v4.13.2): Extracting archive
remote:          - Installing psy/psysh (v0.10.12): Extracting archive
remote:          - Installing laravel/tinker (v2.6.3): Extracting archive
remote:          - Installing laravel-lang/lang (5.0.0): Extracting archive
remote:          - Installing overtrue/laravel-lang (4.2.2): Extracting archive
remote:        Package swiftmailer/swiftmailer is abandoned, you should avoid using it. Use symfony/mailer instead.
remote:        Generating optimized autoload files
remote:        > Illuminate\Foundation\ComposerScripts::postAutoloadDump
remote:        > @php artisan package:discover --ansi
remote:        Discovered Package: fruitcake/laravel-cors
remote:        Discovered Package: laravel/sanctum
remote:        Discovered Package: laravel/tinker
remote:        Discovered Package: nesbot/carbon
remote:        Discovered Package: overtrue/laravel-lang
remote:        Package manifest generated successfully.
remote:        50 packages you are using are looking for funding.
remote:        Use the `composer fund` command to find out more!
remote: -----> Preparing runtime environment...
remote: -----> Checking for additional extensions to install...
remote: -----> Discovering process types
remote:        Procfile declares types -> web
remote:
remote: -----> Compressing...
remote:        Done: 19.9M
remote: -----> Launching...
remote:        Released v10
remote:        https://secret-stream-72395.herokuapp.com/ deployed to Heroku
remote:
remote: Verifying deploy... done.
To https://git.heroku.com/secret-stream-72395.git
   cd4e270..1e23962  main -> main
PS E:\wwwroot\weibo>

33、我们可以使用 heroku run 在 Heroku 运行 Laravel 的指定命令。现在我们需要在 Heroku 上执行迁移,生成用户表,可通过下面命令来完成,报错:SQLSTATE[22023]: Invalid parameter value: 7 ERROR: invalid value for parameter “client_encoding”: “utf8mb4” 。如图28

图28

PS E:\wwwroot\weibo> heroku run php artisan migrate
 »   Warning: heroku update available from 7.53.0 to 7.59.2.
Running php artisan migrate on ⬢ secret-stream-72395... up, run.1841 (Free)
**************************************
*     Application In Production!     *
**************************************

 Do you really wish to run this command? (yes/no) [no]:
 > yes


In Connection.php line 703:

  SQLSTATE[22023]: Invalid parameter value: 7 ERROR:  invalid value for parameter "client_encoding": "utf8mb4" (SQL:
  select * from information_schema.tables where table_schema = public and table_name = migrations and table_type = 'B
  ASE TABLE')


In PostgresConnector.php line 68:

  SQLSTATE[22023]: Invalid parameter value: 7 ERROR:  invalid value for parameter "client_encoding": "utf8mb4"


PS E:\wwwroot\weibo>

34、再次调整数据库配置文件,之前 pgsql 相关的配置未修改到。

        'pgsql' => [
            'driver' => 'pgsql',
            'host' => $db_config['host'],
            'port' => env('DB_PORT', '5432'),
            'database' => $db_config['database'],
            'username' => $db_config['username'],
            'password' => $db_config['password'],
            'charset' => 'utf8',
            'prefix' => '',
            'prefix_indexes' => true,
            'schema' => 'public',
            'sslmode' => 'prefer',
        ],

35、执行命令:heroku config:add DB_CONNECTION=pgsql 。再次执行迁移时报错已经不一样了:

 »   Warning: heroku update available from 7.53.0 to 7.59.2.
DB_CONNECTION: pgsql
PS E:\wwwroot\weibo> heroku run php artisan migrate
 »   Warning: heroku update available from 7.53.0 to 7.59.2.
Running php artisan migrate on ⬢ secret-stream-72395... up, run.7170 (Free)
**************************************
*     Application In Production!     *
**************************************

 Do you really wish to run this command? (yes/no) [no]:
 > yes


In Connection.php line 703:

  SQLSTATE[08006] [7] connection to server at "localhost" (127.0.0.1), port 5432 failed: Connection refused
        Is the server running on that host and accepting TCP/IP connections? (SQL: select * from information_schema.tables
   where table_schema = public and table_name = migrations and table_type = 'BASE TABLE')


In Connector.php line 70:

  SQLSTATE[08006] [7] connection to server at "localhost" (127.0.0.1), port 5432 failed: Connection refused
        Is the server running on that host and accepting TCP/IP connections?


PS E:\wwwroot\weibo> git push heroku main
Everything up-to-date
PS E:\wwwroot\weibo> heroku run php artisan migrate
 »   Warning: heroku update available from 7.53.0 to 7.59.2.
Running php artisan migrate on ⬢ secret-stream-72395... up, run.6564 (Free)
**************************************
*     Application In Production!     *
**************************************

 Do you really wish to run this command? (yes/no) [no]:
 > yes


In Connection.php line 703:

  SQLSTATE[08006] [7] connection to server at "localhost" (127.0.0.1), port 5432 failed: Connection refused
        Is the server running on that host and accepting TCP/IP connections? (SQL: select * from information_schema.tables
   where table_schema = public and table_name = migrations and table_type = 'BASE TABLE')


In Connector.php line 70:

  SQLSTATE[08006] [7] connection to server at "localhost" (127.0.0.1), port 5432 failed: Connection refused
        Is the server running on that host and accepting TCP/IP connections?


PS E:\wwwroot\weibo>

36、最后找到根源在于漏掉了在 Heroku 新增一个 IS_IN_HEROKU 配置项来判断应用是否运行在 Heroku 上。迁移成功。如图29

图29

PS E:\wwwroot\weibo> heroku config:set IS_IN_HEROKU=true
 »   Warning: heroku update available from 7.53.0 to 7.59.2.
Setting IS_IN_HEROKU and restarting ⬢ secret-stream-72395... done, v16
IS_IN_HEROKU: true
PS E:\wwwroot\weibo> heroku run php artisan migrate
 »   Warning: heroku update available from 7.53.0 to 7.59.2.
Running php artisan migrate on ⬢ secret-stream-72395... up, run.3491 (Free)
**************************************
*     Application In Production!     *
**************************************

 Do you really wish to run this command? (yes/no) [no]:
 > yes

Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table (850.26ms)
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table (466.16ms)
Migrating: 2019_08_19_000000_create_failed_jobs_table
Migrated:  2019_08_19_000000_create_failed_jobs_table (902.11ms)
Migrating: 2019_12_14_000001_create_personal_access_tokens_table
Migrated:  2019_12_14_000001_create_personal_access_tokens_table (1,079.00ms)
PS E:\wwwroot\weibo>

37、再次提交表单数据,提交成功。如图30

图30

38、使用 heroku rename 来对应用名称进行更改,但要保证更改的名称未被其它人占用。如图31

图31

PS E:\wwwroot\weibo> heroku rename app-wangqiang-weibo
 »   Warning: heroku update available from 7.53.0 to 7.59.2.
Renaming secret-stream-72395 to app-wangqiang-weibo... done
https://app-wangqiang-weibo.herokuapp.com/ | https://git.heroku.com/app-wangqiang-weibo.git
 !    Don't forget to update git remotes for all other local checkouts of the app.
Git remote heroku updated
PS E:\wwwroot\weibo>

39、打开:https://app-wangqiang-weibo.herokuapp.com/ ,响应 200。符合预期。如图32

图32

40、打开:https://secret-stream-72395.herokuapp.com/ ,响应 404。There’s nothing here, yet。符合预期。如图33

图33

永夜