Simple life, Complicated mind

Friday, November 30, 2018

To determine Vue current development mode

In main.js:

windows['VueMode'] = process.env.NODE_ENV;

Note: If you would like to use process.env.NODE_ENV in a sub component, put it inside one of the lifecycle hooks. For example, created, or mounted.

Friday, November 16, 2018

mtail - extract whitebox monitoring data from application logs for collection in a timeseries database

mtail - extract whitebox monitoring data from application logs for collection in a timeseries database

$ curl -L -o mtail

$ vim linecounter.mtail

# simple line counter
counter line_count
/$/ {

$ mtail --progs linecounter.mtail --logs debug.log

$ echo hi1 >> debug.log
$ echo hi2 >> debug.log

$ curl http://localhost:3903/metrics


Install MySQL 5.7, Apache 2.4, PHP 7.1 on Ubuntu 16.04

Install MySQL 5.7, Apache 2.4, PHP 7.1 on Ubuntu 16.04

Install VMware tools:

VM > Guest > Install/Upgrade VMware Tools

# su -
# df -h
# cd /media/jun/VMware\ Tools/
# ls -la
# tar zxvf VMwareTools-9.4.0-1280544.tar.gz -C /tmp/
# cd /tmp
# ls
# cd vmware-tools-distrib/
# ls
# ./ -d
# reboot

Note: For more info

Move Ubuntu launcher to the bottom:

# gsettings set com.canonical.Unity.Launcher launcher-position Bottom

Update the package repository:

# apt-get update

Upgrades packages with auto-handling of dependencies:

# apt-get dist-upgrade


# apt full-upgrade

Install SSH server:

# apt-get install openssh-server
# systemctl status sshd.service
# systemctl restart sshd.service

Compile and install the latest Git 2.19.0 from source code:

# apt-get install dh-autoreconf libcurl4-gnutls-dev libexpat1-dev gettext libz-dev libssl-dev \
&& apt-get install curl \
&& cd /usr/local/src/ \
&& curl -L -o git.tar.gz \
&& tar zxvf git.tar.gz \
&& cd git-2.19.0/ \
&& make configure \
&& ./configure --prefix=/usr \
&& make all \
&& make install

# git --version

git version 2.19.0

Install Git from ppa:

# add-apt-repository ppa:git-core/ppa
# apt-get update

# apt-cache policy git
# apt-cache madison git

# apt-get install git=1:2.11.0-2~ppa0~ubuntu16.04.1

# git --version

Compile and install the latest Vim 8:

# apt-get install libncurses5-dev python-dev ruby-dev libperl-dev ruby-dev liblua5.3-dev exuberant-ctags cscope

// Fix liblua paths
# ln -s /usr/include/lua5.3 /usr/include/lua \
&& ln -s /usr/lib/x86_64-linux-gnu/ /usr/local/lib/

# cd /usr/local/src \
&& git clone --depth 1 \
&& cd vim \
&& ./configure \
--prefix=/usr \
--with-features=huge \
--enable-multibyte \
--enable-pythoninterp \
--enable-python3interp \
--enable-rubyinterp \
--enable-perlinterp \
--enable-luainterp \
--enable-cscope \
&& make \
&& make install \
&& hash -r \
&& vim --version | head

Install MTA mail server:

# apt-get install postfix

Note: select "Internet site".

Note: If you need to reconfigure the postfix setting, run either one of the following:

# dpkg-reconfigure -plow postfix


# apt-get purge postfix

For other mail related packages:

# apt-get install mailutils

Install mail client:

# apt-get install bsd-mailx
# echo "test message" | mailx -s 'test subject'

For hexdump command:

# apt-get install bsdmainutils

# hexdump -c test.log

Install MySQL5.7:

# apt-cache policy mysql-server
# apt-cache search mysql-server
# apt-cache show mysql-server | less
# apt show mysql-server

# apt-get install mysql-server

# vim /etc/mysql/mysql.conf.d/mysqld.cnf
bind-address =

# vim ~/.my.cnf
host = localhost
port = 3306
user = root
password = MyPassword

# chmod 400 ~/.my.cnf

# mysql -e "SHOW variables WHERE variable_name REGEXP 'open_files_limit|table_open_cache|max_connections';"
| Variable_name              | Value |
| max_connections            | 151   |
| open_files_limit           | 1024  |
| table_open_cache           | 431   |
| table_open_cache_instances | 16    |

Note: You will see the following error message in the error.log file if you did not change the open files limit:
[Warning] Changed limits: max_open_files: 1024 (requested 5000)
[Warning] Changed limits: table_open_cache: 431 (requested 2000)

# mkdir /etc/systemd/system/mysql.service.d
# vim /etc/systemd/system/mysql.service.d/override.conf



# systemctl daemon-reload
# systemctl restart mysql

# mysql -e "SHOW variables WHERE variable_name REGEXP 'open_files_limit|table_open_cache|max_connections';"
| Variable_name              | Value |
| max_connections            | 151   |
| open_files_limit           | 5000  |
| table_open_cache           | 2000  |
| table_open_cache_instances | 16    |

To check MySQL process's limit:

# cat /proc/$(pgrep mysqld$)/limits
Limit                     Soft Limit           Hard Limit           Units
Max cpu time              unlimited            unlimited            seconds
Max file size             unlimited            unlimited            bytes
Max data size             unlimited            unlimited            bytes
Max stack size            8388608              unlimited            bytes
Max core file size        0                    unlimited            bytes
Max resident set          unlimited            unlimited            bytes
Max processes             15614                15614                processes
Max open files            5000                 5000                 files
Max locked memory         65536                65536                bytes
Max address space         unlimited            unlimited            bytes
Max file locks            unlimited            unlimited            locks
Max pending signals       15614                15614                signals
Max msgqueue size         819200               819200               bytes
Max nice priority         0                    0
Max realtime priority     0                    0
Max realtime timeout      unlimited            unlimited            us




To move a MySQL data directory to another directory:

# mysql -e "SELECT @@datadir;"
| @@datadir       |
| /var/lib/mysql/ |

# systemctl stop mysql
# systemctl status mysql

# vim /etc/mysql/mysql.conf.d/mysqld.cnf
datadir         = /home/mysql

# vim /etc/apparmor.d/tunables/alias
alias /var/lib/mysql/ -> /home/mysql/,

Note: We need to tell AppArmor to let MySQL write to the new directory by creating an alias between the default directory and the new location.

Note: If you skipped the AppArmor configuration step, you would see the following error message:

Job for mysql.service failed because the control process 
exited with error code. See "systemctl status mysql.service" 
and "journalctl -xe" for details.

# systemctl restart apparmor
# systemctl restart mysql

To move the existing to MySQL directory to /home:

# rsync -av /var/lib/mysql /home

Or, you can run the following commands to initialize the MySQL data directory:

# mkdir /home/mysql \
&& chown mysql:mysql /home/mysql \
&& chmod 700 /home/mysql \
&& mysqld --initialize-insecure

Note: This option is used to initialize a MySQL installation by creating the data directory and populating the tables in the mysql system database.

Note: If you use --initialize, the random initial password is stored at: tail -n 1 /var/log/mysql/error.log.

Note: You can also start mysqld with --skip-grant-tables to access the database and change the password.

# systemctl start mysql && systemctl status mysql

Login MySQL with the above commands if you initialized MySQL data directory with --initialize-insecure option.
# mysql -u root --skip-password
mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'new_password';

Check the current MySQL data directory:

# mysql -e "SELECT @@datadir;"
| @@datadir    |
| /home/mysql/ |

To change the root password if you did not know the current root password:

# vim /root/tmp/mysql-init.txt
GRANT SUPER ON *.* TO 'root'@'localhost';

# mysqld --init-file=/root/tmp/mysql-init.txt

Use RAM-DISK for tmpdir:

# mysql -e "SHOW GLOBAL STATUS LIKE 'Created_tmp%tables';"
# mysql -e "SHOW GLOBAL VARIABLES LIKE '%table_size';"

# mkdir -p /mnt/ramdisk
# mount -t tmpfs -o size=512M tmpfs /mnt/ramdisk
# chown mysql:mysql /mnt/ramdisk

# id mysql

uid=123(mysql) gid=130(mysql) groups=130(mysql)

# vim /etc/fstab

tmpfs           /mnt/ramdisk     tmpfs   rw,uid=123,gid=130,mode=1770,size=512M    0       0

Note: You need to change the uid and gid of MySQL.

# mysql -e "SHOW GLOBAL VARIABLES LIKE 'tmpdir';"

# vim /etc/apparmor.d/local/usr.sbin.mysqld

/mnt/ramdisk rw,
owner /mnt/ramdisk/** rwkl,

Note: The first line gives read and write access to the directory, the second line gives read, write, lock(k) and link(l) access to all the files and the directories inside the directory owned by the mysql user.

# vim /etc/mysql/mysql.conf.d/mysqld.cnf

tmpdir      = /mnt/ramdisk

# systemctl restart apparmor.service
# systemctl restart mysql.service

Install PHP7.1:

# command -v add-apt-repository >/dev/null 2>&1 \
|| { echo >&2 "add-apt-repository is not installed. I will install it for you"; apt-get install python-software-properties; }

# add-apt-repository -y ppa:ondrej/php
# apt-get update

# apt-cache policy php7.1

# apt-get install php7.1-fpm
# apt-get install php7.1-xml php7.1-curl php7.1-zip php7.1-gd php7.1-bcmath php7.1-intl php7.1-mbstring php7.1-mcrypt php7.1-mysql
# apt-get install php7.1-json php7.1-opcache
# apt-get install php-xdebug

# php -v
PHP (cli) (built: Sep 29 2017 17:04:25) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2017 Zend Technologies
    with Zend OPcache, Copyright (c) 1999-2017, by Zend Technologies
    with Xdebug v2.5.5, Copyright (c) 2002-2017, by Derick Rethans

# vim /etc/php/7.1/fpm/pool.d/www.conf

;listen = /run/php/php7.1-fpm.sock
listen =

Note: You can choose to use either a Unix socket (for local access only) or TCP socket (for the other server on the network to access).

# systemctl restart php7.1-fpm.service && systemctl status php7.1-fpm.service

# ss -an | grep :9000
tcp    LISTEN     0      128                  *:*

# vim /etc/php/7.1/fpm/php.ini

date.timezone = America/Vancouver
display_errors = On
display_startup_errors = On
error_reporting = E_ALL
error_log = /var/log/php_errors.log

List all the installed PHP packages:

# dpkg -l | grep php| awk '{print $2}' |tr "\n" " "

Show the available package version:

# apt-cache search php
# apt-cache policy php

Install the specific package version:

# apt-get install php7=7.0+35ubuntu6

Note: You can look up old versions of packages at their site

Install older version of PHP (PHP5.6):

# add-apt-repository ppa:ondrej/php

# apt-get update

# apt-get install php5.6-fpm

# apt-get install php5.6-gd php5.6-intl php5.6-json php5.6-mbstring php5.6-mcrypt php5.6-mysql php5.6-opcache php5.6-xml

# a2disconf php7.0-fpm.conf
# a2enconf php5.6-fpm.conf

# systemctl restart apache2.service

Install Apache2.4:

# command -v add-apt-repository >/dev/null 2>&1 \
|| { echo >&2 "add-apt-repository is not installed. I will install it for you"; apt-get install python-software-properties; }

# add-apt-repository -y ppa:ondrej/apache2
# apt-get update

# apt-cache policy apache2

# apt-get install apache2

Enable the following modules to talk to PHP:

# cat /etc/apache2/conf-available/php7.1-fpm.conf

# a2enmod proxy proxy_fcgi rewrite setenvif ssl
# a2enconf php7.1-fpm.conf

If your apache is talking to PHP through a TCP socket ( instead of a Unix socket (/run/php/php7.1-fpm.sock), you will need to modify the following line:

# vim /etc/apache2/conf-available/php7.1-fpm.conf
# Define a matching worker.
    # The part that is matched to the SetHandler is the part that
    # follows the pipe. If you need to distinguish, "localhost; can
    # be anything unique.
    <Proxy "fcgi://localhost/" enablereuse=on max=10>
    <FilesMatch ".+\.ph(ar|p|tml)$">
        #SetHandler "proxy:unix:/run/php/php7.1-fpm.sock|fcgi://localhost"
        SetHandler "proxy:fcgi://"

# apache2ctl configtest
# systemctl restart apache2 && systemctl status apache2

Install and enable the following Apache modules if you are connecting to PHP through a TCP socket (

# apt-get install libapache2-mod-fastcgi
# a2enmod fastcgi rewrite setenvif

Edit apache2.conf:

# vim /etc/apache2/apache2.conf

AllowOverride All

Set up a virtual host:

# cd /etc/apache2/sites-available
# cp 000-default.conf mag2.local.conf
# vim mag2.local

Check the configuration:

# apache2ctl -V
# apache2ctl -t
# apache2ctl -M
# apache2ctl configtest

Enable the site:

# a2ensite mag2.local

Start MySQL, PHP, and Apache:

# systemctl restart mysql.service
# systemctl restart php7.0-fpm.service
# systemctl restart apache2.service

# ps auxww | grep -i mysql
# ps auxww | grep -i php-fpm
# ps auxww | grep -i apache2

Install PHPStorm:

# cd ~jun/Downloads/
# tar xf PhpStorm-*.tar.gz -C /opt/
# cd /opt/PhpStorm-163.10504.2/
# ./bin/

Generate a self-signed SSL certificate:

# openssl req -x509 -nodes -days 365 -newkey rsa:2048 -subj "/C=CA/ST=British Columbia/L=Vancouver/O=My Company Name/CN=erp.local" -keyout /etc/ssl/private/test.local.key -out /etc/ssl/certs/test.local.crt

Install node:

$ curl -o- | bash

$ command -v nvm


$ nvm ls-remote
$ nvm install 8.9.3
$ nvm use 8.9.3
$ node -v
$ nvm ls

$ echo '{}' > package.json
$ npm install webpack eslint js-beautify --save-dev


Monday, October 29, 2018

Running php-fpm in Docker based on CentOS 7

Running php-fpm in Docker based on CentOS 7


FROM centos:centos7

RUN curl '' -o \
 && bash \
 && rm -f \
 && yum -y update \
 && yum -y install \
  php71u-common \
  php71u-cli \
  php71u-fpm \
  php71u-opcache \
  php71u-xml \
  php71u-json \
  php71u-pdo \
  php71u-mysqlnd \
  php71u-intl \
  php71u-mbstring \
  php71u-mcrypt \
  php71u-gd \
  php71u-soap \
  php71u-process \
  php71u-pecl-redis \
  php71u-pecl-xdebug \


CMD ["php-fpm", "-F"]

Build the docker image:

# docker build -t junhsieh/php7.1-fpm:0.0.0 .

Some important settings to be changed:

# vim /etc/php-fpm.d/www.conf

; Change ownership:

user = php-fpm
group = php-fpm

; Note: Ubuntu uses www-data user. Add php-fpm user to www-data group if the other container used it.
; # groupadd -g 33 www-data
; # useradd www-data -m -c 'web user' -u 33 -g 33
; # usermod -a -G www-data php-fpm
; # id php-fpm
; Now, restart this container to ensure php-fpm user is in www-data group.

; Bind port 9000 to the all interfaces:

listen = 9000
;listen = [::]:9000

; Note: PHP-FPM has a listen.client_allowed setting which allows you to set a list of IPs that can connect, or leave blank for any IP to connect. However, even with it being left blank, the issue still persisted. Digging into the official PHP-FPM repo, I discovered that you also need to set  listen = [::]:9000 which then began to allow any IP to connect.
; Note:

; Comment out the following line:

;listen.allowed_clients =

; Note: "listen.allowed_clients = any" will not work.
; Note: "listen.allowed_clients = other-container-name" will not work. IP address only.

; Uncomment the following line to debug the issue:

catch_workers_output = yes

; Note: Comment it out on production.

xdebug setting:

### xdebug setting
; Enable xdebug extension module

; Note: php-fpm uses port 9000 as well.



Sunday, October 14, 2018

usermod and groupmod not found in Alpine Linux Docker Image

usermod and groupmod not found in Alpine Linux Docker Image

$ vim Dockerfile

FROM alpine:latest

RUN apk --no-cache add shadow \
  && usermod -u 2500 elasticsearch \
  && groupmod -g 2500 elasticsearch

Monday, October 8, 2018

Setup A Centralized Log Server Using Rsyslog on Ubuntu 16.04 LTS

Setup A Centralized Log Server Using Rsyslog on Ubuntu 16.04 LTS

Rsyslog Server:

# vim /etc/rsyslog.conf

# provides UDP syslog reception
input(type="imudp" port="514")

# provides TCP syslog reception
input(type="imtcp" port="514")

# vim /etc/rsyslog.d/tmpl.conf

$template TmplAuth, "/var/log/client_logs/%HOSTNAME%/%PROGRAMNAME%.log"
$template TmplMsg, "/var/log/client_logs/%HOSTNAME%/%PROGRAMNAME%.log"

authpriv.* ?TmplAuth
*.info;mail.none;authpriv.none;cron.none ?TmplMsg

# systemctl restart rsyslog

Rsyslog Client:

# vim /etc/rsyslog.conf

*.* @

Note: The @ symbol before the IP address tells rsyslog to use UDP to send the messages. Change this to @@ to use TCP.

# systemctl restart rsyslog

# logger -s " This is my Rsyslog client "

# tree /var/log/client_logs/

The following is a list of RFCs that define the Syslog protocol:

RFC 3195 Reliable Delivery for syslog
RFC 5424 The Syslog Protocol
RFC 5425 TLS Transport Mapping for Syslog
RFC 5426 Transmission of Syslog Messages over UDP
RFC 5427 Textual Conventions for Syslog Management
RFC 5848 Signed Syslog Messages
RFC 6012 Datagram Transport Layer Security (DTLS) Transport Mapping for Syslog


Caused by: No subject alternative names matching IP address XXXXX found

Caused by: No subject alternative names matching IP address XXXXX found 
at Source) ~[na:1.8.0_51] 
at Source) ~[na:1.8.0_51] 

# vim

Hashtable<String, Object> objEnvironment;
    objEnvironment = new Hashtable<String, Object>(11);
    objEnvironment.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
    objEnvironment.put(Context.PROVIDER_URL,  "LDAPS://domain:636");
    objEnvironment.put(Context.SECURITY_AUTHENTICATION, "simple");
    objEnvironment.put(Context.SECURITY_PRINCIPAL, <username>);
    objEnvironment.put(Context.SECURITY_CREDENTIALS, <Password>);
    objEnvironment.put("java.naming.ldap.attributes.binary", <attributes>);
    System.setProperty("", "certificates".concat(File.separator).concat("cacerts"));
    this.objLDAPContext = new InitialLdapContext(objEnvironment, null);

# java main -Dcom.sun.jndi.ldap.object.disableEndpointIdentification=true

Note: Do not use the -Dcom.sun.jndi.ldap.object.disableEndpointIdentification=true option on production server.

Improve LDAP support Endpoint identification has been enabled on LDAPS connections.

To improve the robustness of LDAPS (secure LDAP over TLS ) connections, endpoint identification algorithms have been enabled by default.

Note that there may be situations where some applications that were previously able to successfully connect to an LDAPS server may no longer be able to do so. Such applications may, if they deem appropriate, disable endpoint identification using a new system property: com.sun.jndi.ldap.object.disableEndpointIdentification.

Define this system property (or set it to true) to disable endpoint identification algorithms.