目录

简单使用 docker 配置开发环境(mac+php)

简单使用 docker 配置开发环境,在 mac 环境下搭建 PHP环境

前言

  • 搭建开发环境是一个开发者必备的技能,但是重复的搭建各种开发环境,依然是一件很无趣且浪费时间的事情。
  • 以前的解决方案通常是虚拟机或者一些集成工具,它们能很好的解决重复搭建相同开发环境的问题。
  • 同时它们也有着一些缺陷,比如虚拟机过于笨重,集成工具功能比较固定单一。
  • docker 等虚拟容器技术的出现,让开始构建多样的开发环境成为可能。

基础需求

第一步 clone docker-compose 脚本,复制配置文件

1
2
3
4
# 克隆脚本
git clone https://github.com/snowlyg/dnmp
#复制配置文件
copy docker-compose.sample.yml docker-compose.yml

根据自己需要的服务,修改配置文件解开或者加上对应的注释代码

  • php 基础开发环境nginx + mysql + redis 如下
  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
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
version: "3"
services:
  nginx:
    build:
      context: ./services/nginx
      args:
        NGINX_VERSION: 1.15.7-alpine
        CONTAINER_PACKAGE_URL: mirrors.aliyun.com
        NGINX_INSTALL_APPS: ""
    container_name: nginx
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./www:/www/:rw
      - ./services/nginx/ssl:/ssl:rw
      - ./services/nginx/conf.d:/etc/nginx/conf.d/:rw
      - ./services/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
      - ./services/nginx/fastcgi-php.conf:/etc/nginx/fastcgi-php.conf:ro
      - ./services/nginx/fastcgi_params:/etc/nginx/fastcgi_params:ro
      - ./logs/nginx:/var/log/nginx/:rw
    environment:
      TZ: "Asia/Shanghai"
    restart: always
    networks:
      - default

  php:
    build:
      context: ./services/php
      args:
        PHP_VERSION: php:7.3-fpm-alpine
        CONTAINER_PACKAGE_URL: mirrors.aliyun.com
        PHP_EXTENSIONS: "pdo_mysql,mysqli,mbstring,gd,curl,opcache,soap,amqp,bcmath,pcntl,redis,xdebug"
        TZ: "Asia/Shanghai"
    container_name: php
    expose:
      - 9501
    extra_hosts:
      - "www.site1.com:172.17.0.1"
    volumes:
      - ./www:/www/:rw
      - ./services/php/php.ini:/usr/local/etc/php/php.ini:ro
      - ./services/php/php-fpm.conf:/usr/local/etc/php-fpm.d/www.conf:rw
      - ./logs/php:/var/log/php
      - ./data/composer:/tmp/composer
    restart: always
    cap_add:
      - SYS_PTRACE
    networks:
      - default

#  php56:
#    build:
#      context: ./services/php
#      args:
#        PHP_VERSION: php:5.6.40-fpm-alpine
#        CONTAINER_PACKAGE_URL: mirrors.aliyun.com
#        PHP_EXTENSIONS: "pdo_mysql,mysqli,mbstring,gd,curl,opcache"
#        TZ: "Asia/Shanghai"
#    container_name: php56
#    expose:
#      - 9501
#    volumes:
#      - ./www:/www/:rw
#      - ./services/php/php.ini:/usr/local/etc/php/php.ini:ro
#      - ./services/php/php-fpm.conf:/usr/local/etc/php-fpm.d/www.conf:rw
#      - ./logs/php:/var/log/php
#      - ./data/composer:/tmp/composer
#    restart: always
#    cap_add:
#      - SYS_PTRACE
#    networks:
#      - default

  #  php54:
  #    build:
  #      context: ./services/php54
  #      args:
  #        PHP_VERSION: php:5.4.45-fpm
  #        CONTAINER_PACKAGE_URL: mirrors.aliyun.com
  #        PHP_EXTENSIONS: "pdo_mysql,mysqli,mbstring,gd,curl,opcache"
  #        TZ: "Asia/Shanghai"
  #    container_name: php54
  #    volumes:
  #      - ./www:/www/:rw
  #      - ./services/php54/php.ini:/usr/local/etc/php/php.ini:ro
  #      - ./services/php54/php-fpm.conf:/usr/local/etc/php-fpm.d/www.conf:rw
  #      - ./logs/php:/var/log/php
  #      - ./data/composer:/tmp/composer
  #    restart: always
  #    cap_add:
  #      - SYS_PTRACE
  #    networks:
  #      - default

  mysql:
   image: mysql:8.0.13
   container_name: mysql
   ports:
     - "3306:3306"
   volumes:
     - ./services/mysql/mysql.cnf:/etc/mysql/conf.d/mysql.cnf:ro
     - ./data/mysql:/var/lib/mysql/:rw
   restart: always
   networks:
     - default
   environment:
     MYSQL_ROOT_PASSWORD: "123456"
     TZ: "Asia/Shanghai"

  # mysql5:
  #   image: mysql:5.7.28
  #   container_name: mysql5
  #   ports:
  #     - "3305:3306"
  #   volumes:
  #     - ./services/mysql5/mysql.cnf:/etc/mysql/conf.d/mysql.cnf:ro
  #     - ./data/mysql5:/var/lib/mysql/:rw
  #   restart: always
  #   networks:
  #     - default
  #   environment:
  #     MYSQL_ROOT_PASSWORD: "123456"
  #     TZ: "Asia/Shanghai"

  #  openresty:
  #    image:  openresty/openresty:alpine
  #    container_name: openresty
  #    ports:
  #       - "80:80"
  #       - "443:443"
  #    volumes:
  #       - ./www:/www/:rw
  #       - ./services/openresty/conf.d:/etc/nginx/conf.d/:ro
  #       - ./services/openresty/openresty.conf:/ssl:rw
  #       - ./services/openresty/fastcgi-php.conf:/usr/local/openresty/nginx/conf/nginx.conf:ro
  #       - ./services/openresty/fastcgi_params:/usr/local/openresty/nginx/conf/fastcgi-php.conf:ro
  #       - ./services/openresty/ssl:/usr/local/openresty/nginx/conf/fastcgi_params:ro
  #       - ./logs/nginx:/var/log/nginx/:rw
  #    environment:
  #      TZ: "Asia/Shanghai"
  #    networks:
  #      - default

  redis:
    image: redis:5.0.3-alpine
    container_name: redis
    ports:
      - "6379:6379"
    volumes:
      - ./services/redis/redis.conf:/etc/redis.conf:ro
      - ./data/redis:/data/:rw
    restart: always
    entrypoint: ["redis-server", "/etc/redis.conf"]
    environment:
      TZ: "Asia/Shanghai"
    networks:
      - default

  #  memcached:
  #    image: memcached:alpine
  #    container_name: memcached
  #    ports:
  #      - "11211:11211"
  #    environment:
  #       MEMCACHED_CACHE_SIZE: "128"
  #    networks:
  #      - default

  # rabbitmq:
  #   image: rabbitmq:management
  #   container_name: rabbitmq
  #   restart: always
  #   ports:
  #     - "5672:5672"
  #     - "15672:15672"
  #   environment:
  #      TZ: "Asia/Shanghai"
  #      RABBITMQ_DEFAULT_USER: "myuser"
  #      RABBITMQ_DEFAULT_PASS: "mypass"
  #   networks:
  #         - default

  # phpmyadmin:
  #  image: phpmyadmin/phpmyadmin:latest
  #  container_name: phpmyadmin
  #  ports:
  #    - "8080:80"
  #  volumes:
  #    - ./services/phpmyadmin/config.user.inc.php:/etc/phpmyadmin/config.user.inc.php:ro
  #    - ./services/phpmyadmin/php-phpmyadmin.ini:/usr/local/etc/php/conf.d/php-phpmyadmin.ini:ro
  #  networks:
  #    - default
  #  environment:
  #    - PMA_HOST=mysql
  #    - PMA_PORT=3306
  #    - TZ=Asia/Shanghai

  # phpredisadmin:
  #  image: erikdubbelboer/phpredisadmin:latest
  #  container_name: phpredisadmin
  #  ports:
  #    - "${REDISMYADMIN_HOST_PORT}:80"
  #  networks:
  #    - default
  #  environment:
  #    - REDIS_1_HOST=redis
  #    - REDIS_1_PORT=6379
  #    - TZ=Asia/Shanghai

  # mongodb:
  #  image: mongo:4.1
  #  container_name: mongodb
  #  environment:
  #      MONGO_INITDB_ROOT_USERNAME: "root"
  #      MONGO_INITDB_ROOT_PASSWORD: "123456"
  #      TZ: "Asia/Shanghai"
  #  volumes:
  #    - ./data/mongo:/data/db:rw
  #    - ./data/mongo_key:/mongo:rw
  #  ports:
  #     - "27017:27017"
  #  networks:
  #     - default
  #  command:
  #     --auth

  #  adminmongo:
  #    image: mrvautin/adminmongo
  #    container_name: adminmongo
  #    ports:
  #      - "1234:1234"
  #    environment:
  #      - HOST=0.0.0.0
  #      - DB_HOST=mongodb
  #      - DB_PORT=27017
  #    networks:
  #      - default

  # elasticsearch:
  #  build:
  #    context: ./services/elasticsearch
  #    args:
  #      ELASTICSEARCH_VERSION: 7.1.1
  #      ELASTICSEARCH_PLUGINS: ""
  #  container_name: elasticsearch
  #  environment:
  #    - TZ=Asia/Shanghai
  #    - discovery.type=single-node
  #    - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
  #  volumes:
  #    - ./data/esdata:/usr/share/elasticsearch/data
  #    - /services/elasticsearch/elasticsearch.yml:/usr/share/elasticsearch/elasticsearch.yml
  #  hostname: elasticsearch
  #  restart: always
  #  ports:
  #    - "9200:9200"
  #    - "9300:9300"

#  kibana:
#    image: kibana:7.1.1
#    container_name: kibana
#    environment:
#      TZ: "Asia/Shanghai"
#      elasticsearch.hosts: http://elasticsearch:9200
#      I18N_LOCALE: "zh-CN"
#    hostname: kibana
#    depends_on:
#      - elasticsearch
#    restart: always
#    ports:
#      - "5601:5601"

#  logstash:
#    image: logstash:7.1.1
#    container_name: logstash
#    hostname: logstash
#    restart: always
#    depends_on:
#      - elasticsearch
#    environment:
#      TZ: "Asia/Shanghai"
#    ports:
#      - "9600:9600"
#      - "5044:5044"


networks:
  default:

在脚本根目录执行 docker-compose 命令,构建环境

  • 如果本机安装了对应的服务,比如 apache,nginx,mysql 等,会导致对应80,3306 等端口别占用。
  • 需要修改前面的配置的端口映射关系项
1
2
3
4
5
6
7
# 修改为,前面的端口是本机端口,后面的是容器内的端口。
# 这个设置表示将 本机端口映射到容器的80端口
# 后面访问的时候也需要使用 83 端口,比如 http://localhost:83s
ports:
  - "83:80" 


1
2
3
4
5
6
  # 构建本启动脚本未注释部分的服务,并在守护对应服务
  docker-compose up -d
  # 如果只启动部分服务,比如 php
  docker-compose up -d php
  # 或者 php mysql
  docker-compose up -d php mysql

查看对应服务是否正常启动

  • 可以直接在面板看 apps

  • 或者使用命令行 docker ps 查看 apps-cli

  • 可以看到对应服务的名称,状态,创建时间和对应的端口

部署一个应用到这个 docker 搭建的 php 环境中

 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
#进入 nginx 配置目录
cd services/nginx/conf.d/
# 新建一个配置文件 loclhost.conf
server {
  listen 80;
  server_name localhost;
  root /www;

  #add_header X-Frame-Options "SAMEORIGIN";
  #add_header X-XSS-Protection "1; mode=block";
  #add_header X-Content-Type-Options "nosniff";

  index index.html index.htm index.php;

  charset utf-8;

  location / {
    #try_files $uri $uri/ /index.php?$query_string;
    if (!-e $request_filename) {
      rewrite  ^(.*)$  /index.php?s=/$1  last;
    }
  }

  location = /favicon.ico { access_log off; log_not_found off; }
  location = /robots.txt  { access_log off; log_not_found off; }

  error_page 404 /index.php;

  location ~ \.php$ {
    fastcgi_pass  php:9000;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
    include fastcgi_params;
  }

  location ~ /\.(?!well-known).* {
    deny all;
  }
}
# 注意 location ~\.php$ {} 里面, fastcgi_pass 的值是 php:9000 不是通常的 127.0.0.1,至于原理后面会提到

# 新建一个 index.html 文件到 www/ 目录下,再访问 http://localhost 就能看到 index.html 里面的内容了。 

容易踩坑点

  • 部署正式项目的时候,配置 mysql ,redis 的服务地址配置的时候不能使用常规的 localhost 或者 127.0.0.1。
  • 因为 php,mysql,redis,nginx 都部署再相对隔离的不同 docker 容器中,就如同把它们安装再了不同机器上一样。
  • 要在容器中访问其他容器 ,需要使用它们的容器名称,也是它们的网络地址别名,比如 mysql,php 等等。
  • 所以前面配置 nginx 设置的时候 location ~.php$ {} 里面, fastcgi_pass 的值是 php:9000 不是通常的 127.0.0.1