好了,经过前面的尝试,我已经有了一个可以运行的nginx了,这还挺开心的,现在只要我有源码,就可以构建出nginx
,然后放到一台机器里运行web服务了。接下来就开始配置nginx来运行web服务。
首先,我贴出最基本的目录,这是一个开始:
1
2
3
4
5
6
7
8
9
liuxu:test$ tree
.
├── conf
│ └── nginx.conf
├── logs
│ └── error.log
└── nginx
2 directories, 5 files
这是一个基本目录情况,nginx
在当前目录,与它同级的是conf/
和logs/
,这些目录在编译时都是可改的,只是目前我用最简编译是这个目录结构。
然后配置conf/nginx.conf
:
1
2
3
4
5
6
7
liuxu:test$ cat conf/nginx.conf
events{}
http {
server {
}
}
很简单,event{}
是nginx强制需要配置的。然后我需要运行的是http服务器,所以有了http{}
。然后在http里面添加一个server{}
,表示配置一台服务器。如果需要多台服务器,就添加多个server{}
就好了,很简单的。
现在我们运行一下,看看能不能运行:
1
2
3
4
5
6
7
8
9
10
11
12
liuxu:test$ ./nginx -p .
liuxu:test$ ps aux | grep nginx
liuxu 15072 0.0 0.0 14288 332 ? Ss 17:27 0:00 nginx: master process ./nginx -p .
liuxu 15073 0.0 0.0 14452 1240 ? S 17:27 0:00 nginx: worker process
liuxu 15130 0.0 0.0 21536 1092 pts/1 R+ 17:28 0:00 grep --color=auto nginx
liuxu:test$ ss -anpt | grep nginx
LISTEN 0 128 0.0.0.0:8000 0.0.0.0:* users:(("nginx",pid=15073,fd=6),("nginx",pid=15072,fd=6))
liuxu:test$./nginx -p . -s stop
liuxu:test$ sudo ./nginx -p .
liuxu:test$ sudo ss -anpt | grep nginx
LISTEN 0 128 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=16202,fd=6),("nginx",pid=16201,fd=6))
liuxu:test$ sudo ./nginx -p . -s stop
好了,就这么运行起来了,只有一个nginx主进程和一个工作进程,但足够了,可以运行网站了。工作进程默认监听0.0.0.0:8000
,表示监听本机所有地址,所有地址就是即监听本机127.0.0.1
,如果有其他ip,也会监听,例如我还有个局域网ip192.168.1.155
,用这两个地址都能访问我的web服务器。默认监听端口是8000
,但是如果你是root权限,会默认监听80
端口,就像用sudo
执行的时候那样。现在我们来访问一下看看。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
liuxu:test$ curl http://localhost:8000/
<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.14.0</center>
</body>
</html
liuxu:test$ curl http://192.168.1.155:8000/
<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.14.0</center>
</body>
</html>
liuxu:test$ curl http://192.168.1.155:7000/
curl: (7) Failed to connect to 192.168.1.155 port 7000: Connection refused
看,成功返回404了,代表访问服务器成功,但是没有找到内容,当然找不到,因为我们根本就没有设置任何内容用于返回。最后一次访问没有监听的7000端口,所以会返回连接被拒绝,这代表没有服务监听7000端口。
现在为了在访问网站时去掉后面的:8000
,我们让服务器一直监听80
端口。在我们访问网站的时候,例如http://www.liuquanhao.com/
,其实访问的是http://www.liuquanhao.com:80/
,因为http默认是80端口,所以我们平时可以省略,浏览器会自动访问服务器80端口。顺便说一下,如果访问的网站是https
的,那么会默认访问服务器的443
端口,这个https服务器需要额外配置。
好了,我们来配置监听80端口:
1
2
3
4
5
6
7
8
liuxu:test$ cat conf/nginx.conf
events{}
http {
server {
listen 80;
}
}
贼简单,就一个listen 80;
就可以了,表示监听本机所有地址的80端口。listen
表示监听地址和端口,例如写listen 127.0.0.1:80
,表示监听本机回环地址127.0.0.1
,监听端口80
。;
表示指令结束。
现在重新访问看看:
1
2
3
4
5
6
7
8
9
10
11
liuxu:test$ ./nginx -p . -s stop
liuxu:test$ ./nginx -p .
nginx: [emerg] bind() to 0.0.0.0:80 failed (13: Permission denied)
liuxu:test$ sudo ./nginx -p .
liuxu:test$ ps aux | grep nginx
root 16966 0.0 0.0 22744 368 ? Ss 18:02 0:00 nginx: master process ./nginx -p .
nobody 16967 0.0 0.0 27288 2692 ? S 18:02 0:00 nginx: worker process
liuxu 16969 0.0 0.0 21536 1012 pts/1 S+ 18:02 0:00 grep --color=auto nginx
liuxu:test$ ss -anpt | grep nginx
liuxu:test$ sudo ss -anpt | grep nginx
LISTEN 0 128 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=16967,fd=6),("nginx",pid=16966,fd=6))
因为linux服务器中小于等于1024的端口需要root权限才能使用,所以如果nginx配置监听80端口,普通用户权限是无法启动的,需要用sudo命令或root账户才能启动。
现在访问看看:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
liuxu:test$ curl http://127.0.0.1:80/
<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.14.0</center>
</body>
</html>
liuxu:test$ curl http://127.0.0.1/
<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.14.0</center>
</body>
</html>
liuxu:test$ curl http://192.168.1.155/
<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.14.0</center>
</body>
</html>
很愉快,运行成功了。但是很不开心,都是404,我想弄点东西输出,所以我开始配置一下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
liuxu:test$ mkdir html
liuxu:test$ echo "liuquanhao is best." > html/index.html
liuxu:test$ sudo tree
.
├── client_body_temp
├── conf
│ └── nginx.conf
├── fastcgi_temp
├── html
│ └── index.html
├── logs
│ ├── access.log
│ ├── error.log
│ └── nginx.pid
├── nginx
├── proxy_temp
├── scgi_temp
└── uwsgi_temp
liuxu:test$ curl http://127.0.0.1/
liuquanhao is best.
那些..._temp
都是nginx运行时生成的,不用管它们。因为nginx默认将网页放在工作目录下的html/
目录中,所以我新建了html目录。而我们访问一个域名,而且以/
结尾的时候,其实访问的时/index.html
,例如我访问http://www.liuquanhao.com/
,其实访问的是http://www.liuquanhao.com/index.html
,这个可以用nginx服务器设置,将默认访问的网页改为别的。可以看到,我访问成功了。
到现在为止,基本上一个网站已经可以放到html/
,然后到弄一台有外网ip的服务器运行了,但是目前我们都是用ip地址访问的网站,不专业,现在就配置用域名来访问。
1
2
3
4
5
6
7
8
9
10
11
12
13
liuxu:test$ cat conf/nginx.conf
events{}
http {
server {
listen 80 default_server;
return 404;
}
server {
listen 80;
server_name haha.ooo;
}
}
很简单,添加了一个server_name haha.ooo;
,这样就可以用http://haha.ooo/
这个域名访问了。它的工作原理是这样:首先用浏览器访问这个网站,会提交http请求信息,里面包含Host: xxxx
,例如访问的是http://127.0.0.1/
,Host就是Host: 127.0.0.1
,用http://haha.ooo/
访问,Host就是Host: haha.ooo
。当服务器收到请求的时候,会分析这个Host,用来匹配server_name
配置的域名,匹配上了就说明访问的是这个server{}
服务器。如果没匹配到,nginx就把这个请求导向一台默认服务器上,这个默认服务器是这个请求中端口下的默认服务器。这里是80,所以80下有一台默认默认服务器,如果配置里没设置,就是第一个server{}
,或者可以自己设置一个server{}
,里面添加listen 80 default_server;
,这个default_server
关键字就是设定当前所在server{}
是listen中端口下的默认服务器。我这里设置了默认服务器直接返回404,也就是如果不是访问haha.ooo
这个域名的服务器都访问默认服务器,默认服务器会直接返回404错误给你。
为了在本机测试,需要先修改/etc/hosts
配置,将haha.ooo
这个域名指向127.0.0.1
:
1
2
3
4
liuxu:test$ cat /etc/hosts
127.0.0.1 localhost
127.0.0.1 haha.ooo
可以看到,我把127.0.0.1 haha.ooo
添加到了/etc/hosts
中,里面还有个127.0.0.1 localhost
是默认存在的,现在我们可以测试一下了。
1
2
3
4
5
liuxu:test$ sudo ./nginx -p . -s stop
liuxu:test$ sudo ./nginx -p .
liuxu:test$ ss -anpt | grep nginx
liuxu:test$ sudo ss -anpt | grep nginx
LISTEN 0 128 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=22680,fd=6),("nginx",pid=22679,fd=6))
nginx启动成功。
1
2
3
4
5
6
7
8
liuxu:test$ ping haha.ooo
PING haha.ooo (127.0.0.1) 56(84) bytes of data.
64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.018 ms
64 bytes from localhost (127.0.0.1): icmp_seq=2 ttl=64 time=0.046 ms
^C
--- haha.ooo ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1007ms
rtt min/avg/max/mdev = 0.018/0.032/0.046/0.014 ms
haha.ooo
这个域名指向了127.0.0.1
这个ip。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
liuxu:test$ curl -lv http://haha.ooo/
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to haha.ooo (127.0.0.1) port 80 (#0)
> GET / HTTP/1.1
> Host: haha.ooo
> User-Agent: curl/7.58.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: nginx/1.14.0
< Date: Wed, 11 Jul 2018 11:50:05 GMT
< Content-Type: text/html
< Content-Length: 20
< Last-Modified: Wed, 11 Jul 2018 10:10:50 GMT
< Connection: keep-alive
< ETag: "5b45d7aa-14"
< Accept-Ranges: bytes
<
liuquanhao is best.
* Connection #0 to host haha.ooo left intact
haha.ooo
访问成功。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
liuxu:test$ curl -lv http://127.0.0.1/
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 80 (#0)
> GET / HTTP/1.1
> Host: 127.0.0.1
> User-Agent: curl/7.58.0
> Accept: */*
>
< HTTP/1.1 404 Not Found
< Server: nginx/1.14.0
< Date: Wed, 11 Jul 2018 11:50:10 GMT
< Content-Type: text/html
< Content-Length: 169
< Connection: keep-alive
<
<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.14.0</center>
</body>
</html>
* Connection #0 to host 127.0.0.1 left intact
liuxu:test$ curl -lv http://localhost/
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 80 (#0)
> GET / HTTP/1.1
> Host: localhost
> User-Agent: curl/7.58.0
> Accept: */*
>
< HTTP/1.1 404 Not Found
< Server: nginx/1.14.0
< Date: Wed, 11 Jul 2018 11:50:17 GMT
< Content-Type: text/html
< Content-Length: 169
< Connection: keep-alive
<
<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.14.0</center>
</body>
</html>
* Connection #0 to host localhost left intact
其他域名和ip访问服务器返回默认服务器返回的404。
这里额外解释一下http请求:
1
2
3
4
5
6
liuxu:test$ curl -lv http://127.0.0.1/
...
* Connected to haha.ooo (127.0.0.1) port 80 (#0)
> GET / HTTP/1.1
> Host: haha.ooo
...
在请求里我们看到有这一段,可以看见我们访问的是http://127.0.0.1/
。就像前面说的,当访问http
的网站时,默认时访问80端口,这里就可以看见* Connected to haha.ooo (127.0.0.1) port 80 (#0)
,访问80端口。接着是> GET / HTTP/1.1
,代表获取/
这个目录,服务器看到这个/
后,会返回当前server{}
默认的html目录下的index.html
文件。接着是> Host: haha.ooo
,这就是请求头的Host,服务器拿到这个后,会匹配自己server{}
中配置的server_name
。
下面在看一个请求:http://haha.ooo
,最后面没有/
,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
liuxu:test$ curl -lv http://haha.ooo
* Rebuilt URL to: http://haha.ooo/
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to haha.ooo (127.0.0.1) port 80 (#0)
> GET / HTTP/1.1
> Host: haha.ooo
> User-Agent: curl/7.58.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: nginx/1.14.0
< Date: Wed, 11 Jul 2018 11:57:03 GMT
< Content-Type: text/html
< Content-Length: 20
< Last-Modified: Wed, 11 Jul 2018 10:10:50 GMT
< Connection: keep-alive
< ETag: "5b45d7aa-14"
< Accept-Ranges: bytes
<
liuquanhao is best.
* Connection #0 to host haha.ooo left intact
可以看到* Rebuilt URL to: http://haha.ooo/
,curl或者浏览器会自己在后面添加/
。
好了,现在只需要把网页放到html/
下,就可以放线上运行了。那就玩真格的,我买了一台服务器,现在把/etc/host
中的127.0.0.1 haha.ooo
这条记录删了,然后在域名解析里配置一条A记录到我的服务器。
然后我重新在我的服务器编译一次,以为系统环境依赖版本有些不一致,我电脑编译的在服务器里不一定能运行。
因为我的服务器运行的是centos,为了编译nginx,依然是需要先安装编译环境,下载nginx和pcre源码包,然后解压编译:
1
2
3
4
5
6
7
8
9
[root@YUN83222144 ~]# yum -y groupinstall "Development Tools"
[root@YUN83222144 ~]# yum -y install zlib-devel
[root@YUN83222144 ~]# wget http://nginx.org/download/nginx-1.14.0.tar.gz
[root@YUN83222144 ~]# wget https://ftp.pcre.org/pub/pcre/pcre-8.41.tar.bz2
[root@YUN83222144 ~]# tar -xvf nginx-1.14.0.tar.gz
[root@YUN83222144 ~]# tar -xvf pcre-8.41.tar.bz2
[root@YUN83222144 ~]# cd nginx-1.14.0
[root@YUN83222144 nginx-1.14.0]# ./configure --with-pcre=../pcre-8.41
[root@YUN83222144 nginx-1.14.0]# make
然后新建一个server目录,把编译好的nginx
放进去,然后配置好目录必须的文件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[root@YUN83222144 server]# pwd
/root/server
[root@YUN83222144 server]# tree
.
├── conf
│ └── nginx.conf
├── html
│ └── index.html
├── logs
└── nginx
4 directories, 4 files
[root@YUN83222144 server]# cat html/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>哈哈,哦哦哦</title>
</head>
<body>
<p>liuquanhao is best.</p>
<body>
</html>
还有一点,有些服务器默认开了防火墙,会阻挡ssh以外的所有端口,http的80也被阻挡了,所以即使运行了nginx也无法用你的电脑通过浏览器访问,这个时候需要添加端口,具体的方法要看你的iptables还是firewalld,你需要配置好。如果你是阿里云或者aws之类的云服务,可能还需要在云管理平台为你的server添加对应网络规则。我的是firewalld,所以看看我的环境:
1
2
3
4
5
[root@YUN83222144 server]# firewall-cmd --state
running
[root@YUN83222144 server]# firewall-cmd --get-active-zones
public
interfaces: eth0
我服务器的firewalld正在运行,zone是public环境。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[root@YUN83222144 server]# firewall-cmd --info-zone=public
public (active)
target: default
icmp-block-inversion: no
interfaces: eth0
sources:
services: ssh dhcpv6-client http
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
[root@YUN83222144 server]# firewall-cmd --info-service=http
http
ports: 80/tcp
protocols:
source-ports:
modules:
destination:
我的public里面已经添加了http这个service,它配置了80/tcp
端口,就是http端口。
好了,现在打开nginx服务器:
1
2
3
[root@YUN83222144 server]# ./nginx -p .
[root@YUN83222144 server]# ss -anpt | grep nginx
LISTEN 0 128 *:80 *:* users:(("nginx",pid=18474,fd=6),("nginx",pid=18473,fd=6))
现在用浏览器访问http://haha.ooo/
,访问成功。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
liuxu:~$ curl -lv http://haha.ooo/
* Trying 181.xxx.xxx.xxx...
* TCP_NODELAY set
* Connected to haha.ooo (181.xxx.xxx.xxx) port 80 (#0)
> GET / HTTP/1.1
> Host: haha.ooo
> User-Agent: curl/7.58.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: nginx/1.14.0
< Date: Thu, 12 Jul 2018 02:36:12 GMT
< Content-Type: text/html
< Content-Length: 147
< Last-Modified: Thu, 12 Jul 2018 02:35:38 GMT
< Connection: keep-alive
< ETag: "5b46be7a-93"
< Accept-Ranges: bytes
<
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>哈哈,哦哦哦</title>
</head>
<body>
<p>liuquanhao is best.</p>
<body>
</html>
* Connection #0 to host haha.ooo left intact