├── LICENSE ├── README.md ├── docker-compose.yml ├── etc ├── nginx │ ├── cert │ │ └── options-ssl-nginx.conf │ └── conf.d │ │ ├── common.conf │ │ ├── ext │ │ ├── header.conf │ │ ├── proxy.conf │ │ └── ssl.conf │ │ └── vhost │ │ ├── yourdomain.com.conf │ │ └── yourdomain.com_cache.conf └── php │ ├── dockerfile │ ├── 56 │ │ └── Dockerfile │ ├── 70 │ │ └── Dockerfile │ ├── 71 │ │ └── Dockerfile │ ├── 72 │ │ └── Dockerfile │ ├── 73 │ │ └── Dockerfile │ └── 74 │ │ └── Dockerfile │ └── php-fpm.d │ └── php-fpm.conf ├── init.sh └── opt ├── backup ├── backup.sh └── cos.conf ├── g_cache.sh └── g_deathlink_file.sh /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### 一、简单介绍 2 | domp是`Docker+Openresty+php-fpm+MySQL`环境的首字母缩写,可以基于Docker快速部署`Openresty + php-fpm + MySQL`,并且支持开启redis动、静态缓存优化。 3 | 4 | domp用到的Docker镜像全部来自`hub.docker.com`的官方镜像,其中php-fpm因为各网站需求的模块各异,所以单独抽出来自定义编译,基于Dockerfile,过程透明,可完全自定义。 5 | 6 | 通过domp来部署一个php网站环境,不考虑国内网络因素,耗时不超过5分钟,而通过OneinStack或lnmp一键安装包少说也要40分钟甚至1小时以上,高下立判。目前张戈博客完全基于domp稳定运行半年有余,性能、稳定性、可运维性还是值得肯定的! 7 | 8 | ### 二、环境要求 9 | 理论上可以基于任何支持docker的平台,不过domp内置的一些脚本是基于centos 7编写,所以如果是非centos 7系统,不可以通过脚本快速部署,请参见下面的附录。 10 | 11 | ### 三、目录及文件说明(必读): 12 | ``` 13 | [root@localhost]# tree 14 | . 15 | ├── docker-compose.yml # docker 编排配置 16 | ├── Dockerfile # php-fpm docker镜像编译文件(可自定义) 17 | ├── etc # 配置目录 18 | │ ├── nginx 19 | │ │ ├── cert # 证书一级SSL公共配置存放目录,若启用https,请将证书放到此目录 20 | │ │ │ └── options-ssl-nginx.conf 21 | │ │ └── conf.d # nginx 配置目录 22 | │ │ ├── common.conf # nginx 公共配置 23 | │ │ ├── ext # nginx 拓展配置 24 | │ │ │ ├── header.conf # header 通用配置 25 | │ │ │ ├── proxy.conf # proxy 通用配置 26 | │ │ │ └── ssl.conf # ssl 跳转配置 27 | │ │ └── vhost # 虚拟主机配置(必须修改的配置),已放置2个参考实例配置,仅供参考: 28 | │ │ ├── yourdomain.com_cache.conf # 站点配置文件(带缓存),实际使用需要将yourdomain.com改成实际域名。 29 | │ │ └── yourdomain.com.conf # 站点配置文件(无缓存),实际使用需要将yourdomain.com改成实际域名。 30 | │   └── php 31 | │ ├── dockerfile # php-fpm 镜像编译配置(已添加5.6、7.0-7.2版本编译文件) 32 | │ │ ├── 56 33 | │   │   │   └── Dockerfile 34 | │   │   ├── 70 35 | │   │   │   └── Dockerfile 36 | │   │   ├── 71 37 | │   │   │   └── Dockerfile 38 | │   │   └── 72 39 | │   │   └── Dockerfile 40 | │   └── php-fpm.d 41 | │ └── php-fpm.conf # php-fpm 配置 42 | ├── init.sh # domp 初始化并启动的脚本 43 | ├── LICENSE 44 | ├── opt 45 | │   ├── backup 46 | │ │ └── backup.sh # 基于 腾讯云COS备份脚本,需要先安装并配置 coscmd,参考:https://cloud.tencent.com/document/product/436/10976 47 | │ ├── g_cache.sh # 基于 shell 的预缓存脚本,需要自行修改并添加定时任务,参考:https://zhang.ge/5095.html 48 | │ └── g_deathlink_file.sh # 基于 shell 的死链生成脚本,需要自行修改并添加定时任务,参考:https://zhang.ge/5038.html 49 | ├── README.md 50 | └── reload_php.sh # php reload脚本,build镜像的时候回ADD到镜像里面。 51 | ``` 52 | ### 四、快速拉起domp环境 53 | #### 1、 克隆代码 54 | ``` 55 | mkdir -p /data && cd /data 56 | git clone https://github.com/jagerzhang/domp.git 57 | ``` 58 | #### 2、修改MySQL root密码、指定php版本 59 | ``` 60 | vim docker-compose.yml 61 | 找到: 62 | - "MYSQL_ROOT_PASSWORD=yourpassword" 63 | 将 yourpassword 改成自定义密码 64 | 65 | 找到: 66 | build: ./etc/php/dockerfile/72/ 67 | 将72改成需要的php版本,目前支持56、70、71、72 四个版本,若无版本刚需,使用默认的7.2即可! 68 | ``` 69 | Ps: 若因国内功夫墙导致php-fpm在线编译失败,可以如下修改: 70 | ``` 71 | vim docker-compose.yml 72 | 找到: 73 | php-fpm: 74 | build: ./etc/php/dockerfile/72/ 75 | container_name: php-fpm 76 | image: php-fpm:7.2 77 | 改为: 78 | php-fpm: 79 | #build: ./etc/php/dockerfile/72/ 80 | container_name: php-fpm 81 | image: jagerzhang/php-fpm:7.2 # 这里直接使用张戈做好的镜像即可,版本同样有 5.6,7.0-7.2。如果一定有特殊php模块需求则不能使用。 82 | ``` 83 | #### 3、自定义php模块 84 | ##### php5.6 ~ 7.2 参考以下内容操作 85 | ``` 86 | vim etc/php/dockerfile/72/Dockerfile 87 | 88 | # 找到如下语句,若满足要求则无需修改,若缺少某模块,则加上 php72w-模块名称,pecl的可能要额外加上 pecl 89 | yum install -y memcached php72w-fpm php72w-gd php72w-pecl-memcached php72w-opcache php72w-mysql php72w-mbstring php72w-pecl-redis 90 | ``` 91 | ##### php7.3 ~ 7.4 参考以下内容操作 92 | ``` 93 | vim etc/php/dockerfile/74/Dockerfile 94 | 95 | # 参考官方安装拓展的方法:使用内置命令 docker-php-ext-install / pecl install / docker-php-ext-enable 安装即可,请参考文档:https://hub.docker.com/_/php (How to install more PHP extensions) 96 | 97 | ``` 98 | 99 | #### 4、启动domp 100 | ``` 101 | bash init.sh 102 | 103 | docker ps # 查看是否正常启动 104 | CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 105 | 2fdcd10d05c6 openresty/openresty:centos "/usr/bin/openresty …" 2 hours ago Up 2 hours openresty 106 | eb5684527e4b php-fpm:7.2 "php-fpm -F" 2 hours ago Up 2 hours php-fpm 107 | 41381dea3d7f redis:latest "docker-entrypoint.s…" 2 hours ago Up 2 hours 127.0.0.1:6379->6379/tcp redis 108 | 1f6278298539 mysql:8.0 "docker-entrypoint.s…" 4 days ago Up 4 days 127.0.0.1:3306->3306/tcp, 33060/tcp mysql 109 | ``` 110 | ### 五、配置网站 111 | 112 | #### 1、虚拟主机配置说明 113 | domp 默认已经自带了2种虚拟主机配置:`yourdomain.com.conf` 和 `yourdomain.com_cache.conf`,第一个不带`redis`缓存,第二个带`redis`缓存,自行选择一个,然后删除另一个即可。然后参考这个配置文件来定制自己网站的配置文件。若看不懂这个配置文件,可以直接拷贝网站原来的`vhost`配置文件也可以。 114 | 115 | #### 2、https证书配置说明 116 | https证书请放置到 `domp/etc/nginx/cert` 目录,然后在vhost配置中引用即可,注意在vhost里面的配置要变为:`/etc/nginx/cert/证书名字` ,而非`domp/etc/nginx/cert` 目录,因为已经挂载到了`docker`里面了!!! 117 | 118 | #### 3、缓存配置说明 119 | 若开启了openresty+redis缓存,且正好又是wordpress网站,则可以安装下`nginx-hepler`和`Redis Object Cache`插件,天然绝配!后续有时间会有domp一系列的文章分享,敬请期待:https://zhang.ge/ 。 120 | 121 | ## 附录 122 | ### 非centos环境使用参考 123 | 124 | 1、安装docker,参考:https://docs.docker.com/install/ 125 | 126 | 2、安装 docker-compose,参考:https://docs.docker.com/compose/install/ 127 | 128 | Ps:此处提供linux通用安装命令: 129 | ``` 130 | curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/bin/docker-compose 131 | chmod +x /usr/bin/docker-compose 132 | ``` 133 | 3、启动domp 134 | ``` 135 | docker-compose up -d 136 | ``` 137 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | services: 3 | mysql: 4 | container_name: mysql 5 | image: mysql:8.0 6 | ports: 7 | - 127.0.0.1:3306:3306 8 | volumes: 9 | - /etc/localtime:/etc/localtime 10 | - /data/mysql_data:/var/lib/mysql 11 | command: --default-authentication-plugin=mysql_native_password 12 | environment: 13 | - "MYSQL_ROOT_PASSWORD=yourpassword" 14 | privileged: true 15 | restart: always 16 | 17 | redis: 18 | container_name: redis 19 | image: redis:latest 20 | ports: 21 | - 127.0.0.1:6379:6379 22 | volumes: 23 | - /data/redis:/data 24 | - /etc/localtime:/etc/localtime 25 | command: redis-server --appendonly yes 26 | privileged: true 27 | restart: always 28 | 29 | php-fpm: 30 | # build: ./etc/php/dockerfile/74/ 31 | container_name: php-fpm 32 | image: jagerzhang/php-fpm:7.4 33 | volumes: 34 | - /etc/localtime:/etc/localtime 35 | - ./etc/php/php-fpm.d/php-fpm.conf:/usr/local/etc/php-fpm.conf 36 | - /dev/shm:/dev/shm 37 | - /var/log:/data/wwwlogs/php-fpm 38 | - /data:/data 39 | - /tmp:/tmp 40 | network_mode: host 41 | depends_on: 42 | - mysql 43 | - redis 44 | privileged: true 45 | restart: always 46 | 47 | openresty: 48 | container_name: openresty 49 | image: openresty/openresty:centos 50 | volumes: 51 | - /etc/localtime:/etc/localtime 52 | - ./etc/nginx/conf.d:/etc/nginx/conf.d 53 | - ./etc/nginx/cert:/etc/nginx/cert 54 | - /dev/shm:/dev/shm 55 | - /data:/data 56 | - /tmp:/tmp 57 | network_mode: host 58 | depends_on: 59 | - php-fpm 60 | - redis 61 | privileged: true 62 | restart: always 63 | -------------------------------------------------------------------------------- /etc/nginx/cert/options-ssl-nginx.conf: -------------------------------------------------------------------------------- 1 | # This file contains important security parameters. If you modify this file 2 | # manually, Certbot will be unable to automatically provide future security 3 | # updates. Instead, Certbot will print and log an error message with a path to 4 | # the up-to-date file that you will need to refer to when manually updating 5 | # this file. 6 | 7 | ssl_session_cache shared:le_nginx_SSL:1m; 8 | ssl_session_timeout 1440m; 9 | 10 | ssl_protocols TLSv1 TLSv1.1 TLSv1.2; 11 | ssl_prefer_server_ciphers on; 12 | 13 | ssl_ciphers "ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS"; 14 | -------------------------------------------------------------------------------- /etc/nginx/conf.d/common.conf: -------------------------------------------------------------------------------- 1 | map $http_x_forwarded_for $clientRealIp { 2 | "" $remote_addr; 3 | ~^(?P[0-9\.]+),?.*$ $firstAddr; 4 | } 5 | 6 | #log format 7 | log_format access '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" $clientRealIp'; 8 | 9 | proxy_buffers 4 128k; 10 | proxy_connect_timeout 600; #nginx跟后端服务器连接超时时间(代理连接超时) 11 | proxy_read_timeout 600; #连接成功后,后端服务器响应时间(代理接收超时) 12 | proxy_send_timeout 600; #后端服务器数据回传时间(代理发送超时) 13 | proxy_busy_buffers_size 256k; #高负荷下缓冲大小(proxy_buffers*2) 14 | proxy_temp_file_write_size 1024k; #设定缓存文件夹大小,大于这个值,将从upstream服务器传 15 | 16 | 17 | proxy_cache_path /tmp/proxy_cache levels=1:2 keys_zone=cache_one:150m inactive=31d max_size=2g; 18 | proxy_temp_path /tmp/proxy_cache/temp; 19 | 20 | include /etc/nginx/conf.d/vhost/*.conf; -------------------------------------------------------------------------------- /etc/nginx/conf.d/ext/header.conf: -------------------------------------------------------------------------------- 1 | fastcgi_hide_header X-Powered-By; 2 | fastcgi_hide_header X-Runtime; 3 | fastcgi_hide_header X-Version; 4 | add_header X-Frame-Options SAMEORIGIN; 5 | add_header X-Content-Type-Options nosniff; 6 | add_header Content-Security-Policy "upgrade-insecure-requests"; 7 | add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"; -------------------------------------------------------------------------------- /etc/nginx/conf.d/ext/proxy.conf: -------------------------------------------------------------------------------- 1 | proxy_connect_timeout 300s; 2 | proxy_send_timeout 900; 3 | proxy_read_timeout 900; 4 | proxy_redirect off; 5 | proxy_hide_header Vary; 6 | #proxy_set_header Host $host; 7 | proxy_headers_hash_max_size 51200; 8 | proxy_headers_hash_bucket_size 6400; 9 | proxy_set_header Cookie $http_cookie; 10 | proxy_set_header Referer $http_referer; 11 | proxy_set_header X-Forwarded-Proto $scheme; 12 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; -------------------------------------------------------------------------------- /etc/nginx/conf.d/ext/ssl.conf: -------------------------------------------------------------------------------- 1 | if ($http_user_agent ~* "Baiduspider|360spider|360Spider|YisouSpider|spider|bot") { 2 | set $ssl "y"; 3 | } 4 | 5 | if ($http_user_agent ~* "Windows\ NT\ 5.1|Windows\ NT\ 5.2") { 6 | set $ssl "n"; 7 | } 8 | 9 | 10 | if ($scheme = 'http' ) { 11 | set $ssl "${ssl}es"; 12 | } 13 | 14 | if ( $ssl = "yes" ) { 15 | rewrite ^(.*)$ https://$host$1 permanent; 16 | } 17 | -------------------------------------------------------------------------------- /etc/nginx/conf.d/vhost/yourdomain.com.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80; 3 | #listen 443 ssl http2; 4 | server_name domain.com www.domain.com; 5 | #ssl_certificate /etc/nginx/cert/domain.com.crt; 6 | #ssl_certificate_key /etc/nginx/cert/domain.com.key; 7 | #include /etc/nginx/cert/options-ssl-nginx.conf; 8 | index index.html index.htm index.php default.html default.htm default.php; 9 | root /data/wwwroot/domain.com; 10 | 11 | # 跳转到首选域名,若是带www的,请自行加上www 12 | if ($host != domain.com) { 13 | rewrite ^(.*)$ $scheme://domain.com$1 permanent; 14 | } 15 | # https 301跳转,不需要轻删除 16 | if ($scheme = http) { 17 | rewrite ^(.*)$ https://$host$1 permanent; 18 | } 19 | 20 | location ~ [^/]\.php(/|$) 21 | { 22 | include /etc/nginx/conf.d/ext/header.conf; 23 | fastcgi_pass unix:/dev/shm/php-cgi.sock; 24 | fastcgi_index index.php; 25 | include fastcgi.conf; 26 | } 27 | 28 | location / { 29 | try_files $uri $uri/ /index.php?$args; 30 | rewrite /wp-admin$ $scheme://$host$uri/ permanent; 31 | } 32 | 33 | location ~* .*\.(gif|jpg|jpeg|png|bmp|jepg|css|js|ico|ogg|ogv|svg|svgz|eot|otf|woff|woff2|mp4|ttf|rss|atom|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ { 34 | root /data/wwwroot/zhang.ge; 35 | access_log off; 36 | log_not_found off; 37 | expires 30d; 38 | } 39 | 40 | # 解决 robots漏洞 41 | location = /robots.txt { 42 | if ($http_user_agent !~* "spider|bot|Python-urllib|pycurl") { 43 | return 403; 44 | } 45 | access_log off; 46 | log_not_found off; 47 | } 48 | location ~ /\. { 49 | deny all; 50 | access_log off; 51 | log_not_found off; 52 | } 53 | access_log /data/wwwlogs/$host.log; 54 | } 55 | -------------------------------------------------------------------------------- /etc/nginx/conf.d/vhost/yourdomain.com_cache.conf: -------------------------------------------------------------------------------- 1 | upstream redis { 2 | server 127.0.0.1:6379; 3 | keepalive 512; 4 | } 5 | server { 6 | listen 80; 7 | #listen 443 ssl http2; 8 | server_name yourdomain.com www.yourdomain.com; 9 | #ssl_certificate /etc/nginx/cert/yourdomain.com.crt; 10 | #ssl_certificate_key /etc/nginx/cert/yourdomain.com.key; 11 | #include /etc/nginx/cert/options-ssl-nginx.conf; 12 | index index.html index.htm index.php default.html default.htm default.php; 13 | root /data/wwwroot/yourdomain.com; 14 | 15 | # 跳转到首选域名,若是带www的,请自行加上www 16 | if ($host != yourdomain.com) { 17 | rewrite ^(.*)$ $scheme://yourdomain.com$1 permanent; 18 | } 19 | # https 301跳转,不需要轻删除 20 | if ($scheme = http) { 21 | rewrite ^(.*)$ https://$host$1 permanent; 22 | } 23 | 24 | # openresty+redis缓存 25 | set $skip_cache 0; 26 | if ($request_method = POST) { 27 | set $skip_cache 1; 28 | } 29 | # 根据url忽略缓存 30 | if ($request_uri ~* "purge=all|/roll|/goto|/go/?(.*)|comment-page-|/wp-admin/|/xmlrpc.php|wp-.*.php|/feed/|index.php") { 31 | set $skip_cache 1; 32 | } 33 | # 根据cookie忽略缓存 34 | if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in") { 35 | set $skip_cache 1; 36 | } 37 | 38 | location /redis-fetch { 39 | internal ; 40 | set $redis_key $args; 41 | redis_pass redis; 42 | } 43 | 44 | location /redis-store { 45 | internal ; 46 | set_unescape_uri $key $arg_key ; 47 | redis2_query set $key $echo_request_body; 48 | redis2_query expire $key 14400; 49 | redis2_pass redis; 50 | } 51 | 52 | location ~ [^/]\.php(/|$) 53 | { 54 | include /etc/nginx/conf.d/ext/header.conf; 55 | fastcgi_pass unix:/dev/shm/php-cgi.sock; 56 | fastcgi_index index.php; 57 | include fastcgi.conf; 58 | 59 | # redis缓存配置 60 | set $key "nginx-cache:$scheme$request_method$host$request_uri"; 61 | srcache_fetch_skip $skip_cache; 62 | srcache_store_skip $skip_cache; 63 | srcache_response_cache_control off; 64 | set_escape_uri $escaped_key $key; 65 | srcache_fetch GET /redis-fetch $key; 66 | srcache_store PUT /redis-store key=$escaped_key; 67 | more_set_headers 'X-Cache $srcache_fetch_status'; 68 | more_set_headers 'X-Store $srcache_store_status'; 69 | } 70 | 71 | location / { 72 | try_files $uri $uri/ /index.php?$args; 73 | rewrite /wp-admin$ $scheme://$host$uri/ permanent; 74 | } 75 | 76 | location ~* .*\.(gif|jpg|jpeg|png|bmp|jepg|css|js|ico|ogg|ogv|svg|svgz|eot|otf|woff|woff2|mp4|ttf|rss|atom|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ { 77 | root /data/wwwroot/zhang.ge; 78 | access_log off; 79 | log_not_found off; 80 | expires 30d; 81 | } 82 | 83 | # 解决 robots漏洞 84 | location = /robots.txt { 85 | if ($http_user_agent !~* "spider|bot|Python-urllib|pycurl") { 86 | return 403; 87 | } 88 | access_log off; 89 | log_not_found off; 90 | } 91 | location ~ /\. { 92 | deny all; 93 | access_log off; 94 | log_not_found off; 95 | } 96 | access_log /data/wwwlogs/$host.log; 97 | } 98 | -------------------------------------------------------------------------------- /etc/php/dockerfile/56/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM centos:7.5.1804 2 | MAINTAINER jager 3 | 4 | RUN yum install -y epel-release \ 5 | && rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm \ 6 | && yum install -y memcached php56w-fpm php56w-gd php56w-pecl-memcached php56w-pecl-memcache php56w-opcache php56w-mysql php56w-mbstring php56w-pecl-redis \ 7 | && yum clean all \ 8 | && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime 9 | 10 | CMD ["php-fpm", "-F"] 11 | -------------------------------------------------------------------------------- /etc/php/dockerfile/70/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM centos:7.5.1804 2 | MAINTAINER jager 3 | 4 | RUN yum install -y epel-release \ 5 | && rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm \ 6 | && yum install -y memcached php70w-fpm php70w-gd php70w-pecl-memcached php70w-pecl-memcache php70w-opcache php70w-mysql php70w-mbstring php70w-pecl-redis \ 7 | && yum clean all \ 8 | && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime 9 | 10 | CMD ["php-fpm", "-F"] 11 | -------------------------------------------------------------------------------- /etc/php/dockerfile/71/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM centos:7.5.1804 2 | MAINTAINER jager 3 | 4 | RUN yum install -y epel-release \ 5 | && rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm \ 6 | && yum install -y memcached php71w-fpm php71w-gd php71w-pecl-memcached php71w-pecl-memcache php71w-opcache php71w-mysql php71w-mbstring php71w-pecl-redis \ 7 | && yum clean all \ 8 | && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime 9 | 10 | CMD ["php-fpm", "-F"] 11 | -------------------------------------------------------------------------------- /etc/php/dockerfile/72/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM centos:7.5.1804 2 | MAINTAINER jager 3 | 4 | RUN yum install -y epel-release \ 5 | && rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm \ 6 | && yum install -y memcached php72w-fpm php72w-gd php72w-pecl-memcached php72w-pecl-memcache php72w-opcache php72w-mysql php72w-mbstring php72w-pecl-redis \ 7 | && yum clean all \ 8 | && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime 9 | 10 | CMD ["php-fpm", "-F"] 11 | -------------------------------------------------------------------------------- /etc/php/dockerfile/73/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM php:7.3-fpm-alpine3.13 2 | MAINTAINER jager 3 | 4 | ENV TZ=Asia/Shanghai 5 | 6 | # 安装基础依赖 7 | RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories \ 8 | && apk add --update --no-cache \ 9 | && apk add --no-cache autoconf cmake make gcc g++ 10 | 11 | # 安装WP通用依赖 12 | RUN docker-php-ext-install opcache 13 | RUN docker-php-ext-install mysqli 14 | RUN docker-php-ext-install pdo_mysql 15 | RUN docker-php-ext-install exif 16 | 17 | # 安装GD扩展 18 | RUN apk add --update --no-cache libpng-dev jpeg-dev freetype-dev libjpeg-turbo-dev \ 19 | && docker-php-ext-configure gd \ 20 | && docker-php-ext-install -j$(nproc) gd 21 | 22 | # 安装imagick扩展 23 | RUN apk add --update --no-cache imagemagick imagemagick-dev \ 24 | && pecl install imagick \ 25 | && docker-php-ext-enable imagick 26 | 27 | # 安装zip扩展 28 | RUN apk add --no-cache libzip-dev \ 29 | && docker-php-ext-install zip 30 | 31 | # 安装mbstring扩展 32 | RUN apk add --update --no-cache oniguruma-dev \ 33 | && docker-php-ext-install mbstring 34 | 35 | # 安装redis扩展 36 | RUN pecl install redis \ 37 | && docker-php-ext-enable redis 38 | 39 | CMD ["php-fpm", "-F"] 40 | -------------------------------------------------------------------------------- /etc/php/dockerfile/74/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM php:7.4-fpm-alpine3.13 2 | MAINTAINER jager 3 | 4 | ENV TZ=Asia/Shanghai 5 | 6 | # 安装基础依赖 7 | RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories \ 8 | && apk add --update --no-cache \ 9 | && apk add --no-cache autoconf cmake make gcc g++ 10 | 11 | # 安装WP通用依赖 12 | RUN docker-php-ext-install opcache 13 | RUN docker-php-ext-install mysqli 14 | RUN docker-php-ext-install pdo_mysql 15 | RUN docker-php-ext-install exif 16 | 17 | # 安装GD扩展 18 | RUN apk add --update --no-cache libpng-dev jpeg-dev freetype-dev libjpeg-turbo-dev \ 19 | && docker-php-ext-configure gd --with-freetype=/usr/include/ --with-jpeg=/usr/include/ \ 20 | && docker-php-ext-install -j$(nproc) gd 21 | 22 | # 安装imagick扩展 23 | RUN apk add --update --no-cache imagemagick imagemagick-dev \ 24 | && pecl install imagick \ 25 | && docker-php-ext-enable imagick 26 | 27 | # 安装zip扩展 28 | RUN apk add --no-cache libzip-dev \ 29 | && docker-php-ext-install zip 30 | 31 | # 安装mbstring扩展 32 | RUN apk add --update --no-cache oniguruma-dev \ 33 | && docker-php-ext-install mbstring 34 | 35 | # 安装redis扩展 36 | RUN pecl install redis \ 37 | && docker-php-ext-enable redis 38 | 39 | CMD ["php-fpm", "-F"] 40 | -------------------------------------------------------------------------------- /etc/php/php-fpm.d/php-fpm.conf: -------------------------------------------------------------------------------- 1 | ;;;;;;;;;;;;;;;;;;;;; 2 | ; FPM Configuration ; 3 | ;;;;;;;;;;;;;;;;;;;;; 4 | 5 | ;;;;;;;;;;;;;;;;;; 6 | ; Global Options ; 7 | ;;;;;;;;;;;;;;;;;; 8 | 9 | [global] 10 | pid = /var/run/php-fpm.pid 11 | error_log = /var/log/php-fpm.log 12 | log_level = warning 13 | 14 | emergency_restart_threshold = 30 15 | emergency_restart_interval = 60s 16 | process_control_timeout = 5s 17 | daemonize = yes 18 | 19 | ;;;;;;;;;;;;;;;;;;;; 20 | ; Pool Definitions ; 21 | ;;;;;;;;;;;;;;;;;;;; 22 | 23 | [www] 24 | listen = /dev/shm/php-cgi.sock 25 | listen.backlog = -1 26 | listen.allowed_clients = 127.0.0.1 27 | listen.owner = nobody 28 | listen.group = nobody 29 | listen.mode = 0666 30 | user = nobody 31 | group = nobody 32 | 33 | pm = dynamic 34 | pm.max_children = 16 35 | pm.start_servers = 10 36 | pm.min_spare_servers = 8 37 | pm.max_spare_servers = 16 38 | pm.max_requests = 2048 39 | pm.process_idle_timeout = 10s 40 | request_terminate_timeout = 120 41 | request_slowlog_timeout = 0 42 | 43 | pm.status_path = /php-fpm_status 44 | slowlog = /var/log/slow.log 45 | rlimit_files = 51200 46 | rlimit_core = 0 47 | 48 | catch_workers_output = yes 49 | env[PATH] = /usr/local/bin:/usr/bin:/bin 50 | env[TMP] = /tmp 51 | env[TMPDIR] = /tmp 52 | env[TEMP] = /tmp 53 | -------------------------------------------------------------------------------- /init.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # remove old version only for centos 3 | yum remove docker \ 4 | docker-client \ 5 | docker-client-latest \ 6 | docker-common \ 7 | docker-latest \ 8 | docker-latest-logrotate \ 9 | docker-logrotate \ 10 | docker-engine 11 | 12 | # add repo and install latest version only for centos 13 | yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo 14 | yum install -y docker-ce docker-ce-cli containerd.io 15 | 16 | # start and register to startup 17 | service docker start 18 | chkconfig docker on 19 | # ========================================================= 20 | # install docker-compose only foy linux 21 | curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/bin/docker-compose 22 | chmod +x /usr/bin/docker-compose 23 | 24 | # start service 25 | docker-compose up -d 26 | -------------------------------------------------------------------------------- /opt/backup/backup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ################################################################### 3 | # Web Backup version 1.0.0 Author: Jager # 4 | # For more information please visit https://zhang.ge/5117.html # 5 | #-----------------------------------------------------------------# 6 | # Copyright ©2016 zhang.ge. All rights reserved. # 7 | ################################################################### 8 | 9 | isDel=n 10 | args=$# 11 | isDel=${!args} 12 | # 设置压缩包解压密码 13 | mypassword=123456 14 | 15 | test -f /etc/profile && . /etc/profile >/dev/null 2>&1 16 | baseDir=$(cd $(dirname $0) && pwd) 17 | zip --version >/dev/null || yum install -y zip 18 | ZIP=$(which zip) 19 | TODAY=`date +%u` 20 | MYSQLDUMP=$(which mysqldump) 21 | 22 | # 基于coscmd的上传备份文件函数 23 | uploadToCOS() 24 | { 25 | file=$2 26 | domain=$1 27 | file_name=$(basename $2) 28 | coscmd upload $file $domain/$file_name 29 | if [[ $? -eq 0 ]] && [[ "$isDel" == "y" ]] 30 | then 31 | test -f $2 && rm -f $2 32 | fi 33 | } 34 | 35 | printHelp() 36 | { 37 | clear 38 | printf ' 39 | =====================================Help infomation========================================= 40 | 1. Use For Backup database: 41 | The $1 must be [db] 42 | $2: [domain] 43 | $3: [dbname] 44 | $4: [mysqluser] 45 | $5: [mysqlpassword] 46 | $6: [back_path] 47 | $7: [isDel] 48 | 49 | For example:./backup.sh db zhang.ge zhangge_db zhangge 123456 /data/wwwbackup/zhang.ge 50 | 51 | 2. Use For Backup webfile: 52 | The $1 must be [file]: 53 | $2: [domain] 54 | $3: [site_path] 55 | $4: [back_path] 56 | $5: [isDel] 57 | 58 | For example:./backup.sh file zhang.ge /data/wwwroot/zhang.ge /data/wwwbackup/zhang.ge 59 | =====================================End of Hlep============================================== 60 | 61 | ' 62 | exit 0 63 | } 64 | 65 | backupDB() 66 | { 67 | domain=$1 68 | dbname=$2 69 | mysqluser=$3 70 | mysqlpd=$4 71 | back_path=$5 72 | test -d $back_path || (mkdir -p $back_path || echo "$back_path not found! Please CheckOut Or feedback to zhang.ge..." && exit 2) 73 | cd $back_path 74 | #如果是要备份远程MySQL,则修改如下语句中127.0.0.1为远程MySQL地址 75 | $MYSQLDUMP -h127.0.0.1 -u$mysqluser -p$mysqlpd $dbname --skip-lock-tables --default-character-set=utf8 >$back_path/$domain\_db_$TODAY\.sql 76 | test -f $back_path/$domain\_db_$TODAY\.sql || (echo "MysqlDump failed! Please CheckOut Or feedback to zhang.ge..." && exit 2) 77 | $ZIP -P$mypassword -m $back_path/$domain\_db_$TODAY\.zip $domain\_db_$TODAY\.sql && \ 78 | uploadToCOS $domain $back_path/$domain\_db_$TODAY\.zip 79 | } 80 | 81 | backupFile() 82 | { 83 | domain=$1 84 | site_path=$2 85 | back_path=$3 86 | test -d $site_path || (echo "$site_path not found! Please CheckOut Or feedback to zhang.ge..." && exit 2) 87 | test -d $back_path || (mkdir -p $back_path || echo "$back_path not found! Please CheckOut Or feedback to zhang.ge..." && exit 2) 88 | test -f $back_path/$domain\_$TODAY\.zip && rm -f $back_path/$domain\_$TODAY\.zip 89 | $ZIP -P$mypassword -9r $back_path/$domain\_$TODAY\.zip $site_path && \ 90 | uploadToCOS $domain $back_path/$domain\_$TODAY\.zip 91 | } 92 | 93 | while [ $1 ]; do 94 | case $1 in 95 | '--db' | 'db' ) 96 | backupDB $2 $3 $4 $5 $6 97 | exit 98 | ;; 99 | '--file' | 'file' ) 100 | backupFile $2 $3 $4 101 | exit 102 | ;; 103 | * ) 104 | printHelp 105 | exit 106 | ;; 107 | esac 108 | done 109 | printHelp 110 | -------------------------------------------------------------------------------- /opt/backup/cos.conf: -------------------------------------------------------------------------------- 1 | # 1st: install coscmd: https://cloud.tencent.com/document/product/436/10976 2 | # 2st: copy this file to /root/.cos.conf and configure it. 3 | [common] 4 | secret_id = your_secret_id 5 | secret_key = your_secret_key 6 | bucket = your_backet_name 7 | region = ap-hongkong 8 | max_thread = 5 9 | part_size = 1 10 | appid = 1251134401 11 | schema = https 12 | verify = md5 13 | anonymous = False 14 | -------------------------------------------------------------------------------- /opt/g_cache.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | cd /root;curl -o sitemap.xml https://zhang.ge/sitemap.xml >/dev/null 2>&1 3 | for url in `egrep -o 'https://zhang.ge([^\<]+)' sitemap.xml` 4 | do 5 | curl -o /dev/null $url 6 | sleep 3 7 | done 8 | -------------------------------------------------------------------------------- /opt/g_deathlink_file.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #Desc: Cut Nginx Log and Create Death Chain File 3 | #Author: ZhangGe 4 | #Blog: https://zhang.ge/5038.html 5 | #Date: 2015-05-03 6 | 7 | #①、初始化变量: 8 | #定义access日志存放路径 9 | LOGS_PATH=/data/wwwlogs 10 | 11 | #定义蜘蛛UA信息(默认是百度蜘蛛) 12 | UA='+http://www.baidu.com/search/spider.html' 13 | 14 | #定义网站域名(需要先给相应的网站以域名形式配置了nginx日志,比如zhang.ge.log) 15 | DOMAIN=zhang.ge 16 | 17 | #定义网站访问地址 18 | website=https://$DOMAIN 19 | 20 | #定义前一天日期 21 | DATE=`date +%Y-%m-%d -d "1 day ago"` 22 | 23 | #定义日志路径 24 | logfile=/home/wwwlogs/zhang.ge_${DATE}.log 25 | 26 | #定义死链文件存放路径 27 | deathfile=/home/wwwroot/zhang.ge/death.txt 28 | 29 | #②、Nginx日志切割 30 | mv ${LOGS_PATH}/${DOMAIN}.log ${LOGS_PATH}/${DOMAIN}_${DATE}.log 31 | kill -USR1 `ps axu | grep "nginx: master process" | grep -v grep | awk '{print $2}'` 32 | #可选功能: 自动删除30天之前的日志,可自行修改保存时长。 33 | cd ${LOGS_PATH} 34 | find . -mtime +30 -name "*20[1-9][3-9]*" | xargs rm -f 35 | 36 | #③、网站死链生成(百度专用) 37 | #分析日志并保存死链数据 38 | for url in `awk -v str="${UA}" '$9=="404" && $15~str {print $7}' ${logfile}` 39 | do 40 | grep -q "$url" ${deathfile} || echo ${website}${url} >>${deathfile} 41 | done --------------------------------------------------------------------------------