api7 Project.

The purpose of this page is to document the procedure to deply a laravel docker project using Laravel as the API backend.

cd /home/developer/Desktop/local-laravel/docker

Rund the script to create a new project, the script will open the project in the browser. NOTE: if you don't see the laravel default page, then you may need to wait a couple of more seconds and then refresh as it takes a little bit to load all the docker containers for the localhost.

./docker_create_new_laravel

NOTE: See docker_create_new_laravel below this page for the bash script code

Open URL in browser: http://localhost

After you have confirmed through the browser the project is built, cd and create a sail alias and  bring down the docker container so we can continue building the database

cd api7; alias sail="./vendor/bin/sail"; sail down

GIT: "initial" commit created automatically by the script

If you you haven't done so, open this project in Code:

code .

Open .env file and check MySQL settings are like the following:

DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=api7
DB_USERNAME=root
DB_PASSWORD=123

GIT: Save grit progress

git add .
git commit -m "Added MySQL settings to .env"
echo "done"

open docker-compose.yml file and add the following code after mailhog to install phpmyadmin in the docker container using port 8081 for the local and remote (ie Heroku) port

code ./docker-compose.yml

    phpmyadmin:
        image: phpmyadmin/phpmyadmin
        restart: always
        depends_on:
            - mysql
        ports:
            - "8081:80"
        environment:
            PMA_HOST: mysql
            MYSQL_ROOT_PASSWORD: '${DB_PASSWORD}'
        networks:
            - sail

Start the Docker Container with the new phpmyadmin settings

sail up -d

Confirm PHPMyAdmin is working by opening your browser with the following command:

http://localhost:8081/

NOTE THE DEFAULTS:

User: root
Password: [blank]

GIT: Save grit progress

git add .
git commit -m "Added PHPMyAdmin to docker-compose.yml"
echo "done"

Create the database migration model in the host, not the docker container, so be sure to have PHP and artisan already installed

php artisan make:model Tareas
php artisan make:seeder TareasTableSeeder
php artisan make:controller TareasController
php artisan make:migration create_tareas_table --table=tareas
echo "done"

Open and edit ./app/Http/Controllers/TareasController.php with Visual Code to make it look like this:

code ./app/Http/Controllers/TareasController.php
<?php

namespace App\Http\Controllers;

use App\Models\Tareas;
use Illuminate\Http\Request;

class TareasController extends Controller
{
    public function index(){
        //$tareas = Tareas::all();
        //$tareas = Tareas::find();
        $tareas = Tareas::
                where('done',1)
                ->get();
        
        return response()->json($tareas,200);
    }
}

GIT: Save grit progress

git add .
git commit -m "Added index to TareasController.php"
echo "done"

Open file ./database/migrations/2021_*_create_tareas_table.php - NOTE: * is whatever date the system created. Make sure it looks like this:

code ./database/migrations/2021_*_create_tareas_table.php

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateTareasTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('tareas', function (Blueprint $table) {
            $table->string('title')->nullable();
            $table->string('description')->nullable();
            $table->integer('done')->nullable();
            $table->integer('category_id')->nullable();
            $table->integer('user_id')->nullable();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('tareas', function (Blueprint $table) {
            //
        });
    }

GIT: Save grit progress

git add .
git commit -m "Added migrations to create_tareas_table.php"
echo "done"

Open ./database/seeders/TareasTableSeeder.php and make sure to the code looks like this:

code ./database/seeders/TareasTableSeeder.php

<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
class TareasTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        for ($i=0; $i < 50; $i++) {
            
            DB::table('tareas')->insert([
                'title' => Str::random(10),
                'description' => 'Exercitation cillum adipisicing qui laborum fugiat. Dolore dolore est minim excepteur dolore consequat irure anim. Anim reprehenderit esse amet velit. In ut ipsum occaecat velit.',
                'done' => random_int(0,1),
            ]);
        }
    }
}

GIT: Save grit progress

git add .
git commit -m "Added seeds to TareasTableSeeder.php"
echo "done"

Open ./app/Models/Tareas.php and make it look like this:

code ./app/Models/Tareas.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Tareas extends Model
{
    use HasFactory;
    public $timestamps = false;
}

GIT: Save grit progress

git add .
git commit -m "Added timestamps to false to Tareas.php"
echo "done"

Be sure to have all the changes in each of these files and start the docker container with Sail.

sail up -d

Confirm your Laravel project is working properly by opening the following URL in your broswer:

xdg-open http://localhost

Now its time to create our model migrations with the sail command. Sail is used as php in the docker container to send commands to the container.
For example, normally you would use the php artisan migrate command in the host, but to execute this command in the docker container, the command will look like this: sail artisan migrate.

sail artisan migrate

After the migration has been completed, check the status with the following command:

sail artisan migrate:status

the output might look something like this:

+------+------------------------------------------------+-------+
| Ran? | Migration                                      | Batch |
+------+------------------------------------------------+-------+
| Yes  | 2014_10_12_000000_create_users_table           | 1     |
| Yes  | 2014_10_12_100000_create_password_resets_table | 1     |
| Yes  | 2019_08_19_000000_create_failed_jobs_table     | 1     |
| Yes  | 2021_01_27_042427_create_tareas_table          | 2     |
+------+------------------------------------------------+-------+

Now lets run the seeder to build our fake data:

sail artisan db:seed --class=TareasTableSeeder

Now that we created some dummy data, you can confirm by viewing in PHPMyAdmin in your browser:

http://localhost:8081/sql.php?server=1&db=api7&table=tareas&pos=0

Now that we know our data in our table, lets view our data in an API with JSON format. First open the file ./routes/api.php to change the code to the following:

code ./routes/api.php

<?php
use App\Http\Controllers\TareasController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;


Route::get('tareas',[TareasController::class, 'index']);


/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/

// Route::middleware('auth:api')->get('/user', function (Request $request) {
// return $request->user();
// });

GIT: Save grit progress

git add .
git commit -m "Added api/tareas route"
echo "done"

Now you should see the data in JSON format by opening your browser to the following URL:

http://localhost/api/tareas

At this point, it would be a good idea of making a backup list of all your GIT commits into a file with the following command:

git log --oneline > ../api7_GIT_Log_20213021_2321.txt

DEPLOY TO HEROKU

Lets deply our laravel Application to Heroku using our Docker container. Be sure you have docker CLI installed if you dont already have it, you can visit the Heroku Installation section at the Heroku website.

Create Procfile and add the following line to the Procfile:

echo "web: vendor/bin/heroku-php-apache2 public/" > Procfile

GIT: Save grit progress

git add .
git commit -m "Added Procfile File"
echo "done"

Create a Herokup Application with the name of our app and date and time. This app name must be a unique name in Heroku.

heroku create api7-20213021-2321

NOTE: Herokup Application Name must start with a letter, end with a letter or digit and can only contain lowercase letters, digits,and dashes.

Lets push our app to our new Heroku App

git push heroku master

NOTE: if this command doesn't work try this one:

git push heroku main

Open the application in your broswer:

api7-20213021-2321.herokuapp.com

You will see a 500 error. Don't worry, follow the instructions on the following page to fix it.

https://www.webune.com/forums/lzpyzz.html

CREATE A MySQL DATABASE RESOURCE

While you are still in the Heroku App Dashboard, add a MySQL resource:

Add MySQL Resource:

a. Go to your browser and open the application we just created and click on the "Resources" tab
b. Click on the "Find more add-ons" button
c. Find "JawsDB MySQL" and click on it
d. In the JawsDB MySQL page, click on the "Install JawsDB MySQL" button
e. In the "App to provision to" field, enter the name of your application [NAME_OF_APPLICATION]
f. Click the "Submit Order Form" button
g. The new datbase has been attached to your app, you can confirm by going to the settings tab and click on the Reveal Config Vars button, you will see "JAWSDB_URL" in the KEY field

After you have created the database resource, you can find the user/password credentials with the following command:

heroku pg:credentials:url

Or by going to the dashboard . Resources > Add-ons and click on the icon "JawsDB MySAL" - it will open a new window to the JaswDB site which will show you all the credentials

or

To get the credentials for the newly created database resource, in the dashboard, go to settings > Reveal Config Vars > JAWSDB_URL
you will see something like this: mysql://myddo8pxnb1n08o:pykdd8m4cro63fi@phtfddd4p6a970uc0.cbetxkdyhwsb.us-east-1.rds.amazonaws.com:3306/t587gxdd71dj04e9s9
To breakdown:
HOST: phtfddd4p6a970uc0.cbetxkdyhwsb.us-east-1.rds.amazonaws.com
USERNAME: myddo8pxnb1n08o
PASSWORD: pykdd8m4cro63fi
PORT: 3306
DATABASE: t587gxdd71dj04e9s9

Now setup these crendential variables to your app. You can go to your dashboard an enter manually or run the bash script Proc_HerokusetDb.sh file included at the bottom of this page:

DB_CONNECTION
DB_HOST
DB_USERNAME
DB_PASSWORD
DB_PORT
DB_DATABASE

GIT: Save grit progress

git add .
git commit -m "Added Proc_HerokusetDb.sh"
echo "done"

Migrate Datbase
Now that we have all the necesseary credentials, lets complete our migrations in the Heroku App with the following command:
heroku run php artisan migrate

This was my output as an example:

Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table (43.91ms)
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table (31.85ms)
Migrating: 2019_08_19_000000_create_failed_jobs_table
Migrated:  2019_08_19_000000_create_failed_jobs_table (39.16ms)
Migrating: 2021_01_31_063701_create_tareas_table
Migrated:  2021_01_31_063701_create_tareas_table (18.85ms)

Migrate the seeder to the herokup container:

$heroku run php artisan db:seed --class=TareasTableSeeder

Try it: api7-20213021-2321.herokuapp.com/api/tareas

The next step is optional, you can create a controller and a view to display the data tables in HTML, follow this tutorial:

https://www.webune.com/forums/zmpywa.html

 

 

OPTIONAL IF YOU WANT TO TEST YOUR DATABASE CONNECTION FOR BOTH YOUR LOCAL SERVER AND REMOTE SERVER:

Open ./config/database.php to configrue Heroku's database connection:

code ./config/database.php

Setup a configuration variable for our database. Copy and paste the following below the line: use Illuminate\Support\Str;

$DATABASE_URL=parse_url('DATABASE_URL');

In database.php find the mysql section and change the connections settings to match the following:

            'host' =>     isset($DATABASE_URL['host']) ? $DATABASE_URL['host'] : null,
'port' => isset($DATABASE_URL['port']) ? $DATABASE_URL['port'] : null,
'database' => isset($DATABASE_URL['path']) ? ltrim( $DATABASE_URL['path'], "/") : null,
'username' => isset($DATABASE_URL['user']) ? $DATABASE_URL['user'] : null,
'password' => isset($DATABASE_URL['pass']) ? $DATABASE_URL['pass'] : null,

 

docker_create_new_laravel.sh

#!/bin/bash

clear

APPNAME_DEFAULT="api"
read -p "Enter The App you want to Create: [$APPNAME_DEFAULT/] " APPNAME
if [[ $APPNAME == "" ]]
then
    APPNAME=$APPNAME_DEFAULT
    set -e
fi

#https://stackoverflow.com/questions/59838/how-can-i-check-if-a-directory-exists-in-a-bash-shell-script
# check if directory exists
if [ -d "$APPNAME" ]; then
  echo "FATAL FERROR: $APPNAME ALREADY EXIST. Try Again."
  set -e
  exit
fi
echo "App does not exist. Creating APP: $APPNAME"

curl -s https://laravel.build/$APPNAME | bash

cd $APPNAME
git init
git commit -am "initial"
./vendor/bin/sail up -d 

# ALWAYS PUT THIS AT THE END OF THE SCRIPT
echo "Opening browser with localhost"
xdg-open http://localhost

This bash file is used to enter the database variables into a heroku app with the terminal:

Proc_HerokusetDb.sh

#!/bin/bash
clear
echo "Lets setup the database connections variables to Heroku"
read -p "Enter DB_CONNECTION [mysql/pgsql] " DB_CONNECTION
if [[ $DB_CONNECTION == "" ]]
then
    echo "ERROR: You must enter a DB_CONNECTION"
    set -e
      exit
fi
read -p "Enter DB_HOST " DB_HOST
if [[ $DB_HOST == "" ]]
then
    echo "ERROR: You must enter a DB_HOST"
    set -e
      exit
fi
read -p "Enter DB_USERNAME " DB_USERNAME
if [[ $DB_USERNAME == "" ]]
then
    echo "ERROR: You must enter a DB_USERNAME"
    set -e
      exit
fi
read -p "Enter DB_PASSWORD " DB_PASSWORD
if [[ $DB_PASSWORD == "" ]]
then
    echo "ERROR: You must enter a DB_PASSWORD"
    set -e
      exit
fi
read -p "Enter DB_PORT " DB_PORT
if [[ $DB_PORT == "" ]]
then
    echo "ERROR: You must enter a DB_PORT"
    set -e
      exit
fi
read -p "Enter DB_DATABASE " DB_DATABASE
if [[ $DB_DATABASE == "" ]]
then
    echo "ERROR: You must enter a DB_DATABASE"
    set -e
      exit
fi
heroku config:add DB_CONNECTION=$DB_CONNECTION
set -e
heroku config:add DB_HOST=$DB_HOST
set -e
heroku config:add DB_USERNAME=$DB_USERNAME
set -e
heroku config:add DB_PASSWORD=$DB_PASSWORD
set -e
heroku config:add DB_PORT=$DB_PORT
set -e
heroku config:add DB_DATABASE=$DB_DATABASE
set -e
echo "[OK] COMPLETED"

Hope that helps.