记录我是如何搭建自己的一个服务器的。

目前服务器用途:参加比赛时需要使用一些服务(如PHP网页)。不定期更新。

部署

初始

在华为云购买了一台比较低配的弹性云,选了个弹性公网

配置免密登录(注意不要复制错了本地公钥),应该很简单,不赘述了。就把本机的 C 盘用户目录的生成好的 .ssh/id_rsa.pub 追加到服务器的 ~/.ssh/authorized_keys 即可

php
安装

使用 apt get php 不行 apt-get update--fix-missing 都不行,报错:

1
E: Failed to fetch http://repo.huaweicloud.com/ubuntu/pool/main/p/php7.4/php7.4_7.4.3-4ubuntu2.8_all.deb  404  Not Found [IP: 58.42.56.86 80]

百度,得知需要更换 DNS,于是找到 /etc/resolv.conf,修改一行为:

1
namespace 8.8.8.8

于是可以了。

安装:

1
2
apt install php
apt install libapache2-mod-php

发现有 apache2,但是输入指令后说:

1
[Thu Jun 30 14:39:22.807497 2022] [core:warn] [pid 12458] AH00111: Config variable ${APACHE_RUN_DIR} is not defined

经查,发现需要导入环境变量:

1
source /etc/apache2/envvars

测试访问,直接在本机浏览器输入 https://服务器IP地址/,发现有页面,证明 IP 地址可达,有权访问。在 /var/www/html/ 随便写了一个 PHP 页面 info.php,发现 https://服务器IP地址/info.php 正确。

POST测试

测试 POST,发现不行,http 协议报错:

1
No 'Access-Control-Allow-Origin' header is present on the requested resource

解决方案:对服务器代码,添加:

1
2
3
header("Access-Control-Allow-Origin:*");
/*星号表示所有的域都可以接受,*/
header("Access-Control-Allow-Methods:GET,POST");

如,进行测试(/var/www/html/test.php):

1
2
3
4
<?php
header("Access-Control-Allow-Origin:*");
header("Access-Control-Allow-Methods:GET,POST");
echo "Hello, ".$_POST['name'];

本机写一个 HTML,用 vscode 的 live 插件跑,发现正常:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="http://lib.sinaapp.com/js/jquery/1.9.1/jquery-1.9.1.min.js"></script>
<script>
function f() {
$.post("http://IP地址/test.php", {
name: 'lr580'
}, function(res) {
console.log(res);
});
}
</script>
</head>

<body>
<h1>这是一个主页</h1>
<div onclick="f();">点我</div>
</body>

</html>
php调python脚本

服务器自带 python,可以自行检查:

1
python3 --version

写一个简单 Python 程序调试:(/var/www/html/hello.py)

1
2
3
import sys
name = sys.argv[1]
print('Hi, %s'%name)

修改上文 test.php 最后一行为:

1
2
3
$param = $_POST['name'];
$res = exec("python3 hello.py $param");
echo $res;
mysql
安装
1
apt install mysql-server

经测试,发现直接输入 mysql 可以进入 CLI,证明安装成功。

配置远程连接

尝试设置一个用户,拥有所有权限,使得可以通过本地 mysql 访问:

1
2
create user lr580 identified by '密码'
grant all privileges on *.* to 'lr580'@'%'

好像不管用

增加防火墙:

1
/sbin/iptables -I INPUT -p tcp --dport 3306 -j ACCEPT

查看防火墙:

1
iptables -L -n

本地连接失败:

1
ERROR 2003 (HY000): Can't connect to MySQL server on 'IP地址:3306' (10060)

于是去华为云控制台改了一下安全组 ACL,允许了 3306。

然后变成了 10061。参考,解决方法 参考

修改配置文件:找到 /etc/init.d/mysql/my.cnf,发现找不到 bind-address,顺藤摸瓜在 !includedir 发现了 /etc/mysql/mysql.conf.d/mysqld.cnf 找到了,将其改为:

1
bind-address  = 0.0.0.0

至此发现可以成功访问,本地输入:

1
mysql -u lr580 -h IP地址 -p

输入密码后,成功进入到服务器。

PHP调用mysql

创建测试数据库:

1
2
3
4
5
6
7
create database cv;
use cv
create table foo (
name char(20) primary key,
secret char(32)
);
insert into foo values ('baicha', md5('123456'));

参考 这里。安装 PHP 的 mysql 插件:

1
2
apt-get install php-mysql
phpenmod mysqli

找到 php.ini 所在地,发现有一个是 /etc/php/7.4/apache2/php.ini

1
find / -name 'php.ini'

/etc/php/7.4/apache2/php.ini 修改,取消 extension=开头的mbstring,mysqli,pdo_mysql的注释。重启服务:

1
2
service apache2 restart
service mysql restart

建立测试 conn.php 文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
$dbname='cv';
$dbuser='lr580';
$dbpsw='密码';
$conn = new mysqli('localhost', $dbuser, $dbpsw, $dbname);
if($conn->connect_error)
{
die('Could not connect: ' . $conn->connect_error);
}
$result = $conn->query('select * from foo;');
while($row = $result->fetch_assoc()){
echo "\n".$row['name'].' says hey with '.$row['secret'].'to you.';//\n要在双引号才生效
}
$conn->close();

在上文 test.php 追加测试代码:

1
include "conn.php";

重新在本地进行测试,发现测试成功,正常输出数据。