(此处省略300字前言…)
按如下结构建立文件夹:
1
2
3
4
5
6
7
8
9
10
11
12
├── mysql
│ └── conf.d // mysql配置文件目录
│ └── data // mysql数据目录
├── nginx
│ └── conf.d // nginx配置目录
│ └── ssl // ssl证书目录
│ └── logs // nginx日志文件目录
├── php-fpm
│ └── Dockerfile // php构建文件
│ └── typecho // typecho路径
│ └── blog // typecho站点,请解压typecho程序到此文件夹
├── docker-compose.yml
docker-compose.yml
先看看整体结构:
1
2
3
4
5
6
7
8
9
10
11
12
version : "2"
networks :
default :
external : false
name : app-tier
services :
mysql :
image : mysql:8.0
php-fpm :
build : ./php-fpm
nginx :
image : nginx:1.23.3-alpine
由上到下,三个部分:
version
指定此配置的版本,一般与 docker-compose 版本对应
networks
定义网络,如果多个容器都在同一个网络下,那么它们之间可以通过容器名互相访问,即 服务名:端口
代替 IP:端口
。这里定义了一个名为 app-tier
的默认网络
services
部分是定义服务,这里定义了 mysql
、php-fpm
、nginx
三个服务,下面分而述之。
mysql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
mysql :
image : mysql:8.0
container_name : mysql
restart : always
environment :
TZ : Asia/Shanghai
MYSQL_ROOT_PASSWORD : 12345678
ports :
- 4417 : 3306
volumes :
- ./mysql/data:/var/lib/mysql
- ./mysql/conf.d:/etc/mysql/conf.d
- ./mysql/init:/docker-entrypoint-initdb.d/
command :
- --character-set-server=utf8mb4
- --collation-server=utf8mb4_unicode_ci
networks :
- default
这里的 mysql
是服务名,也是容器名
image
是指定使用的镜像,通常格式:镜像名:版本号
;可以在 Docker Hub 上找到我们需要的镜像,这里我们使用的是 mysql:8.0
,也就是使用的是 mysql
的 8.0
版本。
container_name
是指定容器名,后续操作都是基于容器名的,这里指定为 mysql
restart
是指定容器重启策略,这里指定为 always
,也就是容器异常退出后,自动重启
environment
是指定环境变量,这里指定的 TZ
是时区,MYSQL_ROOT_PASSWORD
是 root
用户的密码,更多环境变量可以参考 官方文档
ports
是指定端口映射,前面是宿主机端口,后面是容器端口,也就是将宿主机的 4417
端口映射到容器的 3306
端口,这样我们就可以通过 localhost:4417
来访问 mysql
了
volumes
是指定挂载目录,前面是宿主机目录,后面是容器目录,挂载之后,二者互通,修改任意一方的文件,另一方都会同步修改,这里我们挂载了三个目录,分别是
./mysql/data:/var/lib/mysql
数据持久化
./mysql/conf.d:/etc/mysql/conf.d
配置文件,在里面添加的 .cnf
文件,文件内容将被合并到mysql的配置文件中
./mysql/init:/docker-entrypoint-initdb.d/
初始化目录,可以在里面添加 .sql
文件,如创建用户、数据库等,里面的所有sql都将在容器初始化时自动执行
command
是指定启动命令
networks
是指定网络,这里指定为 default
,即上文定义的默认网络 app-tier
php-fpm
1
2
3
4
5
6
7
8
9
10
11
12
php-fpm :
build : ./php-fpm
container_name : php-fpm
restart : always
environment :
TZ : Asia/Shanghai
volumes :
- ./php-fpm/typecho/blog:/var/www/blog
networks :
- default
depends_on :
- mysql
1
2
3
4
5
6
7
8
FROM php:8.1.13-fpm-alpine
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories \
&& apk update \
&& apk add alpine-conf \
&& /sbin/setup-timezone -z Asia/Shanghai \
&& apk del alpine-conf \
&& docker-php-ext-install pdo pdo_mysql calendar \
&& printf '[PHP]\ndate.timezone = Asia/Shanghai\n' > /usr/local/etc/php/conf.d/tzone.ini
这里的 php-fpm
是服务名,也是容器名
build
是指定构建镜像,这里指定的是 ./php-fpm
目录,也即从通过路径下的 Dockerfile
文件构建,看下 Dockerfile
文件:
FROM
指定以哪个镜像为基础进行构建。这里我们使用的是 php:8.1.13-fpm-alpine
镜像
RUN
表示执行命令。由于Docker每执行一次 RUN 就会多构建一层 所以使用 & 将多条命令拼接在一次执行,从上往下命令大意:
设置alpine apk 仓库为 aliyun 镜像仓库
更新软件
安装 alpine-conf (alpine 不包含时区文件,故需下载)
设置系统时区为 Asia/Shanghai
删除 alpine-conf (释放空间)
安装 pdo
和 pdo_mysql
、calendar
等PHP扩展
设置 PHP 时区为 Asia/Shanghai
volumes
挂载了两个目录,对应两个 typecho 站点,需要将 typecho 程序放到这两个目录下
depends_on
是指定依赖,也就是说 php-fpm
服务启动之前,必须保证 mysql
服务已经启动
nginx
上配置文件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
nginx :
image : nginx:1.23.3-alpine
container_name : nginx
restart : always
ports :
- 80 : 80
- 443 : 443
volumes :
- ./nginx/conf.d:/etc/nginx/conf.d
- ./nginx/logs:/var/log/nginx
- ./nginx/ssl:/etc/nginx/ssl
- ./php-fpm/typecho/blog:/var/www/blog
networks :
- default
depends_on :
- php-fpm
environment :
TZ : Asia/Shanghai
到这里就没什么好说的了,端口映射、挂载目录等等和前面一样。接下来看向 ./nginx/conf.d
,在其中新建一个 .cnf
文件作为nginx站点配置文件,其内容如下:
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
server {
listen 80 ;
server_name localhost : 80
index index.php index.html index.htm default.php default.htm default.html ;
root /var/www/blog ;
#伪静态
if (!-e $request_filename ) {
rewrite ^(.*) $ /index.php $1 last ;
}
#PHP
location ~ [^/]\.php(/|$) {
fastcgi_pass php-fpm : 9000 ;
fastcgi_index index.php ;
fastcgi_param PATH_INFO $fastcgi_path_info ;
fastcgi_param PATH_TRANSLATED /var/www/blog $fastcgi_path_info ;
fastcgi_param SCRIPT_NAME $fastcgi_script_name ;
fastcgi_param SCRIPT_FILENAME /var/www/blog $fastcgi_script_name ;
include fastcgi_params ;
}
#禁止访问的文件或目录
location ~ ^/(\.user.ini|\.htaccess|\.git|\.svn|\.project|LICENSE|README.md) {
return 404 ;
}
}
关于nginx配置就不多展开了,其中,listen
指定了站点端口,root
指定了站点目录,和我们在 nginx 中挂载路径一致,然后就是伪静态、反向代理和访问限制。这里反向代理中使用了:fastcgi_pass php-fpm:9000
即通过服务名来和 fpm 容器连接,这背后的 DNS 等工作将由 docker 自动完成。
到这里,docker-compose.yml
就写完了, 最后整合以下,完整版如下:
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
49
50
51
52
53
54
version: "2"
networks:
default:
external: false
name: app-tier
services:
mysql:
image: mysql:8.0
container_name: mysql
restart: always
environment:
TZ: Asia/Shanghai
MYSQL_ROOT_PASSWORD: 12345678
ports:
- 4417:3306
volumes:
- ./mysql/data:/var/lib/mysql
- ./mysql/logs:/var/log/mysql
- ./mysql/conf.d:/etc/mysql/conf.d
- ./mysql/init:/docker-entrypoint-initdb.d/
command:
- --character-set-server= utf8mb4
- --collation-server= utf8mb4_unicode_ci
networks:
- default
php-fpm:
build: ./php-fpm
container_name: php-fpm
restart: always
environment:
TZ: Asia/Shanghai
volumes:
- ./php-fpm/typecho/blog:/var/www/blog
networks:
- default
depends_on:
- mysql
nginx:
image: nginx:1.23.3-alpine
container_name: nginx
restart: always
ports:
- 80:80
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d
- ./nginx/logs:/var/log/nginx
- ./nginx/ssl:/etc/nginx/ssl
- ./php-fpm/typecho/blog:/var/www/blog
networks:
- default
depends_on:
- php-fpm
environment:
TZ: Asia/Shanghai
启动
最后,在我们的文件夹下打开终端,键入以下命令,也即启动服务并在后台运行:
等待拉取镜像和构建可能需要一些时间,当这一切完成后,浏览器访问 localhost:80
就会进入typecho 安装页啦~