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 免密碼, |