在DigitalOcean上引入营销自动化工具mautic
在DigitalOcean上安装Mautic。
虽然听说日本没有廉价的数据中心,但由于想尝试一下DigitalOcean这个我早就听说过的平台,又想尝试一下mautic这个我一直想用的工具,所以我一举两得。
关于DigitalOcean
可以使用Droplet作为虚拟服务器的单位,最便宜的Droplet配置(512MB内存、20GB SSD硬盘)价格约为5美元,支持在28天内使用。
虽然无法使用日本的数据中心有些遗憾,但由于可以使用新加坡的数据中心,对于验证来说已经足够了,所以决定使用。
DigitalOcean在此链接→https://www.digitalocean.com/
只需要提供电子邮件、密码、地址和支付信息进行注册,只要5分钟不到。
关于Mautic
这是一个开源的营销自动化(MA)工具。由于我经常听到 MA 工具这个词,我首先想知道它究竟是什么。虽然可以通过书籍等途径来学习,但我偶然间知道了这个开源的 MA 工具,同时也想试试上述的 DigitalOcean,于是我准备了一个 Droplet,将 mautic 安装在其中,以试验性地使用。
Mautic可在此处找到→https://www.mautic.org/
请提供更多上下文信息。
我已经配置好了Nginx、PHP7和MySQL的环境。
创建 Droplet
操作系统为CentOS6.9(64位),最低配置为5美元,在新加坡的数据中心,勾选私人网络(实际上这是不必要的),注册了SSH公钥,并设置了主机名创建。大约1分钟完成,可以通过密钥认证登录虚拟服务器。
创建iptables
尽管是为了验证,但为确保最低限度的安全性,我在iptables上设置了简单的防火墙配置。
#!/bin/sh
iptables -F INPUT
iptables -F OUTPUT
iptables -F FORWARD
iptables -P INPUT DROP
iptables -P OUTPUT ACCEPT
iptables -P FORWARD DROP
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
在上述设置中,除了ssh和http之外的通信都不被允许。但是,对于来自服务器的响应,我们进行了接受。通过执行上述shell脚本,我们实现了一个简易防火墙。
$ /bin/sh /root/tools/iptables.sh
另外,在重新启动时,请在/etc/rc.local文件中添加以下内容。
/bin/sh /root/tools/iptables.sh
设置时间
时区的变更
将时区更改为日本时间。
$ cp /usr/share/zoneinfo/Japan /etc/localtime
与NTP服务器的同步
安装ntpd,并确保以SLEW模式准确地保持软件时钟。
安装ntpd。
$ yum install ntp
$ chkconfig ntpd on
ntpd的配置
把ntp.conf文件按照以下的方式进行编写。
# For more information about this file, see the man pages
# ntp.conf(5), ntp_acc(5), ntp_auth(5), ntp_clock(5), ntp_misc(5), ntp_mon(5).
driftfile /var/lib/ntp/drift
# Permit time synchronization with our time source, but do not
# permit the source to query or modify the service on this system.
restrict default kod nomodify notrap nopeer noquery
restrict -6 default kod nomodify notrap nopeer noquery
# Permit all access over the loopback interface. This could
# be tightened as well, but to do so would effect some of
# the administrative functions.
restrict 127.0.0.1
restrict -6 ::1
# Hosts on local network are less restricted.
#restrict 192.168.1.0 mask 255.255.255.0 nomodify notrap
# Use public servers from the pool.ntp.org project.
# Please consider joining the pool (http://www.pool.ntp.org/join.html).
#server 0.centos.pool.ntp.org iburst
#server 1.centos.pool.ntp.org iburst
#server 2.centos.pool.ntp.org iburst
#server 3.centos.pool.ntp.org iburst
server -4 ntp.nict.jp
server -4 ntp1.jst.mfeed.ad.jp
server -4 ntp2.jst.mfeed.ad.jp
server -4 ntp3.jst.mfeed.ad.jp
#broadcast 192.168.1.255 autokey # broadcast server
#broadcastclient # broadcast client
#broadcast 224.0.1.1 autokey # multicast server
#multicastclient 224.0.1.1 # multicast client
#manycastserver 239.255.254.254 # manycast server
#manycastclient 239.255.254.254 autokey # manycast client
# Enable public key cryptography.
#crypto
includefile /etc/ntp/crypto/pw
# Key file containing the keys and key identifiers used when operating
# with symmetric key cryptography.
keys /etc/ntp/keys
# Specify the key identifiers which are trusted.
#trustedkey 4 8 42
# Specify the key identifier to use with the ntpdc utility.
#requestkey 8
# Specify the key identifier to use with the ntpq utility.
#controlkey 8
# Enable writing of statistics records.
#statistics clockstats cryptostats loopstats peerstats
启动ntpd
$ /etc/init.d/ntpd start
将其反映到硬件时钟中
执行以下命令。
$ hwclock -w > /dev/null 2>&1
在Cron中,添加并进行下述设置非常简便。
在下述示例中,我们将同步设置为每周一上午3点。
0 3 * * 1 root /sbin/hwclock -w > /dev/null 2>&1
创建交换空间
创建 droplet 后,swap 区域变为了 0。
$ free
total used free shared buffers cached
Mem: 501968 493816 8152 53488 3736 74344
-/+ buffers/cache: 415736 86232
Swap: 0 0 0
如果在没有swap空间的情况下进行运营,MySQL会频繁出现错误,导致数据库崩溃。
017-06-23T16:52:56.670021Z 0 [ERROR] InnoDB: mmap(137428992 bytes) failed; errno 12
2017-06-23T16:52:56.670092Z 0 [ERROR] InnoDB: Cannot allocate memory for the buffer pool
2017-06-23T16:52:56.670117Z 0 [ERROR] InnoDB: Plugin initialization aborted with error Generic error
2017-06-23T16:52:56.670145Z 0 [ERROR] Plugin 'InnoDB' init function returned error.
2017-06-23T16:52:56.670161Z 0 [ERROR] Plugin 'InnoDB' registration as a STORAGE ENGINE failed.
2017-06-23T16:52:56.670175Z 0 [ERROR] Failed to initialize plugins.
2017-06-23T16:52:56.670196Z 0 [ERROR] Aborting
使用dd命令创建用于交换的文件。
我在这里创建了一个1GB的交换文件。
$ dd if=/dev/zero of=/swapfile bs=1M count=1024
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB) copied, 2.83618 s, 379 MB/s
创建一个交换领域
mkswap /swapfile
mkswap: /swapfile: warning: don't erase bootbits sectors
on whole disk. Use -f to force.
Setting up swapspace version 1, size = 1048572 KiB
no label, UUID=4cc2fb29-7e0d-4342-b888-d131c248febe
激活交换领域
$ swapon /swapfile
通过启用交换领域,可以确认以下交换领域已准备就绪。
$ free
total used free shared buffers cached
Mem: 501968 495760 6208 53488 2728 76548
-/+ buffers/cache: 416484 85484
Swap: 1048572 0 1048572
当你重新启动时,仍然要确保激活swap分区。
编辑/etc/fstab。
UUID=3fda56ee-2072-4762-b2d8-51a806890759 / ext4 defaults 1 1
tmpfs /dev/shm tmpfs defaults 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
/swapfile swap swap defaults 0 0
安装MySQL5.7
安装
$ rpm --import http://dev.mysql.com/doc/refman/5.7/en/checking-gpg-signature.html
$ rpm -ihv http://dev.mysql.com/get/mysql57-community-release-el6-7.noarch.rpm
$ yum --disablerepo=\* --enablerepo='mysql57-community*' list available
$ yum --enablerepo='mysql57-community*' install -y mysql-community-server
设定文件
[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_general_ci
default-storage-engine=innodb
innodb_large_prefix
sql_mode=ONLY_FULL_GROUP_BY,NO_AUTO_CREATE_USER,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
symbolic-links=0
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
[client]
default-character-set=utf8mb4
[mysql]
default-character-set=utf8mb4
启动
启动MySQL 5.7。
$ /etc/init.d/mysqld start
请确认root用户的初始密码。
执行以下命令,确认初始密码。
$ cat /var/log/mysqld.log | grep 'password is generated'
更改根目录的密码
使用确认过的初始密码登录MySQL5.7。
mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'LxAeT$#11op';
另外,在 Mautic 中创建数据库。
shell-session
mysql> 创建数据库 mautic;
MTA检查
安装mailx,并尝试发送测试邮件。
$ yum install -y mailx
$ alternatives --display mta
$ echo "test" | mail -s "subject" myname@mydomain.com
安装Nginx
安装
$ rpm -ivh http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm
$ yum -y install nginx
配置文件
user nginx;
worker_processes 1;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
error_log /var/log/nginx/error.log warn;
sendfile off;
#tcp_nopush on;
keepalive_timeout 65;
fastcgi_read_timeout 180;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
server {
listen 80 default;
server_name _;
root /var/www/html/mautic;
index index.php index.html index.htm;
charset utf-8;
access_log /var/log/nginx/default.access.log;
error_log /var/log/nginx/default.error.log;
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
sendfile off;
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
fastcgi_intercept_errors on;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_buffer_size 16k;
fastcgi_buffers 4 16k;
include fastcgi_params;
}
}
安装PHP7和php-fpm。
安装
$ yum install --enablerepo=remi-php70 -y \
php \
php-fpm \
php-cli \
php-mcrypt \
php-common \
php-devel \
php-mbstring \
php-mysqlnd \
php-opcache \
php-pdo \
php-pear \
php-pecl-apcu \
php-pecl-zip \
php-process \
php-xml \
php-intl \
php-soap \
php-pecl-memcache \
php-pecl-memcached \
php-couchbase \
php-imap \
php-json \
php-curl \
php-gd
設置檔案
default_charset = "UTF-8"
date.timezone = "Asia/Tokyo"
display_errors = On
display_startup_errors = On
log_errors = On
[mbstring]
mbstring.language = Japanese
user = nginx
group = nginx
listen = /var/run/php-fpm/php-fpm.sock
listen.owner = nginx
listen.group = nginx
listen.mode = 0660
catch_workers_output = yes
php_flag[display_errors] = on
php_admin_value[display_errors] = 'stderr'
安装Node.js(npm),gulp和webpack
$ yum install -y gcc-c++ make
$ curl -sL https://rpm.nodesource.com/setup_6.x | sudo -E bash -
$ yum install nodejs
$ npm i -g grunt-cli
$ npm i -g browserify
$ npm i -g uglify-js
$ npm i -g webpack
安装Mautic
安装git和composer
$ yum install -y git
$ cd /tmp
$ curl -sS https://getcomposer.org/installer | php
$ mv composer.phar /usr/local/bin/composer
$ composer self-update
事前にgithubにあるmauticをforkする。
その後、仮想サーバで以下のコマンドを実行し、forkしたmauticをgit cloneすることで設置。mauticのバージョンを更新するときは、git pull origin masterで、更新。
$ cd /var/www/html
$ git clone https://github.com/myacccount/mautic.git
$ cd mautic
$ git checkout master
$ composer install
アクセス権限の変更
このままだとnginxを起動しても、ブラウザアクセスしたときにエラーが発生するので、権限を変更する。
$ touch /var/log/php-fpm/www-error.log
$ chmod 777 -R /var/log/php-fpm
$ chmod 777 -R /var/lib/php/session
$ chmod 777 -R /var/www/html/app/cache
$ chmod 777 -R /var/www/html/app/logs
启动 nginx 和 php-fpm。
まずはphp-fpmから起動する。
$ /etc/init.d/php-fpm start
接下来启动nginx。
$ /etc/init.d/nginx start
启动Mautic。
只要打开浏览器,Mautic的数据库设置和管理员用户注册页面将依次显示出来,并且成功显示仪表盘页面。
※キャプチャ画像では日本語対応で表示されている。設定の詳細はこちらを参照した。ただし、一度ログアウトしないと日本語化されなかったので、動作仕様について調べてみたいと思う。
その他
阿凡达 (Ā dá)
mauticにログインするとアバター画像が表示されない状態になるので、気になるのであればgravatarで、アカウント作成時に指定したメールアドレスでgravatarに登録すれば(登録しても即時反映されなかった)正常に表示される。
故障相关
※実はMariaDBでmauticを動作させようとしたが、下記のPHPエラーが発生したため、断念し、Dropletを再作成した背景があった。
[2017-05-02 11:55:53] mautic.CRITICAL: Uncaught PHP Exception Doctrine\DBAL\Exception\DriverException: "An exception occurred while executing 'SELECT COUNT(t.date_added) AS leads, ll.id, ll.name FROM lead_lists_leads t INNER JOIN lead_lists ll ON ll.id = t.leadlist_id WHERE (ll.is_published = ?) AND (t.date_added BETWEEN ? AND ?) GROUP BY ll.id ORDER BY leads DESC LIMIT 9' with params [true, "2017-04-02 00:00:00", "2017-05-02 23:59:59"]: SQLSTATE[42000]: Syntax error or access violation: 1055 'mautic.ll.name' isn't in GROUP BY" at /var/www/html/src/mautic/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractMySQLDriver.php line 115 {"exception":"[object] (Doctrine\\DBAL\\Exception\\DriverException(code: 0): An exception occurred while executing 'SELECT COUNT(t.date_added) AS leads, ll.id, ll.name FROM lead_lists_leads t INNER JOIN lead_lists ll ON ll.id = t.leadlist_id WHERE (ll.is_published = ?) AND (t.date_added BETWEEN ? AND ?) GROUP BY ll.id ORDER BY leads DESC LIMIT 9' with params [true, \"2017-04-02 00:00:00\", \"2017-05-02 23:59:59\"]:\n\nSQLSTATE[42000]: Syntax error or access violation: 1055 'mautic.ll.name' isn't in GROUP BY at /var/www/html/src/mautic/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractMySQLDriver.php:115, Doctrine\\DBAL\\Driver\\PDOException(code: 42000): SQLSTATE[42000]: Syntax error or access violation: 1055 'mautic.ll.name' isn't in GROUP BY at /var/www/html/src/mautic/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php:93, PDOException(code: 42000): SQLSTATE[42000]: Syntax error or access violation: 1055 'mautic.ll.name' isn't in GROUP BY at /var/www/html/src/mautic/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php:91)"} []
我总结了关于这个错误的调查结果。由于在GROUP BY中省略了列指定而进行了SELECT操作。不是MariaDB或MySQL,而是取决于sql_mode是否设置为ONLY_FULL_GROUP_BY。