个人网站搭建教程
目录:
最近尝试用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