个人网站搭建教程
目录:
最近尝试用Apache搭建个人网站,记录一下过程。本文中所有需要替换的内容都用<>括起来,读者可以搜索>'和>"来查找需要替换的内容。
由于完整代码包含私钥等敏感信息,恕不提供。
sed命令
替换文件中的字符串
支持正则表达式
sed --in-place 's/old/new/[option]' file
sed -i 's/old/new/[option]' file
option:
g:全局替换i:忽略大小写p:打印替换的行
范围替换
sed --in-place '/start/,/end/s/old/new/g' file
sed --in-place '10,20s/old/new/g' file
删除文件中的字符串
sed --in-place '/pattern/d' file
查看文件中的字符串
sed --quiet '/pattern/p' file
过滤输出
替换输出内容
echo "hello world" | sed 's/hello/hi/'
删除包含pattern的行
echo -e "hello\nworld" | sed '/hello/d'
只输出包含pattern的行
echo -e "hello\nworld" | sed --quiet '/hello/p'
更新并安装应用
由于PHP依赖Apache2和Git(?),所以第三行命令事实上可以改为sudo apt-get install php mysql-server --assume-yes --quiet。
sudo apt-get update
sudo apt-get upgrade --assume-yes --quiet
# 安装Apache2、PHP、MySQL、Git
sudo apt-get install apache2 php mysql-server git --assume-yes --quiet
# 安装php插件
sudo apt-get install php-mysql php-mbstring php-gd --assume-yes --quiet
配置HTTP服务器
修改PHP配置文件
short_open_tag配置项默认为Off,修改为On,以便支持<?标签作为<?php的简写。
详见PHP配置文件。
打开配置项short_open_tag(位于/etc/php/8.1/apache2/php.ini文件)
sudo sed --in-place 's/^short_open_tag = Off$/short_open_tag = On/g' /etc/php/8.1/apache2/php.ini
查看配置项short_open_tag是否修改成功
sed --quiet '/^short_open_tag/p' /etc/php/8.1/apache2/php.ini
修改APACHE2配置文件
启用rewrite模块
rewrite模块用来配置伪静态规则,详见Apaceh RewriteRule。
更详细的介绍请见mod_rewrite参考手册和mod_rewrite入门。
启用rewrite模块。使用--relative选项创建相对路径的软链接。
sudo ln --symbolic --relative /etc/apache2/mods-available/rewrite.load /etc/apache2/mods-enabled/rewrite.load
或者使用a2enmod命令:
sudo a2enmod rewrite
修改apache2.conf文件
修改apache2.conf文件,允许/var/www/html目录下的.htaccess文件覆盖默认配置,并禁止列出目录内容。
原来的配置文件长这样:
<Directory /var/www/>
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>
修改后的配置文件长这样:
<Directory /var/www/>
Options FollowSymLinks
AllowOverride All
Require all granted
</Directory>
修改apache2.conf文件
sudo sed --in-place '/<Directory \/var\/www\/>/,/<\/Directory>/s/Options Indexes FollowSymLinks/Options FollowSymLinks/' /etc/apache2/apache2.conf
sudo sed --in-place '/<Directory \/var\/www\/>/,/<\/Directory>/s/AllowOverride None/AllowOverride All/' /etc/apache2/apache2.conf
这里使用/pattern1/,/pattern2/表示只替换pattern1和pattern2之间的内容(局部替换)。
查看修改后的配置文件(<Directory /var/www/>部分)
sed --quiet '/<Directory \/var\/www\/>/,/<\/Directory>/p' /etc/apache2/apache2.conf
修改000-default.conf文件(可选)
修改000-default.conf文件,将DocumentRoot修改为/var/www/html/subdir。
sudo sed --in-place 's/DocumentRoot \/var\/www\/html/DocumentRoot \/var\/www\/html\/subdir/' /etc/apache2/sites-enabled/000-default.conf
查看配置文件中的DocumentRoot配置项
sed --quiet '/DocumentRoot/p' /etc/apache2/sites-enabled/000-default.conf
重启Apache
sudo /etc/init.d/apache2 restart
配置伪静态规则
因为允许.htaccess文件覆盖默认配置,所以可以在/var/www/html目录下创建.htaccess文件,添加伪静态规则,无需重启Apache。
RewriteEngine on
RewriteRule ^(Ue|app|config|install)/ - [F]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?s=$1 [L,QSA]
解释:
- 如果请求的URL是
Ue、app、config、install目录时,返回403错误; - 如果请求的URL对应的文件或目录不存在,将请求重写到
index.php文件。
另一种伪静态规则:
RewriteEngine on
RewriteBase "/"
RewriteRule ^(admin.php|index.php|assets)/ - [L]
RewriteRule ^(.*)$ /index.php?s=$1 [L,QSA]
解释:
- 如果请求的URL是
admin.php/index.php,则直接返回该文件或目录; - 如果请求的URL是
assets目录,直接返回该文件或目录; - 否则,将请求重写到
index.php文件(无论该URL对应的文件或目录是否存在)
修改/var/www/html目录权限
默认情况下,/var/www/html目录的所有者是root,这是为了保护网站的安全性,防止用户修改网站文件。
如果需要修改/var/www/html目录下的文件,有几种方法(越靠前越不推荐):
- 将网站的用户改为
root,这样就可以直接修改网站文件。因为root有权访问修改所有文件,如果网站以root身份访问文件系统,那么一旦Web服务器被破坏,它就能访问您的整个系统。本质上,我们通过指定身份是www-data而不是root,以保证即使Web服务器被破坏,它也只能完全访问其自己的文件,而不是整个服务器。 - 将
/var/www/html修改为777权限,这样所有用户都可以访问修改网站文件。这样做会导致网站不安全,任何用户都可以访问修改网站文件。 - 将
/var/www/html所有者改为网站用户,这样网站用户就可以访问修改网站文件,但是网站用户对该文件夹有完全的所有权,仍然可以任意访问修改网站文件,没有起到权限控制的作用。 - 将我本人加入
www-data组,将/var/www/html的所有者改为我本人,所有组改为www-data,这样我本人就可以访问修改网站文件,但是www-data组对该文件夹有完全的所有权,通过权限管理可以控制www-data允许查看和修改的文件。
我现在选择最后一种方案,但是权限管理上暂且偷懒了:除去部分文件设置了600权限(U=RW, G=, O=),其他文件设置了664权限(U=RW, G=RW, O=R),文件夹设置了775权限(U=RWX, G=RWX, O=RX)。
sudo usermod --append --groups www-data $USER # 将当前用户加入www-data组
sudo chown --verbose --recursive --from=root:root $USER:www-data /var/www/html # 将/var/www/html的所有者改为$USER, 所有组改为www-data
chmod --recursive g+w /var/www/html # 将/var/www/html的组权限改为可写。因为本来就是文件644,文件夹755,所以只需要加上组可写权限
ln --symbolic /var/www/html ~/html # 创建软链接~/html -> /var/www/html,方便平时访问
配置MySQL
创建数据库和用户
创建数据库web,创建用户web和当前用户,授权web和当前用户访问web数据库。
这里分开web用户和当前用户,是为了区分网站用户和和我本人,以便权限管理,并且也可以区分SQL命令来源。至于我本人为什么不用root用户,是因为root用户拥有最高权限,不适合用于日常操作。
sudo mysqladmin create web
sudo mysql -vvv --execute="CREATE USER 'web'@'localhost' IDENTIFIED BY '<password1>';"
sudo mysql -vvv --execute="CREATE USER '$USER'@'localhost' IDENTIFIED BY '<password2>';"
sudo mysql -vvv --execute="GRANT ALL PRIVILEGES ON web.* TO 'web'@'localhost';"
sudo mysql -vvv --execute="GRANT ALL PRIVILEGES ON web.* TO '$USER'@'localhost';"
sudo mysql -vvv --execute="FLUSH PRIVILEGES;"
命令解释:
- -v: 显示输入的sql语句
- -vv: 显示输入的sql语句和执行的结果(
Query OK, 0 rows affected) - -vvv: 像交互式一样显示结果(
Query OK, 0 rows affected (0.05 sec) Records: 0 Duplicates: 0 Warnings: 0
配置~/.my.cnf
配置~/.my.cnf文件,以便在命令行中不用输入密码就可以访问数据库。这里不配置user,这样默认使用当前用户访问数据库,并且使用sudo mysql命令访问数据库时,用户自动切换为root用户(反正root用户没有密码,设置password并不影响访问)。
一定要配置600权限,你也不想别人看到你的数据库密码吧。尤其这个“别人”还是一般网站访客。
echo "配置~/.my.cnf"
echo -e "[client]\npassword=<password2>" | tee ~/.my.cnf
echo -e "[mysql]\ndatabase = web\nshow-warnings\nsafe-updates\nbinary-as-hex" | tee --append ~/.my.cnf
# 设置权限
chmod 600 ~/.my.cnf
命令解释:
echo命令用于输出内容,-e选项用于解析转义字符(比如\n),以便输出多行内容tee命令用于将标准输入的内容写入文件,--append选项用于追加内容到文件末尾- show-warnings: 显示警告信息
- safe-updates: 禁止不带
WHERE子句的UPDATE和DELETE语句 - binary-as-hex: 以十六进制显示二进制数据
临时关闭safe-updates选项
mysql --safe-updates=0
配置Git
因为我选择使用SSH访问Git服务器,所以需要配置SSH密钥。别忘了设置600权限。
git config --global user.email "<email>"
git config --global user.name "<name>"
mkdir --parents ~/.ssh
cp --verbose "/mnt/d/install/git_ed25519" ~/.ssh/id_ed25519
find ~/.ssh -type f -exec chmod 600 {} \; -o -type d -exec chmod 700 {} \;
如果是远程服务器,可以使用scp命令上传密钥。
scp .\git_ed25519 <user>@<host>:~/.ssh/id_ed25519