Install Kong Api Gateway on Docker Windows

Today i want to explain how to install Kong Api Gateway on your Windows Docker Desktop.

This is the official guide but there are some error ( https://hub.docker.com/_/kong )

I have used PostreSQL. In the official guide there is not a “Password” for database and so it do error.

Open a command line and insert this three command.

On your docker desktop client than you must to see the 2 container for database and api gateway.

1. Link Kong to either a Cassandra or PostgreSQL container

docker run -d --name kong-database ^
                -p 5432:5432 ^
                -e "POSTGRES_USER=kong" ^
                -e "POSTGRES_DB=kong" ^
		-e "POSTGRES_PASSWORD=kong" ^
                postgres:9.6

2. Prepare your database

docker run --rm ^
    --link kong-database:kong-database ^
    -e "KONG_DATABASE=postgres" ^
    -e "KONG_PG_HOST=kong-database" ^
    -e "KONG_PG_PASSWORD=kong" ^
    kong kong migrations bootstrap
docker run -d --name kong ^
    --link kong-database:kong-database ^
    -e "KONG_DATABASE=postgres" ^
    -e "KONG_PG_HOST=kong-database" ^
    -e "KONG_PG_PASSWORD=kong" ^
    -e "KONG_PROXY_ACCESS_LOG=/dev/stdout" ^
    -e "KONG_ADMIN_ACCESS_LOG=/dev/stdout" ^
    -e "KONG_PROXY_ERROR_LOG=/dev/stderr" ^
    -e "KONG_ADMIN_ERROR_LOG=/dev/stderr" ^
    -e "KONG_ADMIN_LISTEN=0.0.0.0:8001, 0.0.0.0:8444 ssl" ^
    -p 8000:8000 ^
    -p 8443:8443 ^
    -p 8001:8001 ^
    -p 8444:8444 ^
    kong

Have fun!

Enable Plesk Webp PHP 7.4 GD Support

Today i want to add on my website the support for webp images, and so i have found a plugin for wordpress that is free WebP Converter for Media

But for this plugin we must to active the support webp on the php module GD.
On My VPS i have installed PHP 7.4 on Plesk, the simple way is to change the modulo gd of plesk php version with a custom module in witch the webp support is enabled.

I have find this useful guide that i rewrite with php 7.4 that i have used on my VPS. 

Install the necessary package

# yum install make gcc plesk-php74-devel libjpeg-turbo-devel libpng-devel libXpm-devel freetype-devel libwebp-devel

Download PHP source. Note! Version of PHP source should be the same as your Plesk PHP version! For example, for PHP 7.4.4

# wget http://be2.php.net/get/php-7.4.4.tar.gz/from/this/mirror
# tar -xzf mirror
# cd php-7.4.4/ext/gd

Compile gd.so module

# /opt/plesk/php/7.4/bin/phpize
# ./configure --with-php-config=/opt/plesk/php/7.4/bin/php-config --with-webp --with-freetype --with-jpeg --with-xpm
# make

Replace original Plesk PHP gd.so module with compiled

# mv /opt/plesk/php/7.4/lib64/php/modules/gd.so /opt/plesk/php/7.4/lib64/php/modules/gd.so_orig
# cp modules/gd.so /opt/plesk/php/7.4/lib64/php/modules/
# plesk bin php_handler --reread

Check that all is OK

# /opt/plesk/php/7.4/bin/php -m | grep gd
gd

Do not forget to to make fake removal of original plesk-php74-gd package! Otherwise, your custom gd.so will be overwritten with next update.

# rpm -e --justdb plesk-php74-gd

 

At last remember that you must to go on
Plesk -> Tool & Setting -> PHP Settings
Choose your PHP Verison in this case PHP 7.4.4 and

  • Remove GD module and save
  • Add GD module and save

So Plesk rebuild php for the domains.

Geekle.us – Free Online Tech Conference 2 April 2020

We can use this period of quarantine to stay at home and study something of new.
At the 2 April there will be an online tech conference about DevOps and JS at the 11:00 AM CET on www.geekle.us.

The Conference is free and you can register on the bottom site, through eventbrite

The event is divided into 2 Track, One about DevOps and One about JS

TRACK #1 TRACK #2
11:00 AM Senior DevOps Section React.js Section
Azure DevOps and GitHub Actions Maintainable React
Infrastructure as Code on AWS: Deep Dive How to build your reusable UI
component library like a pro
Build and deploy a serverless
web app on GCP
End to end testing a world of web,
mobile & desktop apps
13:40 AM Junior DevOps Section Node.js Section
Topik
(Coming soon)
Callbacks to Async/Await in Node.js
+ Build you own promise
Automating your first infrastructure with Terraform on AWS Finding memory leaks and CPU bottlenecks
with Node.js debug tools
Observability in DevOps Malicious Modules on npm – a series of unfortunate events
16:10 AM Soft Skills Section
Working from home –
how to not kill relationships
Modern Stoicism: How practice discipline
and stay calm during the crisis.

I think that will be interesting the final section about the Soft Skill and how to not kill relationships while we stay at home.

And so.. let’s go to subscribe on geekle.us event!

CodeAnywhere Laravel Php Container Setup

I use for a long time CodeAnywhere to develop my application via FTP, or to use shell server console via SSH.
Now i want to use the Container and try to create a Laravel PHP application.
But i have encountered some errors that i want to report you.

Now start with the creation of the container, with the “Connection Wizard” is very simple:

If we want to run the Laravel php application, we must to use this command, and set the ip 0.0.0.0 to use app from remote container url.

https://phpbox-CODEOFCODEANYWHERE.codeanyapp.com/

[cabox@PHPBOX app]$ php artisan serve --host=0.0.0.0 --port=8000
Laravel development server started: http://0.0.0.0:8000

Some possible error

SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes

Edit your app/providers/AppServiceProvider.php file and inside the boot method set a default string length:

use Illuminate\Support\Facades\Schema;

public function boot()
{
    Schema::defaultStringLength(191);
}

SQLSTATE[42S01]: Base table or view already exists: 1050 Table ‘users’ already exists

Solution is to run con shell

[cabox@PHPBOX app]$ php artisan migrate:fresh
[cabox@PHPBOX app]$ php artisan migrate

PHP Script Import Mysql Dump Gzip .sql.gz

In many case we have the necessity to import a mysql dump in fast way on our database, to see some old data or to restore.

Now i want to show you a simple but powerful php script to import a mysql dump gzipped.

We use the function zcat with shell_exec

shell_exec("zcat <url file> | mysql -u <user_db> -p<password db> <database>")

This is a simple php script that we can use on our application, to restore in fast way our gzipped mysql dump

We create a select, to show a list of file, and then choose one and click “load”, then with our zcat shell execution function, load it.

<?php
if(isset($_POST['action']) &amp;&amp; $_POST['action'] == 'execute')
{  
  $file_name = $_POST['filename'];
  $out = shell_exec("zcat ".$file_name." | mysql -u user_db -pPasswordDB db_name");
  echo "Mysql Dump Imported Successfull!";
}


function getDirContents($dir, &amp;$results = array()){
    $files = scandir($dir);
    foreach($files as $key => $value){
        $path = realpath($dir.DIRECTORY_SEPARATOR.$value);
        if(!is_dir($path)) {
            $results[] = $path;
        } else if($value != "." &amp;&amp; $value != "..") {
            getDirContents($path, $results);
            $results[] = $path;
        }
    }

    return $results;
}

//directory of our backup file
$listFile = getDirContents('/var/www/vhosts/<our domain>/backups');
echo "<form method=POST>";
echo "<select name='filename'>";
foreach ($listFile as &amp;$value) {
  echo "<option>".$value."</option>";
}
echo "</select>";
echo "<input type='hidden' name='action' value='execute'>";
echo "<input type='submit' name='Load Mysql Dump'>";
echo "</form>";
?>

QuaggaJS Barcode Scanner Setting EAN13 Code128

Today is very important the use of smartphone / table for work. 
And in many case is important to read barcode or qrcode.

For that, now i want to speak about QuaggaJS a javascript library for reading barcode.
I have used it and setting up for a correct mobile resize of video stream, and for reading code128 and ean13.

At first we must to download it from the website: https://serratus.github.io/quaggaJS/

Install

  1. At first we must to download it from the website: https://serratus.github.io/quaggaJS/
  2. Read the guide about installation https://serratus.github.io/quaggaJS/#installing

Example Page

CSS responsive

#interactive.viewport {
    position: relative;
}

#interactive.viewport > canvas, #interactive.viewport > video {
    max-width: 100%;
    width: 100%;
}

canvas.drawing, canvas.drawingBuffer {
    position: absolute;
    left: 0;
    top: 0;
}
  
@media (max-width: 603px) {

  .reader-config-group {
    width: 100%;
  }

  .reader-config-group label > span {
      width: 50%;
  }

  .reader-config-group label > select, .reader-config-group label > input {
      max-width: calc(50% - 2px);
  }

  #interactive.viewport {
    width: 100%;
    height: auto;
    overflow: hidden;
  }
}

HTML

<div class="card">
    <div class="card-body">
        <div class="row">
          <div class="col-xs-12 col-sm-12 col-md-6">
            <div id="interactive" class="viewport"></div>
          </div>
          <div class="col-xs-12 col-sm-12 col-md-6">
            <div id="result_strip">
          </div>
         </div>
        </div>
    </div>
  </div>

JAVASCRIPT

var AppQuagga = {
    init: function() {
        var self = this;

        Quagga.init(this.state, function(err) {
            if (err) {
                return self.handleError(err);
            }
            //Quagga.registerResultCollector(resultCollector);
            Quagga.start();

            Quagga.onProcessed(function(result) {
                var drawingCtx = Quagga.canvas.ctx.overlay,
                    drawingCanvas = Quagga.canvas.dom.overlay;

                if (result) {
                    if (result.boxes) {
                        drawingCtx.clearRect(0, 0, parseInt(drawingCanvas.getAttribute("width")), parseInt(drawingCanvas.getAttribute("height")));
                        result.boxes.filter(function (box) {
                            return box !== result.box;
                        }).forEach(function (box) {
                            Quagga.ImageDebug.drawPath(box, {x: 0, y: 1}, drawingCtx, {color: "green", lineWidth: 2});
                        });
                    }

                    if (result.box) {
                        Quagga.ImageDebug.drawPath(result.box, {x: 0, y: 1}, drawingCtx, {color: "#00F", lineWidth: 2});
                    }

                    if (result.codeResult &amp;&amp; result.codeResult.code) {
                        Quagga.ImageDebug.drawPath(result.line, {x: 'x', y: 'y'}, drawingCtx, {color: 'red', lineWidth: 3});
                    }
                }
            });

            setTimeout(function() {
              var track = Quagga.CameraAccess.getActiveTrack();
              var capabilities = {};
              if (typeof track.getCapabilities === 'function') {
                try
                  {
                 capabilities = track.getCapabilities(); 
                 track.applyConstraints({advanced: [{zoom: 2.5}]});
                  } catch(e) {}
              }
            }, 500);
        });
    },
    handleError: function(err) {
        console.log(err);
    },
    state: {
        inputStream: {
            type : "LiveStream",
            constraints: {
                facingMode: "environment"
            }
        },
        locator: {
            patchSize: "medium",
            halfSample: true
        },
        numOfWorkers: (navigator.hardwareConcurrency ? navigator.hardwareConcurrency : 4),
        frequency: 20,
        decoder: {
            readers : [{
                format: "code_128_reader",
                config: {}
            }, {
                format: "ean_reader",
                config: {
                }
            }, {
                format: "code_39_reader",
                config: {}
            }, {
                format: "code_93_reader",
                config: {}
            }]
        },
        locate: true
    },
    lastResult : null
};



AppQuagga.init();
      
Quagga.onDetected(function(result) {
	var code = result.codeResult.code;

	if(code != null) {
		if (AppQuagga.lastResult !== code) {
			AppQuagga.lastResult = code;

			var $node = null;
			$node = $('<p>Read: '+code+'</p>');
			$("#result_strip").prepend($node);
		}
	}
});

This piece of code is for zoom, and the timeout attend that the videocamera open itself.
For the zoom you can set the max with: capabilities.zoom.max

setTimeout(function() {
  var track = Quagga.CameraAccess.getActiveTrack();
  var capabilities = {};
  if (typeof track.getCapabilities === 'function') {
	try
	  {
	 capabilities = track.getCapabilities(); 
	 track.applyConstraints({advanced: [{zoom: 2.5}]});
	  } catch(e) {}
  }
}, 500);

Plesk Nginx WP Super Cache Expert Mode Settings

Have you got a wordpress site and you want to optimize it?
The simple way to take fast your website is:

  • Install WPSuper Cache Plugin
  • Setting Server side Nginx

Install WP Super Cache Plugin

The installation of WPSuper Cache is easy, just download the plugin and then upload it on our wordpress website.

Setting WP Super Cache

Now i show to you how to set wp super cache in “Expert mode”, remember that this mode require the change on the server for nginx configuration.

Enable Caching ON

Then we must to set the Expert Mode, and then suggest some setting:

Settings Server side Nginx

Now we need to set the configuration of nginx on our server, in this case i configure a Plesk Server.
We must go in the Domain Setting -> Apache & nginx Settings
In the bottom we find “Additional nginx directives

We must to enable:

  • GZIP compression for the page that we serve on the client
  • Header Cache Control to declase a cache browser for the js, css, image etc..
  • Location to find wpsupercache generated file
  • Security setting 
### WP Super Cache Below ###
set $cache_uri $request_uri;

# POST requests and urls with a query string should always go to PHP
if ($request_method = POST) {
	set $cache_uri 'null cache';
}

# GZIP Compression
gzip on;
gzip_disable "MSIE [1-6]\\.(?!.*SV1)";
gzip_min_length 1100;
gzip_buffers 4 32k;
gzip_proxied any;
gzip_comp_level 9;
gzip_types text/plain text/css application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript image/x-icon image/bmp image/svg+xml;
gzip_vary on;

# NGINX Caching
location ~* \.(?:ico|css|js|gif|jpe?g|png|svg|woff)$ {
	expires 14d;
	add_header Cache-Control "public, no-transform";
	log_not_found off;
}

location ~* \.(jpg|jpeg|gif|png)$ {
	expires 14d;
	add_header Cache-Control "public, no-transform";
	log_not_found off;
}

location ~* \.(pdf|css|html|js|swf)$ {
	expires 14d;
	add_header Cache-Control "public, no-transform";
	log_not_found off;
}

location ~ \.css {
	add_header  Content-Type    text/css;
}
location ~ \.js {
	add_header  Content-Type    application/x-javascript;
}

if ($query_string != "") {
	set $cache_uri 'null cache';
}

# Don't cache uris containing the following segments
if ($request_uri ~* "(/wp-admin/|/xmlrpc.php|/wp-(app|cron|login|register|mail).php|wp-.*.php|/feed/|index.php|wp-comments-popup.php|wp-links-opml.php|wp-locations.php|sitemap(_index)?.xml|[a-z0-9_-]+-sitemap([0-9]+)?.xml)") {
	set $cache_uri 'null cache';
}

# Don't use the cache for logged in users or recent commenters
if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_logged_in") {
	set $cache_uri 'null cache';
}

# Use cached or actual file if they exists, otherwise pass request to WordPress
location ~ / {
	try_files /wp-content/cache/supercache/$http_host/$cache_uri/index.html $uri $uri/ /index.php ;
}

# WORDPRESS PERMALINKS
if (!-e $request_filename) {
	rewrite ^(.+)$ /index.php?q=$1 last;
}

# SECURITY
location ~* wp-config.php { deny all; }
location ~* "^/wp-content/(?!plugins/).*\.php" { deny all; }

Now you can test your site on pagespeed and see the difference!
If you want much performance you can use Autoptimize WordPress plugin to minify js, css and html.

Extend Log4J and evitate the error Repository is null

I have seen that on the web there are few guide on how to extend Log4j.
Now i show to you how to create an extension with a timer function for Log4J.

If you have extended yet a class but have error on “repository nulla” like:
NullPointerException when extending Log4j Logger class

You must to see this extension and resolve that problem. Because you must to use the LogManager istance.

import org.apache.log4j.Logger;

public class LogHelper extends Logger {
    final int _whitespace = 20;
    protected Logger target;

    public LogHelper(Logger target) {
        super(target.getName());
        this.target = target;
    }

    public void timer(String msg, Long timerMillisecond) {
        _timer(msg, timerMillisecond);
    }

    public void timer(Long timerMillisecond) {
        _timer("", timerMillisecond);
    }

    private void _timer(String msg, Long timerMillisecond)
    {
        StringBuilder builder = new StringBuilder(_whitespace);
        String strLog = "";
        strLog = "TIMER: "+timerMillisecond+"ms";
        builder.append(strLog);

        int whiteSpace = _whitespace-builder.length();
        for(int i = 0; i <whiteSpace ; i++) {
            builder.append(' ');
        }
        strLog = builder.toString();

        if(msg != null &amp;&amp; msg != "")  strLog = strLog.concat(" || "+msg);

        if(timerMillisecond < 2000) {
            target.info(strLog);
        } else {
            target.warn(strLog);
        }
    }

    public void error(String message){
        if (target != null)
            target.error(message);
    }

    public void error(Object message, Throwable t) {
        if (target != null)
            target.error(message, t);
    }
}

Refer Logger

The important was to set the refer to a Logger

public LogHelper(Logger target) {
        super(target.getName());
        this.target = target;
    }

Wrap the log error to avoid the NullPointerException on Repository

public void error(String message){
    if (target != null)
    target.error(message);
}

public void error(Object message, Throwable t) {
    if (target != null)
    target.error(message, t);
}

React how to convert Class to Hooks tutorial

The Hooks are a functional component that simplify the use of React, and allow use to create some reusable component.

I have changed on my TodoList App a class to a Hooks

The React Class

class TodoListElementDelete extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      index: 0,
      timer: 0,
      _timeoutRef: null
    };

    this.onClickUndoDelete = this.onClickUndoDelete.bind(this);
    
  }

  componentDidMount() {
    this.setState({
      index: this.props.index,
      timer: this.props.timer
    });
  }

  componentDidUpdate() {
    if (this.props.enable) {
      this.state._timeoutRef = setTimeout(() => {
        if (this.state.timer > 0) {
          this.setState({
            timer: this.state.timer - 1
          });
        } else {
          this.props.onEndTimerAction();
        }
      }, 1000);
    }
  }

  componentWillUnmount() {
    console.log("componentWillUnmount");
    clearTimeout(this.state._timeoutRef);
  }

  onClickUndoDelete() {
    clearTimeout(this.state._timeoutRef);
    this.setState({
      timer: this.props.timer
    });
    this.props.onClickUndoDelete();
  }

  render() {
    let classHideItem = this.props.enable ? "" : "hidden";
    return (
      <div className={"alert alert-danger " + classHideItem}>
        You want to undo the action? {this.state.timer}
        <button
          type="button"
          className="btn btn-warning"
          onClick={this.onClickUndoDelete}
        >
          Undo
        </button>
      </div>
    );
  }
}

React Hooks

I have changed a React Class with React Hooks:

  • timer managed with useState
  • _timeoutRef with useRef
  • ComponentDidMount, ComponentWillUnmount, ComponentDidUpdate with useEffect
const TodoListElementDelete = props => {
  const [timer, setTimer] = React.useState(props.timer);
  let _timeoutRef = React.useRef();

  function onClickUndoDelete() {
    clearTimeout(_timeoutRef.current);
    setTimer(props.timer);
    props.onClickUndoDelete();
  }

  React.useEffect(() => {
    if (props.enable) {
      _timeoutRef.current = setTimeout(() => {
        if (timer > 0) {
          setTimer(timer - 1);
        } else {
          props.onEndTimerAction();
        }
      }, 1000);
    }

    return () => clearTimeout(_timeoutRef.current);
  });

  return (
    <div className={`alert alert-danger ${props.enable ? "" : "hidden"}`}>
      You want to undo the action? {timer}
      <button
        type="button"
        className="btn btn-warning"
        onClick={onClickUndoDelete}
      >
        Undo
      </button>
    </div>
  );
};

30 Second to React – Collection of useful React snippets

Today i want to speak about this beautiful collection of React snippet that i found on github 

There are some useful function, in my opinion the most important are about the use of Hooks.

I report here the Hooks found on GitHub

Hooks

  • useFetch
  • useInterval
  • useNavigatorOnline
  • useTimeout

useFetch

A hook that implements fetch in a declarative manner.

  • Create a custom hook that takes a url and options.
  • Use the React.useState() hook to initialize the response and error state variables.
  • Use the React.useEffect() hook to anychronously call fetch() and update the state varaibles accordingly.
  • Return an object containting the response and error state variables.
const useFetch = (url, options) => {
  const [response, setResponse] = React.useState(null);
  const [error, setError] = React.useState(null);

  React.useEffect(() => {
    const fetchData = async () => {
      try {
        const res = await fetch(url, options);
        const json = await res.json();
        setResponse(json);
      } catch (error) {
        setError(error);
      }
    };
    fetchData();
  }, []);

  return { response, error };
};

useInterval

A hook that implements setInterval in a declarative manner.

  • Create a custom hook that takes a callback and a delay.
  • Use the React.useRef() hook to create a ref for the callback function.
  • Use the React.useEffect() hook to remember the latest callback.
  • Use the React.useEffect() hook to set up the interval and clean up.
const useInterval = (callback, delay) => {
  const savedCallback = React.useRef();

  React.useEffect(() => {
    savedCallback.current = callback;
  }, [callback]);

  React.useEffect(() => {
    function tick() {
      savedCallback.current();
    }
    if (delay !== null) {
      let id = setInterval(tick, delay);
      return () => clearInterval(id);
    }
  }, [delay]);
};

useNavigatorOnLine

A hook that returns if the client is online or offline.

  • Create a function, getOnLineStatus, that uses the NavigatorOnLine web API to get the online status of the client.
  • Use the React.useState() hook to create an appropriate state variable, status, and setter.
  • Use the React.useEffect() hook to add listeners for appropriate events, updating state, and cleanup those listeners when unmounting.
  • Finally return the status state variable.
const getOnLineStatus = () =>
  typeof navigator !== "undefined" &amp;&amp; typeof navigator.onLine === "boolean"
    ? navigator.onLine
    : true;

const useNavigatorOnLine = () => {
  const [status, setStatus] = React.useState(getOnLineStatus());

  const setOnline = () => setStatus(true);
  const setOffline = () => setStatus(false);

  React.useEffect(() => {
    window.addEventListener("online", setOnline);
    window.addEventListener("offline", setOffline);

    return () => {
      window.removeEventListener("online", setOnline);
      window.removeEventListener("offline", setOffline);
    };
  }, []);

  return status;
};

useTimeout

A hook that implements setTimeout in a declarative manner.

  • Create a custom hook that takes a callback and a delay.
  • Use the React.useRef() hook to create a ref for the callback function.
  • Use the React.useEffect() hook to remember the latest callback.
  • Use the React.useEffect() hook to set up the timeout and clean up.
const useTimeout = (callback, delay) => {
  const savedCallback = React.useRef();

  React.useEffect(() => {
    savedCallback.current = callback;
  }, [callback]);

  React.useEffect(() => {
    function tick() {
      savedCallback.current();
    }
    if (delay !== null) {
      let id = setTimeout(tick, delay);
      return () => clearTimeout(id);
    }
  }, [delay]);
};