Web 安装
npm (nodejs)
# 安装 npm
sudo apt install npm -y
# 可能要重进 CLI
npm -v
# 3.5.2
nodejs -v
# v8.10.0
sudo npm install -g n
sudo n latest
PATH="$PATH"
npm -v
sudo npm -g install npm@6.14.8 (1)
PATH="$PATH"
npm -v
# 6.14.8
nodejs -v
# v8.10.0
# 另一个安装方式
sudo npm cache clean -f
sudo npm install -g n
sudo n 14.15.0
node -v
# v14.15.0
1 | 可至 npm 查找版本。 |
# npm 安装跟路径有关 (除了 global)
cd <package_path>
npm install <package>
# global 安装
sudo npm install --global <package>
# 得知 global 安装路径
npm list -g | head -1
# /usr/local/lib
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.0/install.sh | bash
source ~/.bashrc
nvm ls-remote | grep v14.
# v14.15.0 (Latest LTS: Fermium)
nvm install 14.15.0
node -v
# v14.15.0
nvm --help Usage: nvm install [version] # Download and install [version] nvm uninstall [version] # Uninstall [version] nvm use [version] # Switch to use [version] nvm list # List installed versions
rm -rf ~/.nvm rm -rf ~/.npm rm -rf ~/.bower
export NVM_DIR="/home/ubuntu/.nvm" [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
sudo apt remove nodejs -y
sudo apt remove npm -y
sudo rm -rf /usr/local/share/man/man1/node*
sudo rm -rf /usr/local/lib/dtrace/node.d
sudo rm -rf /opt/local/bin/node
sudo rm -rf /opt/local/include/node
sudo rm -rf /opt/local/lib/node_modules
sudo rm -rf /usr/local/lib/node*
sudo rm -rf /usr/local/include/node*
sudo rm -rf /usr/local/bin/node*
rm -rf ~/.node-gyp
rm -rf ~/.npm
# 可能会出错, 采用 sudo rm -rf /home/ubuntu/.npm
# 取得 prefix
npm config get prefix
# /usr/local (1)
# 测试安装 global 套件,没有 sudo 就是要让它出错.
npm install -global rouge
# npm ERR! Error: EACCES: permission denied, access '/usr/local/lib/node_modules' (2)
# 设置 prefix 为 /usr/bin, 看看会不会变成 /usr/bin/lib
# 竟然不需要 root 权限 ?
npm config set prefix /usr/bin
# 没有 sudo 让它出错.
npm install -global rouge
# npm ERR! Error: EACCES: permission denied, mkdir '/usr/bin/lib' (3)
# 改回来
npm config set prefix /usr/local
1 | 有点奇怪,npm global 会安装在 /usr/local/lib/node_modules,但 prefix 怎么不是 /usr/local/lib? 而是 /usr/local,莫非会自行附加 lib? |
2 | 路径没错,prefix 会自动附加 lib 变成 /usr/local/lib。 |
3 | 没错!npm 创建 /usr/local/lib 目录,prefix 会自动附加 lib。 |
Apache
sudo apt update && sudo apt upgrade -y
sudo apt install apache2 -y
# 激活 mod_reswite 功能
sudo a2enmod rewrite
# 显示版本
apache2 -v
# 列出激活的 rewrite 模块
ls /etc/apache2/mods-enabled/ | grep rewrite
sudo apache2ctl -M | grep rewrite
# 列出可用模块
ls /etc/apache2/mods-available/
# 检查目前可用的站台
ls /etc/apache2/sites-available
# 检查目前激活中的站台
ls /etc/apache2/sites-enabled
# 激活 a2ensite
sudo a2ensite $site
# 不激活 a2dissite
sudo a2dissite $site
# apache 重新加载组态
sudo systemctl reload apache2
# 重新启动 apache
sudo systemctl restart apache2
# 停止 apache
sudo systemctl stop apache2
/etc/apache2 ├── conf-available ├── conf-enabled ├── mods-available ├── mods-enabled ├── sites-available (1) └── sites-enabled (2)
1 | 网站设置档是在 /etc/apache2/sites-available 的位置,另外 /etc/apache2/sites-enabled 是经过 a2ensite 指令激活过的虚拟主机 (实际上可能不是虚拟主机), 会在 sites-enabled 文件夹中创建一个链接连回到 sites-available 设置档。 |
2 | a2ensite (激活) 就是将站台 (.conf) 在 sites-enabled 的目录中创建链接,a2dissite (不激活) 则是删除该链接。
|
apache 会读取激活的每个 .conf (组态档),可以分散不同文件或者集中一个文件,实务上会将每个站台区分出不同的文件。
<Directory /var/www/$site>
Include /var/www/$site/.htaccess (1)
AllowOverride None (1)
...
</Directory>
1 | cms 大多会提供 .htaccess 文件,将 $site 站台安装的路径纳入该文件。
|
Apache 问题集
# 测试配置是否正确
sudo apachectl configtest
如果服务器受到 AH00558 影响,则应该收到类似以下的输出:
AH00558: apache2: Could not reliably determine the server’s fully qualified domain name, using 192.168.1.2. Set the 'ServerName' directive globally to suppress this message
Syntax OK
AH00558 主要用于提供消息,并不会影响 Apache 正常运行。
在消息中已说明「apache 无法使用 192.168.1.2 确定服务器的 FQDN (完整网域名称),全局设置 ServerName 以禁止显示此消息。」
ServerName 127.0.0.1
sudo bash -c "echo ServerName 127.0.0.1 >> /etc/apache2/apache2.conf"
# 检查一下加入的情况
tail /etc/apache2/apache2.conf
# 再次测试配置是否正确,应该没有 AH00558 的消息。
sudo apachectl configtest
# Syntax OK
PHP
apt-cache search php7.3
# Ubuntu16 / Ubuntu18 没有 php7.3
# 安装 repository
sudo apt install software-properties-common -y
sudo add-apt-repository ppa:ondrej/php -y
sudo apt update && sudo apt upgrade -y
# 安装 php 7.3
sudo apt install libapache2-mod-php7.3 php7.3-common php7.3-mbstring php7.3-soap \
php7.3-gd php7.3-xml php7.3-mysql php7.3-cli php7.3-curl php7.3-fpm -y
# 安装 zip unzip 及 php-zip 模块 (php-zip 应该已经安装了,再次安装并无问题)
sudo apt install zip unzip php-zip -y
# 检查 php 模块
php -m
phpini=/etc/php/7.3/apache2/php.ini
# 先检查一下原始设置
grep -E \
'output_buffering =|'\
'post_max_size =|'\
'upload_max_filesize =' \
$phpini
# 以 sed 改设置值并检查 (尚未存盘)
sed -r '
s/output_buffering =.*/output_buffering = Off/
s/post_max_size =.*/post_max_size = 24M/
s/upload_max_filesize =.*/upload_max_filesize = 16M/
' $phpini | grep -E \
'output_buffering =|'\
'post_max_size =|'\
'upload_max_filesize ='
# output_buffering = Off
# post_max_size = 24M
# upload_max_filesize = 16M
# 没有问题则直接修改 php.ini 文件
sudo sed -r -i '
s/output_buffering =.*/output_buffering = Off/
s/post_max_size =.*/post_max_size = 24M/
s/upload_max_filesize =.*/upload_max_filesize = 16M/
' $phpini
安装 MySQL (MariaDB)
sudo apt -y install mariadb-server mariadb-client mysql --version # mysql Ver 15.1 Distrib 10.0.36-MariaDB, for debian-linux-gnu (x86_64) using readline 5.2 # 查看状态 systemctl status mysql # ● mariadb.service - MariaDB 10.1.44 database server # Loaded: loaded (/lib/systemd/system/mariadb.service; enabled; vendor preset: enabled) # Active: active (running) since Tue 2020-09-29 14:30:58 CST; 32s ago # Docs: man:mysqld(8) # 检查开机是否自动启动 # 事实上前面 enabled 已得知是自动启动 systemctl list-unit-files --state=enabled | grep mysql # mysql.service enabled # mysqld.service enabled
mysql --help Usage: mysql [OPTIONS] [database] -B, --batch Don't use history file. Disable interactive behavior. (Enables --silent.) -N, --skip-column-names Don't write column names in results. -D, --database=name Database to use. -p, --password[=name] Password to use when connecting to server. If password is not given it's asked from the tty. -P, --port=# Port number to use for connection or 0 for default to, in order of preference, my.cnf, $MYSQL_TCP_PORT, /etc/services, built-in default (3306). --protocol=name The protocol to use for connection (tcp, socket, pipe, memory).
select plugin from user where user='root'; +-----------------------+ | plugin | +-----------------------+ | mysql_native_password | +-----------------------+
-N
+-----------------------+ | mysql_native_password | +-----------------------+
-B
plugin mysql_native_password
-B -N
mysql_native_password
sudo mysql_secure_installation
设置 MySQL root 密码,之后的其他选项都是 y Change the root password? [Y/n] y New password: Re-enter new password: - Set root password? [Y/n] y - Remove anonymous users? [Y/n] y - Disallow root login remotely? [Y/n] y - Remove test database and access to it? [Y/n] y - Reload privilege tables now? [Y/n] y
sudo mysql (1)
1 | 那前面是做什么东东? 原来要改为原生密码,才会以密码认证。 |
use mysql;
select plugin from user where user='root';
-- unix_socket
update user set plugin='mysql_native_password' where user='root';
flush privileges;
exit
mysqlpw='MySQL root 密码' (1)
mysql -uroot -p$mysqlpw --host=localhost --port=3306 --protocol=tcp
1 | mysqlpw 设置为 MySQL root 密码。 |
-- 查看时间
select now();
-- 如果不对则改时区
set global time_zone = '+8:00';
-- 事实上这里只是连接阶段, 前面才是全局修改.
set time_zone = '+8:00';
select timediff(now(), utc_timestamp);
-- 08:00:00
flush privileges;
exit
sudo mysql -N <<EOF (1)
use mysql;
update user set plugin='mysql_native_password' where user='root';
set global time_zone = '+8:00';
set time_zone = '+8:00';
flush privileges;
select plugin from user where user='root';
select timediff(now(), utc_timestamp);
EOF
1 | 若已经改成 mysql_native_password,则本行必须为 mysql -uroot -p$mysqlpw --host=localhost --port=3306 --protocol=tcp -N <<EOF |
若需要更多 MySQL 相关数据请参阅:创建多实例的 MariaDB。
mysqldump
mysqldump -u<user> -p<password> --host=localhost --port=3306 <database> -B > <database>.sql
<user> 导出数据库的帐户 <password> 导出数据库的帐户密码 <database> 导出的数据库 -B, --databases 导出的 SQL 包含创建数据库。 --lock-all-tables 导出时锁定所有数据库中的所有表,为默认值。 --add-drop-database 导出的 SQL 包含删除数据库。
/*!40000 DROP DATABASE IF EXISTS `mydb`*/; (1)
1 | 当 Mysql 的版本大于 4,这个 SQL 会被运行,这个 SQL 语句不是注解,而是可以运行的语句。 |
phpMyAdmin
sudo apt install phpmyadmin -y
sudo update-alternatives --config php
即然是全新安装,那就装新版的吧,在
phpMyAdmin - Downloads 查找版本及文件 url。
建议 4.x 版,下载后解压至 /usr/share/phpmyadmin。
# 先将 phpmyadmin 改名为 phpmyadmin.bak
sudo mv /usr/share/phpmyadmin /usr/share/phpmyadmin.bak
sudo mkdir /usr/share/phpmyadmin
myAdminVersion=4.9.7
cd ~
wget https://files.phpmyadmin.net/phpMyAdmin/$myAdminVersion/phpMyAdmin-$myAdminVersion-all-languages.tar.gz
sudo tar xzf phpMyAdmin-$myAdminVersion-all-languages.tar.gz
sudo mv phpMyAdmin-$myAdminVersion-all-languages/* /usr/share/phpmyadmin
sudo rm phpMyAdmin-$myAdminVersion-all-languages -r
# 拷贝原始的 config.inc.php
# sudo cp /usr/share/phpmyadmin.bak/config.inc.php /usr/share/phpmyadmin/config.inc.php
# 安装后可删除, 现在删除也行.
# sudo rm /usr/share/phpmyadmin.bak -r
# rm ~/phpMyAdmin-$myAdminVersion-all-languages.tar.gz
sudo bash -c 'cat > /etc/apache2/sites-available/phpmyadmin.conf' << "EOF"
<Directory /usr/share/phpmyadmin>
Require ip 192.168.1.1/255.255.255.0(1)
</Directory>
Include /etc/phpmyadmin/apache.conf
EOF
sudo a2ensite phpmyadmin
sudo systemctl reload apache2
1 | 依实际内部网络修改。 |
注: 当建置完成后 phpMyAdmin 网页为 http://<site>/phpmyadmin/
unix_socket 建置 phpMyAdmin 保存空间
phpMyAdmin 在建置过程中,创建 phpMyAdmin 保存空间 (数据库) 及权限 MySQL root 必须为 unix_socket
不支持 mysql_native_password,并且没有输入 MySQL root 密码的功能。
可直接采用 bash 建置 phpMyAdmin 保存空间,直接建置 phpMyAdmin 保存空间。
# 以 mysql_native_password 登录,改成 unix_socket
mysql -uroot -p$mysqlpw --host=localhost --port=3306 --protocol=tcp -N<<EOF
use mysql;
update user set plugin='unix_socket' where user='root'; (1)
flush privileges;
select plugin from user where user='root';
EOF
# 设置 phpMyAdmin
sudo dpkg-reconfigure phpmyadmin (2)
# 以 unix_socket 登录,改成 mysql_native_password
sudo mysql -N<<EOF
use mysql;
update user set plugin='mysql_native_password' where user='root'; (3)
flush privileges;
select plugin from user where user='root';
EOF
1 | 改为 unix_socket 类型,让 phpMyAdmin 建置程序,能以无密码的方式创建数据库及帐户权限。 |
2 | 按后文「设置 phpMyAdmin」建置。 |
3 | 改回原来的 mysql_native_password 类型。否则 http://<site>/phpmyadmin/index.php 登录 root 会出现下列错误。 mysqli_real_connect(): (HY000/1698): Access denied for user 'root'@'localhost' |
设置 phpMyAdmin
bash 建置 phpMyAdmin 保存空间
# 安装 phpmyadmin 保存空间 (注: Salve port 为 3307)
mysql -uroot -p$mysqlpw --host=localhost --port=3306 --protocol=tcp \
< /usr/share/phpmyadmin/sql/create_tables.sql
# 创建 phpmyadmin 用户并设置密码 (Salve 不需要创建 phpmyadmin 用户)
phpmyadminpw='password' (1)
mysql -uroot -p$mysqlpw --host=localhost --port=3306 --protocol=tcp -e \
"grant all privileges on phpmyadmin.* to 'phpmyadmin'@'localhost' identified by '$phpmyadminpw'";
1 | 设置 phpmyadmin 密码 |
$dbuser=''; (1)
$dbpass=''; (2)
$basepath='';
$dbname='phpmyadmin';
$dbserver='localhost';
$dbport='3306';
$dbtype='mysql';
1 | 改为 dbuser='phpmyadmin'; |
2 | 改为 $dbpass='password',即为前述的 phpmyadminpw; |
phpMyAdmin 问题集
- 解决「设置文件需要设置加密密码(blowfish_secret)。」
-
# 拷贝 config.sample.inc.php 至 config.inc.php sudo cp /usr/share/phpmyadmin/config.sample.inc.php /usr/share/phpmyadmin/config.inc.php sudo nano /usr/share/phpmyadmin/config.inc.php
修改 config.inc.php 内容$cfg['blowfish_secret'] = '';(1)
1 找出该行,任意输入32个字符即可如 d7eiDJ32jkdk8kd08983kDSJD37532aj
- 解决「无法访问 $cfg['TempDir'] (./tmp/)。phpMyAdmin 会无法缓存模版,并且会因为此原因变得很慢。」
-
sudo mkdir /usr/share/phpmyadmin/tmp sudo chmod 777 /usr/share/phpmyadmin/tmp
- 尚未设置 phpMyAdmin 设置保存空间,部份延伸功能将无法使用。
-
可参考「bash 建置 phpMyAdmin 保存空间」,如果是 Salve 只需安装 phpmyadmin 保存空间 (数据库),不需要创建 phpmyadmin 帐户, 记得 --port=3306 要改为 --port=3307。
www 目录维护
/var/www
拥有者为www-data
-
在一般情况 Windows 帐户会拷贝文件,为了拥有者一致 samba 的 Linux 帐户也为 www-data, 另外 rsync 以 root 帐户发送时可一并同步拥有者;或以参数 (chmod、chown) 明确设置拥有者。
ubuntu 归属于 www-data 群组,当 ubuntu 登录主机时,才能修改 www-data 的文件,/var/www
权限设置为 775 让群组成员能写入。不过当 ubuntu 添加文件后,如果为站台使用则拥有者需改为 www-data。但这有例外情况,如 drupal 会改变某些文件的群组权为唯读 (555),需调整为 775。
sudo su -l www-data -s /bin/bash
- 但如果该系统为测试系统,可按下列将 www-data 激活登录功能
-
列出 www-data 的情况: grep www-data /etc/passwd www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin 帐户的主目录为 /var/www,未激活登录 比对 root 帐户: grep root /etc/passwd root:x:0:0:root:/root:/bin/bash 帐户 root 的主目录为 /root,激活登录。
设置 www-data 登录功能sudo passwd www-data # 输入 www-data 密码 sudo chsh -s /bin/bash www-data (1) sudo gpasswd -a www-data sudo (2)
1 改变 www-data 的 login shell,激活登录功能。 2 www-data 加入 sudo 群组 列出 www-data 修改后的情况: grep www-data /etc/passwd www-data:x:33:33:www-data:/var/www:/bin/bash
拷贝 bash 登录设置档测试登录没有问题: sudo su www-data 拷贝 bash 登录设置档: cp /etc/skel/.profile ~ cp /etc/skel/.bash* ~ source ~/.bashrc
grep www-data /etc/passwd # www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin # 设置 www-data 密码 sudo passwd www-data # 改变 www-data login shell sudo chsh -s /bin/bash www-data # www-data 加入 sudo 群组 sudo gpasswd -a www-data sudo grep www-data /etc/passwd # www-data:x:33:33:www-data:/var/www:/bin/bash # 测试登录没有问题 sudo su www-data # 拷贝 bash 登录设置档 cp /etc/skel/.profile ~ cp /etc/skel/.bash* ~ source ~/.bashrc
- 为什么不采用 www-data 作为维护者
-
主要是为安全性考虑,维护者往往需要运行
sudo
,如果是免密码,风险有点高。
# 列出 www-data 成员
grep www-data /etc/group
# 将 ubuntu 加入 www-data 群组
sudo gpasswd -a ubuntu www-data
# 需要重新登录
sudo sh -c "chown -R www-data:www-data /var/www; chmod -Rf 775 /var/www" (1)
mkdir /var/www/bin (2)
nano ~/.bashrc
1 | 刚开始的 /var/www 的 拥有者为 root,先改变成 www-data。 |
2 | 需要重新登录 /var/www 才能写入。 |
export PATH="/var/www/bin:$PATH"
source ~/.bashrc
增加一个简单的脚本,修正 /var/www 的拥有者,如建置网站目录是由 ubuntu 来创建,创建后改变拥有者为 www-data, 另外 Drupal 会改变某些文件的群组权为唯读 (r--:4),也重设为可读取 (rwx:7)。
# ubuntu@host:$
mkdir /var/www/bin (1)
bash -c 'cat > /var/www/bin/chwww' << "EOF"
#!/bin/bash -e
if [ "$1" = "" ]; then
WorkPath='/var/www'
else
WorkPath=$(readlink -f $1)
fi
if [ ! -d $WorkPath ]; then
WorkPath=/var/www/$1
fi
WorkPath=$(readlink -f $WorkPath)
if [ $WorkPath != '/var/www' ] && [ ${WorkPath:0:9} != '/var/www/' ]; then
echo $WorkPath 'is not site directory!'
exit 1
fi
if [ ! -d $WorkPath ]; then
echo 'No such directory' $WorkPath
exit 1
fi
if [ "$WorkPath" == "/var/www" ]; then
read -p "Change the owner and mode of all /var/www? [Y/n] " yn
yn=${yn:-y}
if [ "$yn" != "Y" ] && [ "$yn" != "y" ]; then
exit 1
fi
fi
echo 'chown & chmod:' $WorkPath
sudo sh -c "chown -R www-data:www-data $WorkPath; chmod -Rf 775 $WorkPath" (2)
if [ "$WorkPath" == "/var/www" ] && [ -d "/var/www/.ssh" ]; then
echo 'chmod: .ssh'
set +e
chmod go-w ~/
chmod -R 700 /var/www/.ssh
chmod 600 /var/www/.ssh/authorized_keys
chmod 600 /var/www/.ssh/config
fi
EOF
sudo chmod +x /var/www/bin/chwww
1 | 将站台维护的指令档或连接档,集中在 /var/www/bin,记得将该目录加入 PATH。 |
2 | script 运行 sudo 需设置 运行 sudo 免密码, |