├── .all-contributorsrc ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report_zh.md │ ├── feature_request_zh.md │ └── question_zh.md ├── scripts │ └── build.sh └── workflows │ └── main.yml ├── .gitignore ├── LICENSE.md ├── README.md ├── assistant ├── .gitattributes ├── .gitignore ├── Makefile ├── const.go ├── go.mod ├── go.sum ├── internal │ ├── cmd │ │ ├── docker_cmd.go │ │ ├── docker_quick_cmd.go │ │ ├── init_cmd.go │ │ └── vhost_cmd.go │ ├── consts │ │ └── consts.go │ ├── controller │ │ └── hello.go │ ├── model │ │ ├── .gitkeep │ │ └── entity │ │ │ └── .gitkeep │ ├── packed │ │ └── packed.go │ └── service │ │ ├── .gitkeep │ │ └── internal │ │ ├── dao │ │ └── .gitkeep │ │ └── do │ │ └── .gitkeep ├── main.go ├── manifest │ ├── config │ │ └── config.yaml │ ├── deploy │ │ └── kustomize │ │ │ ├── base │ │ │ ├── deployment.yaml │ │ │ ├── kustomization.yaml │ │ │ └── service.yaml │ │ │ └── overlays │ │ │ └── develop │ │ │ ├── configmap.yaml │ │ │ ├── deployment.yaml │ │ │ └── kustomization.yaml │ └── docker │ │ ├── Dockerfile │ │ └── docker.sh ├── readme.md ├── resource │ ├── i18n │ │ └── .gitkeep │ ├── public │ │ ├── html │ │ │ └── .gitkeep │ │ ├── plugin │ │ │ └── .gitkeep │ │ └── resource │ │ │ ├── css │ │ │ └── .gitkeep │ │ │ ├── image │ │ │ └── .gitkeep │ │ │ └── js │ │ │ └── .gitkeep │ └── template │ │ └── .gitkeep └── utility │ ├── .gitkeep │ ├── container.go │ ├── dir.go │ ├── init.go │ └── vhost.go ├── dev.md ├── docs ├── php.md ├── 仓库操作流程.md ├── 开发流程.md ├── 快速安装.md ├── 系统需求.md ├── 约定规范.md └── 路线图.md ├── env └── readme.md ├── release ├── xii_linux.zip ├── xii_linux_arm.zip ├── xii_linux_arm64.zip ├── xii_mac.zip └── xii_mac_arm.zip ├── repo ├── base │ ├── compose.yml │ ├── env.sample │ └── readme.md ├── memcached │ ├── compose.yml │ └── env.sample ├── mongo │ ├── compose.yml │ └── env.sample ├── mysql55 │ ├── build │ │ └── mysql.cnf │ ├── compose.yml │ └── env.sample ├── mysql56 │ ├── build │ │ └── mysql.cnf │ ├── compose.yml │ └── env.sample ├── mysql57 │ ├── build │ │ └── mysql.cnf │ ├── compose.yml │ └── env.sample ├── mysql80 │ ├── build │ │ └── mysql.cnf │ ├── compose.yml │ └── env.sample ├── nginx │ ├── build │ │ ├── Dockerfile │ │ ├── acme │ │ │ └── readme.md │ │ ├── acme_install.sh │ │ ├── dhparam.pem │ │ ├── fastcgi-php.conf │ │ ├── fastcgi_params │ │ ├── helper │ │ │ ├── cut_log.sh │ │ │ └── readme.md │ │ ├── nginx.conf │ │ ├── other │ │ │ ├── brotli.conf │ │ │ ├── disable_html_cache.conf │ │ │ ├── general.conf │ │ │ ├── gzip.conf │ │ │ ├── proxy.conf │ │ │ ├── python_uwsgi.conf │ │ │ ├── security.conf │ │ │ └── wellknow.conf │ │ ├── rewrite │ │ │ ├── codeigniter.conf │ │ │ ├── dabr.conf │ │ │ ├── dedecms.conf │ │ │ ├── discuz.conf │ │ │ ├── discuzx.conf │ │ │ ├── discuzx2.conf │ │ │ ├── drupal.conf │ │ │ ├── ecshop.conf │ │ │ ├── joomla.conf │ │ │ ├── laravel.conf │ │ │ ├── phpwind.conf │ │ │ ├── sablog.conf │ │ │ ├── shopex.conf │ │ │ ├── thinkphp.conf │ │ │ ├── typecho.conf │ │ │ ├── typecho2.conf │ │ │ ├── wordpress.conf │ │ │ ├── wp2.conf │ │ │ ├── yii2.conf │ │ │ └── zblog.conf │ │ └── vhost │ │ │ └── localhost.conf │ ├── compose.yml │ └── env.sample ├── node10 │ ├── compose.yml │ └── env.sample ├── node14 │ ├── compose.yml │ └── env.sample ├── node16 │ ├── compose.yml │ └── env.sample ├── node18 │ ├── compose.yml │ └── env.sample ├── php73 │ ├── build │ │ ├── Dockerfile │ │ ├── extensions │ │ │ ├── install-composer.sh │ │ │ ├── install-php-extensions │ │ │ └── install.sh │ │ ├── php-fpm.conf │ │ └── php.ini │ ├── changelog.md │ ├── compose.yml │ └── env.sample ├── php74 │ ├── build │ │ ├── Dockerfile │ │ ├── extensions │ │ │ ├── amqp-1.10.2.tgz │ │ │ ├── apcu-5.1.17.tgz │ │ │ ├── event-2.5.6.tgz │ │ │ ├── install-composer.sh │ │ │ ├── install-php-extensions │ │ │ ├── install.sh │ │ │ ├── memcache-2.2.6.tgz │ │ │ ├── memcache-4.0.5.2.tgz │ │ │ ├── mongodb-1.7.4.tgz │ │ │ ├── redis-5.2.2.tgz │ │ │ ├── swoole-2.0.11.tgz │ │ │ ├── swoole-4.5.2.tgz │ │ │ ├── xdebug-2.5.5.tgz │ │ │ ├── xdebug-2.6.1.tgz │ │ │ ├── xdebug-2.9.2.tgz │ │ │ ├── xhprof-2.2.0.tgz │ │ │ └── yaf-2.3.5.tgz │ │ ├── php-fpm.conf │ │ └── php.ini │ ├── compose.yml │ └── env.sample ├── php80 │ ├── build │ │ ├── Dockerfile │ │ ├── extensions │ │ │ ├── event-3.0.5.tgz │ │ │ ├── install-php-extensions │ │ │ └── install.sh │ │ ├── php-fpm-dnmp.conf │ │ ├── php-fpm.conf │ │ └── php.ini │ ├── compose.yml │ └── env.sample ├── php81 │ ├── build │ │ ├── Dockerfile │ │ ├── extensions │ │ │ ├── install-php-extensions │ │ │ └── install.sh │ │ ├── php-fpm.conf │ │ └── php.ini │ ├── compose.yml │ └── env.sample ├── php82 │ ├── build │ │ ├── Dockerfile │ │ ├── extensions │ │ │ ├── install-php-extensions │ │ │ └── install.sh │ │ ├── php-fpm.conf │ │ └── php.ini │ ├── compose.yml │ └── env.sample ├── phpmyadmin │ ├── build │ │ ├── config.user.inc.php │ │ └── php-phpmyadmin.ini │ ├── compose.yml │ └── env.sample ├── rabbitmq │ ├── build │ │ └── Dockerfile │ ├── compose.yml │ └── env.sample ├── readme.md ├── redis5 │ ├── build │ │ └── redis.conf │ ├── compose.yml │ └── env.sample ├── redis6 │ ├── build │ │ └── redis.conf │ ├── compose.yml │ └── env.sample └── supervisor │ ├── build │ ├── Dockerfile │ ├── conf.d │ │ └── php-fpm.ini │ └── supervisord.conf │ ├── compose.yml │ └── env.sample ├── script ├── install.sh ├── make.sh ├── manual.sh └── uninstall.sh ├── script_dev ├── install.sh └── make.sh └── www └── localhost └── index.html /.all-contributorsrc: -------------------------------------------------------------------------------- 1 | { 2 | "files": [ 3 | "README.md" 4 | ], 5 | "imageSize": 100, 6 | "commit": false, 7 | "commitConvention": "angular", 8 | "contributors": [ 9 | { 10 | "login": "mslxi", 11 | "name": "mslxi", 12 | "avatar_url": "https://avatars.githubusercontent.com/u/56199297?v=4", 13 | "profile": "https://github.com/mslxi", 14 | "contributions": [ 15 | "code" 16 | ] 17 | }, 18 | { 19 | "login": "xiiapp", 20 | "name": "xiiapp", 21 | "avatar_url": "https://avatars.githubusercontent.com/u/109425179?v=4", 22 | "profile": "https://github.com/xiiapp", 23 | "contributions": [ 24 | "code", 25 | "ideas" 26 | ] 27 | } 28 | ], 29 | "contributorsPerLine": 7, 30 | "skipCi": true, 31 | "repoType": "github", 32 | "repoHost": "https://github.com", 33 | "projectName": "xii", 34 | "projectOwner": "xiiapp" 35 | } 36 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report_zh.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug 报告 3 | about: 创建一份 Bug 报告帮助我们优化产品 4 | title: '' 5 | labels: ':bug: bug' 6 | assignees: '' 7 | --- 8 | 9 | 10 | 11 | 12 | 13 | #### 请确认 14 | - [ ] 是当前最新的发布版本(官网安装),还是开发版本 15 | 16 | #### Bug 描述 17 | 18 | 19 | #### 复现步骤 20 | 该 Bug 复现步骤如下: 21 | 1. 在 xxx 时 做了什么动作 22 | 2. 然后又xxx 23 | 3. 会出现 xxx 24 | 25 | 26 | 27 | #### 截图 28 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request_zh.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 功能需求或优化 3 | about: 创建一份合理可行的建议帮助我们提升产品 4 | title: '' 5 | labels: ':sparkles: enhancement' 6 | assignees: '' 7 | --- 8 | 9 | #### 如是功能需求,请确定符合以下情况 10 | - [ ] 难以通过自己实现 11 | - [ ] 难以通过第三方插件实现 12 | 13 | #### 请描述该需求尝试解决的问题 14 | 15 | 16 | #### 请描述您认为可行的解决方案 17 | 18 | 19 | #### 考虑过的替代方案 20 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/question_zh.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 问题求助 3 | OS: 操作系统 4 | about: 提出一个使用过程中遇到的问题,需要得到帮助 5 | --- 6 | 7 | 8 | 9 | 10 | #### 请确认 11 | - [ ] 在 [用户指南](https://xii.app) 中没有找到解决办法 12 | 13 | #### 问题描述 14 | -------------------------------------------------------------------------------- /.github/scripts/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Hello world! Not yet implemented." -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | on: 3 | release: 4 | types: [prereleased] #预发布时出发 5 | jobs: 6 | build-and-deploy: 7 | runs-on: ubuntu-20.04 8 | steps: 9 | - name: Checkout 🛎️ 10 | uses: actions/checkout@v2 11 | with: 12 | persist-credentials: false 13 | 14 | - name: Run build script 15 | run: | 16 | chmod +x .github/scripts/build.sh 17 | ./.github/scripts/build.sh 18 | shell: bash 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | 3 | /dev/ 4 | 5 | /data/ 6 | /data/composer/ 7 | /data/mysql/ 8 | 9 | /logs/ 10 | /logs/letsencrypt/ 11 | /logs/mysql80/ 12 | /logs/nginx/ 13 | /logs/php80/ 14 | 15 | /env_bk/ 16 | /assistant/ 17 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | Copyright (c) 2012 xiiapp/xii 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [![All Contributors](https://img.shields.io/badge/all_contributors-2-orange.svg?style=flat-square)](#contributors-) 4 | 5 | ![GitHub](https://img.shields.io/github/license/xiiapp/xii) 6 | ![GitHub language count](https://img.shields.io/github/languages/count/xiiapp/xii) 7 | ![GitHub issues](https://img.shields.io/github/issues-raw/xiiapp/xii) 8 | ![GitHub closed issues](https://img.shields.io/github/issues-closed-raw/xiiapp/xii) 9 | ![GitHub pull requests](https://img.shields.io/github/issues-pr/xiiapp/xii) 10 | ![GitHub closed pull requests](https://img.shields.io/github/issues-pr-closed-raw/xiiapp/xii) 11 | ![GitHub forks](https://img.shields.io/github/forks/xiiapp/xii) 12 | 13 | # 最新changelog(1-2条) 14 | 2022-10-21 增加 `xii db` 命令,封装了mysql的备份还原,增删数据库的便捷操作 15 | 16 | 2022-10-19 增加对arm、arm64 架构的支持。 17 | 18 | ### Xii 助手命令: 19 | 20 | 命令:`xii db` 包括了8个常规mysql操作,主要有: 21 | > xii db 并不是要代替mysql的所有操作,他主要是针对最常用的场景做了处理。【参考自lnmp.org的操作】,更多功能请用专业管理软件或命令操作。 22 | 23 | - 创建备份 24 | - 还原/导入备份 25 | - 创建数据库+用户 ,删除数据库 26 | - 显示所有用户 27 | - 常用mysql操作集合提示。 28 | 29 | 30 | 31 | 32 | 33 | 34 | # 群聊沟通 35 | Tg: [https://t.me/xii_app](https://t.me/xii_app) 36 | 37 | # 简介 38 | 39 | 详细文档请查看: 40 | [https://xii.app](https://xii.app) 41 | 42 | 43 | Docker 化的 lnmp 环境及更多软件包,同时提供助手程序 xii 用来快捷管理。 44 | 45 | 46 | > **注:** xii 是罗马数字 12 的意思,正好有域名 xii.app ,就很随意的用了。 这会征求名。 47 | 48 | 49 | 50 | ## 内置软件(Docker 镜像)清单 51 | | 软件 | 具体版本 | 备注 | 52 | | ------------- | ---------------------------------------- | --------------------------- | 53 | | **PHP** | php7.3 , php7.4, php8.0, php8.1, php8.2 | | 54 | | **Web服务器** | nginx | 内嵌acme.sh,用于ssl证书申请 | 55 | | **数据库** | mysql5.7, mysql8.0 , mysql5.6 , mysql5.5 | | 56 | | **Nosql** | mongoldb , redis | | 57 | | **缓存** | memcached | | 58 | | **消息队列** | rabitmq | | 59 | | **其他** | supervisor | | 60 | | **工具** | phpmyadmin | | 61 | 62 | 63 | **注 1:** 可自行轻松扩展软件清单 64 | 65 | **注 2:** php 支持快捷安装扩展,已默认安装 compose,php 扩展等请查看左边 php 节点说明。 nginx 的配置已做优化处理,默认自带 acme.sh,可免费申请 ssl 证书。phpmyadmin 实际运行体积大改 450Mb,不太建议启用。 66 | 67 | **注3:** Mysql尽可能建议使用5.7或以上版本,能获得更多的性能。 使用前请查看左边mysql说明了解端口、导出导入数据等信息。 68 | 69 | 70 | ## 助手程序 Xii 71 | 72 | 主要提供了易用性功能,具体如下: 73 | 74 | 1. 便捷的网站增删查,使用 xii vhost add 可以创建安装,安装 nginx 的优化配置,申请免费的 ssl 证书等(该功能借鉴自 lnmp 套件)。 75 | 2. 便捷的 docker 镜像管理功能, 使用 `` xii init` 可以随时随地增删 docker 镜像。 76 | 3. 封装了 docker-compose 的大部分命令,docker-compose 平时要的时候,要么需要进入到 docker-compose.yml 所在的目录,要么需要带一大串参数。 而且任何危险操作都没有二次确认,这导致不是很熟悉的人容易误操作。 xii 的封装解决了这些问题。可以在任何目录下执行,危险动作会有说明或二次确认。 77 | 4. 封装了 docker 的几个命令,主要也是危险动作二次确认或便捷操作。 78 | 5. 后续拟增加的功能:升级功能,继续提供一些便捷操作组合等,具体参照“路线图” 79 | 80 | 81 | # 安装 82 | 83 | **当前仅在 linux 和 mac 测试完全。** 84 | 85 | 注:暂没在 window 下充分测试完,项目的快捷操作严重依赖 xii 助手,所以如需要 window 下使用,建议使用 yeszao/dnmp 这个开源项目(本项目的配置项大量复用了它的代码段,并进行优化配置或提升版本等)。 86 | 87 | ## 一键安装 88 | 89 | 复制并执行一下命令: 90 | 91 | ```sh 92 | wget -c https://raw.githubusercontent.com/xiiapp/xii/main/script/install.sh && chmod +x install.sh && ./install.sh 93 | ``` 94 | 95 | 96 | 97 | **注:** 当前仅支持 mac 和 linux,暂不支持 win 系统一键安装。 98 | 99 | 100 | ## 手动安装 101 | 102 | ### mac 系统 103 | 104 | 1. 确保系统安装好 docker 和 docker-compose,建议直接安装 docker 官方的 docker-desktop。 105 | 106 | 2. 下载安装包,下载地址二选一 107 | 108 | > 苹果M1/M2芯片用户请下载 arm64 版本 109 | > [https://github.com/xiiapp/xii/raw/main/release/xii_mac_arm.zip ](https://github.com/xiiapp/xii/raw/main/release/xii_mac_arm.zip) 110 | 111 | > 苹果Intel芯片用户请下载 112 | > [https://github.com/xiiapp/xii/raw/main/release/xii_mac.zip ](https://github.com/xiiapp/xii/raw/main/release/xii_mac.zip) 113 | 114 | 115 | 3. 解压安装后后,手动执行 `chmod +x manual.sh && ./manual.sh` 完成安装。 116 | 117 | 4. 注意检测 docker 是否启动,在 docker 启动的情况下,可以执行后续命令。 118 | 119 | ### Linux 系统 120 | 121 | 1. 确保系统安装好 docker 和 docker-compose。 122 | 安装docker# 123 | > docker官方提供了傻瓜式安装脚本,为你做好所有工作,免去了手动安装的繁琐。 124 | > 125 | > 本文实测系统环境:debian11 126 | > 127 | > 执行以下命令 128 | > 129 | > 2023-03-07更新 130 | > 131 | > 不知道从什么时候开始官方脚本已经默认也安装了 docker compose,不需要后面的手动安装了 132 | > 133 | > 注意是 docker compose 而不是 docker-compose. 执行命令时候也没有这个杠 134 | 135 | `curl -fsSL https://get.docker.com | bash -s docker` 136 | 137 | 3. 下载安装包,下载地址二选一 138 | 139 | > Linux 版本 140 | > [https://github.com/xiiapp/xii/raw/main/release/xii_linux.zip ](https://github.com/xiiapp/xii/raw/main/release/xii_linux.zip) 141 | > 142 | > Linux arm64 版本 143 | > [https://github.com/xiiapp/xii/raw/main/release/xii_linux_arm64.zip ](https://github.com/xiiapp/xii/raw/main/release/xii_linux_arm64.zip) 144 | > 145 | > Linux arm 版本 146 | > [https://github.com/xiiapp/xii/raw/main/release/xii_linux_arm.zip ](https://github.com/xiiapp/xii/raw/main/release/xii_linux_arm.zip) 147 | 148 | 149 | 4. 解压安装后后,手动执行 `chmod +x manual.sh && ./manual.sh` 完成安装。 150 | 151 | 5. 注意检测 docker 是否启动,在 docker 启动的情况下,可以执行后续命令。 152 | 153 | # 卸载 154 | 155 | 156 | 157 | 158 | 159 | ## 快捷卸载 160 | 161 | ```sh 162 | wget -c https://raw.githubusercontent.com/xiiapp/xii/main/script/uninstall.sh && chmod +x uninstall.sh && ./uninstall.sh 163 | ``` 164 | 165 | 166 | 167 | ## 手动卸载 168 | 169 | - 备份好所需数据,网站数据放在```www目录```,配置放在```env/容器类型```, 容器产生的数据,比如msyql,一般在```data/容器名``` 下 170 | 171 | - 执行 ```xii down``` 停止所有容器 172 | 173 | - 执行 ```xii rmall``` 删除所有容器、镜像、卷 174 | 175 | - Linux用户执行 ``` rm -rf /home/xii ```,Mac用户执行 ``` rm -rf ~/xii``` 删除所有数据 176 | 177 | - 执行 ``` rm -f /usr/local/bin/xii ``` 和 ``` rm -f /usr/local/bin/xxi``` 删除软链接 178 | 179 | 180 | # 快速选择组件 181 | 182 | 无论什么时候,只要你想变更 docker 容器,都可以执行以下命令进行组件的变更。 183 | 184 | ``` 185 | xii init 186 | ``` 187 | 188 | **演示动画** 189 | 190 | 191 | 192 | **友情提示,一个可能更好的操作流程** 193 | 194 | 第一次建议执行 `xii up -d` 然后再执行 `xii ps` 看下你的容器是否都起来了。如果没起来,可以再执行一次 `xii up ` 或 `xii up -容器名` 来看一下报了什么错误 195 | 196 | 197 | 198 | # 网站管理 199 | 200 | 201 | 202 | ## 添加网站或nginx反代 203 | 204 | > xii vhost add 205 | 206 | 207 | 208 | **注:** 添加网站或者任意nginx反代的过程中,会提示很多选项,根据需要创建即可,此外过程中,会提示是否申请免费的SSL证书。 209 | 210 | **注:**当前不会创建mysql数据库,拟后续版本推出。 211 | 212 | 213 | 214 | **演示:** 215 | 216 | 217 | 218 | **注:**国内某些云服务器间歇性屏蔽掉github的访问,有可能会导致用来生成证书的acme.sh无法安装上,xii vhost如果遇到这种情况,会尝试自己安装一次,还不行会将安装命令显示出来,并提示用户复制黏贴后自己执行几次安装。 219 | 220 | 221 | 222 | ## 删除网站或反代 223 | 224 | > xii vhost del 225 | 226 | 227 | 228 | 注:其本质是检查nginx的配置目录vhost里的配置文件,一个文件就是一个网站 229 | 230 | **演示:** 231 | 232 | 233 | 234 | 235 | 236 | ## 查看网站列表(仅查看) 237 | 238 | > xii vhost list 239 | 240 | 241 | 242 | 243 | 244 | ## 修改网站配置 245 | 246 | 解析匹配关系,暂不提供。 247 | 248 | 请自行编辑 ```env/nginx/vhost/域名.conf```文件 249 | 250 | # 有关 xii 的操作问答 251 | 252 | ## 问题 1:如何重新编译镜像,即修改 docker-compose.yml ,dockerfile,env 文件等,要如何让他生效? 253 | 254 | **场景:**服务器已经在跑了一个 nginx 容器(也就是说这个容器被 `docker-compose up` 或者 `xii up` 过一次了), 此时修改`docker-compose.yml`或者`dockerfile`文件、.env 文件后,要如何让他生效? 255 | 256 | **关键理解:** 257 | 258 | - docker-compose.yml 的的改变,只跟 2 个 docker-compose up 和 docker-compose build 有关,其他命令都无法让他生效 259 | - 默认**/data 、/www、/env 里的数据是不会被删除掉**的。如有需要强制清理,请`docker-compose down --volumes`。 260 | 261 | **可以有几种如下操作来确保生效,但推荐使用`xii rebuild -镜像名`来快捷操作:** 262 | 263 | - **最粗暴做法,先 `xii down` 后 `xii up` 一次:** 264 | 265 | ```sh 266 | # 做法 1:使用原始命令,必须在 xii 的项目下执行 267 | docker-compose down 268 | docker-compose up -d 269 | 270 | # 做法 2: 使用 xii 助手,可以在任何目录下执行 271 | xii down 272 | xii up -d 273 | ``` 274 | 275 | 注意:`docker-compose down` 会删除容器、镜像、网络、映射的卷(我们通过 dockerfile 里 volume 命令挂载上去的不会删除)。 276 | 277 | - **标准流程** 278 | 279 | ```sh 280 | 281 | 282 | #做法 1:原始命令方式,必须在 docker-compose.yml 所在目录下执行 283 | docker stop 容器名 #1.先停止容器 284 | docker rm 容器名 #2.删除掉容器 285 | systemctl restart docker #重启 docker 服务(测试过,新版似乎无需,需要进一步测试,可以暂时跳过观察一下) 286 | docker-compose up -d --no-deps --build 容器名 #4.重新 docker up 一下 287 | 288 | # 做法 2:使用 xii 助手 289 | 290 | xii stop -容器名 291 | xii rm -容器名 #重启 docker,同做法 1 第 3 步一样 #在 up 之前,也可以直接先 xii build 一次,多了一条操作命令, 292 | xii up -d -容器名 293 | 294 | # 做法 3: 使用 xii rebuild 一步到位。强烈推荐这个,最简单 295 | xii rebuild -容器名 296 | 297 | ``` 298 | 299 | - **粗暴做法 2,适合同样不想手动删除已经建立的 container** 300 | 301 | ```sh 302 | # --force-recreate 即使配置或者镜像(images)没有改变也强制重启 303 | 304 | docker-compose up --force-recreate -d 305 | 306 | # 参数挺长的,推荐使用 xii rebuild -容器名 307 | 308 | ``` 309 | 310 | ## 问题 2: 在 Linux 上非 root 安装,每次启动 docker 都需要增加 sudo 的解决方法: 311 | 312 | ``` 313 | sudo gpasswd -a ${USER} docker 314 | ``` 315 | 316 | 执行完毕后,重新登陆一次 ssh 即可 317 | 318 | ## 问题 3: 国内使用 docker 慢 319 | 320 | 安装的时候,复制专用国内的安装脚本。其实就是 install.sh 后面加一个参数 china 就会默认使用国内源。 321 | 322 | 323 | # 授权 324 | 325 | **MIT** 326 | 327 | 328 | ## Contributors 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 |
mslxi
mslxi

💻
xiiapp
xiiapp

💻 🤔
341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | [![All Contributors](https://img.shields.io/badge/all_contributors-13-orange.svg?style=flat-square)](#contributors) 356 | 357 | -------------------------------------------------------------------------------- /assistant/.gitattributes: -------------------------------------------------------------------------------- 1 | * linguist-language=GO -------------------------------------------------------------------------------- /assistant/.gitignore: -------------------------------------------------------------------------------- 1 | .buildpath 2 | .hgignore.swp 3 | .project 4 | .orig 5 | .swp 6 | .idea/ 7 | .settings/ 8 | .vscode/ 9 | vendor/ 10 | composer.lock 11 | gitpush.sh 12 | pkg/ 13 | bin/ 14 | cbuild 15 | **/.DS_Store 16 | .test/ 17 | main 18 | output/ 19 | manifest/output/ 20 | temp/ -------------------------------------------------------------------------------- /assistant/Makefile: -------------------------------------------------------------------------------- 1 | ROOT_DIR = $(shell pwd) 2 | NAMESPACE = "default" 3 | DEPLOY_NAME = "template-single" 4 | DOCKER_NAME = "template-single" 5 | 6 | # Install/Update to the latest CLI tool. 7 | .PHONY: cli 8 | cli: 9 | @set -e; \ 10 | wget -O gf https://github.com/gogf/gf/releases/latest/download/gf_$(shell go env GOOS)_$(shell go env GOARCH) && \ 11 | chmod +x gf && \ 12 | ./gf install -y && \ 13 | rm ./gf 14 | 15 | 16 | # Check and install CLI tool. 17 | .PHONY: cli.install 18 | cli.install: 19 | @set -e; \ 20 | gf -v > /dev/null 2>&1 || if [[ "$?" -ne "0" ]]; then \ 21 | echo "GoFame CLI is not installed, start proceeding auto installation..."; \ 22 | make cli; \ 23 | fi; 24 | 25 | 26 | # Generate Go files for DAO/DO/Entity. 27 | .PHONY: dao 28 | dao: cli.install 29 | @gf gen dao 30 | 31 | 32 | 33 | # Build image, deploy image and yaml to current kubectl environment and make port forward to local machine. 34 | .PHONY: start 35 | start: 36 | @set -e; \ 37 | make image; \ 38 | make deploy; \ 39 | make port; 40 | 41 | # Build docker image. 42 | .PHONY: image 43 | image: cli.install 44 | $(eval _TAG = $(shell git log -1 --format="%cd.%h" --date=format:"%Y%m%d%H%M%S")) 45 | ifneq (, $(shell git status --porcelain 2>/dev/null)) 46 | $(eval _TAG = $(_TAG).dirty) 47 | endif 48 | $(eval _TAG = $(if ${TAG}, ${TAG}, $(_TAG))) 49 | $(eval _PUSH = $(if ${PUSH}, ${PUSH}, )) 50 | @gf docker -p -b "-a amd64 -s linux -p temp" -t $(DOCKER_NAME):${_TAG}; 51 | 52 | 53 | # Build docker image and automatically push to docker repo. 54 | .PHONY: image.push 55 | image.push: 56 | @make image PUSH=-p; 57 | 58 | 59 | # Deploy image and yaml to current kubectl environment. 60 | .PHONY: deploy 61 | deploy: 62 | $(eval _ENV = $(if ${ENV}, ${ENV}, develop)) 63 | 64 | @set -e; \ 65 | mkdir -p $(ROOT_DIR)/temp/kustomize;\ 66 | cd $(ROOT_DIR)/manifest/deploy/kustomize/overlays/${_ENV};\ 67 | kustomize build > $(ROOT_DIR)/temp/kustomize.yaml;\ 68 | kubectl apply -f $(ROOT_DIR)/temp/kustomize.yaml; \ 69 | kubectl patch -n $(NAMESPACE) deployment/$(DEPLOY_NAME) -p "{\"spec\":{\"template\":{\"metadata\":{\"labels\":{\"date\":\"$(shell date +%s)\"}}}}}"; 70 | 71 | 72 | -------------------------------------------------------------------------------- /assistant/const.go: -------------------------------------------------------------------------------- 1 | // Package main 2 | // @Description: 定义dokcer 容器相关的常量 3 | // 4 | package main 5 | 6 | const Nginx = "nginx" 7 | const Php = "php80" 8 | const PhpPort = "9000" 9 | -------------------------------------------------------------------------------- /assistant/go.mod: -------------------------------------------------------------------------------- 1 | module assistant 2 | 3 | go 1.18 4 | 5 | require ( 6 | github.com/AlecAivazis/survey/v2 v2.3.6 7 | github.com/gogf/gf/v2 v2.0.4 8 | github.com/tufanbarisyildirim/gonginx v0.0.0-20220829083426-44da4d61ef9a 9 | ) 10 | 11 | require ( 12 | github.com/BurntSushi/toml v0.4.1 // indirect 13 | github.com/cespare/xxhash/v2 v2.1.2 // indirect 14 | github.com/clbanning/mxj/v2 v2.5.5 // indirect 15 | github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect 16 | github.com/fatih/color v1.13.0 // indirect 17 | github.com/fsnotify/fsnotify v1.5.1 // indirect 18 | github.com/go-redis/redis/v8 v8.11.4 // indirect 19 | github.com/go-sql-driver/mysql v1.6.0 // indirect 20 | github.com/gorilla/websocket v1.4.2 // indirect 21 | github.com/grokify/html-strip-tags-go v0.0.1 // indirect 22 | github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect 23 | github.com/mattn/go-colorable v0.1.9 // indirect 24 | github.com/mattn/go-isatty v0.0.16 // indirect 25 | github.com/mattn/go-runewidth v0.0.13 // indirect 26 | github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect 27 | github.com/olekukonko/tablewriter v0.0.5 // indirect 28 | github.com/rivo/uniseg v0.3.4 // indirect 29 | go.opentelemetry.io/otel v1.0.0 // indirect 30 | go.opentelemetry.io/otel/sdk v1.0.0 // indirect 31 | go.opentelemetry.io/otel/trace v1.0.0 // indirect 32 | golang.org/x/net v0.0.0-20220812174116-3211cb980234 // indirect 33 | golang.org/x/sys v0.0.0-20220817070843-5a390386f1f2 // indirect 34 | golang.org/x/term v0.0.0-20220722155259-a9ba230a4035 // indirect 35 | golang.org/x/text v0.3.8-0.20211105212822-18b340fc7af2 // indirect 36 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect 37 | ) 38 | -------------------------------------------------------------------------------- /assistant/go.sum: -------------------------------------------------------------------------------- 1 | github.com/AlecAivazis/survey/v2 v2.3.6 h1:NvTuVHISgTHEHeBFqt6BHOe4Ny/NwGZr7w+F8S9ziyw= 2 | github.com/AlecAivazis/survey/v2 v2.3.6/go.mod h1:4AuI9b7RjAR+G7v9+C4YSlX/YL3K3cWNXgWXOhllqvI= 3 | github.com/BurntSushi/toml v0.4.1 h1:GaI7EiDXDRfa8VshkTj7Fym7ha+y8/XxIgD2okUIjLw= 4 | github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= 5 | github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s= 6 | github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w= 7 | github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= 8 | github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= 9 | github.com/clbanning/mxj/v2 v2.5.5 h1:oT81vUeEiQQ/DcHbzSytRngP6Ky9O+L+0Bw0zSJag9E= 10 | github.com/clbanning/mxj/v2 v2.5.5/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s= 11 | github.com/creack/pty v1.1.17 h1:QeVUsEDNrLBW4tMgZHvxy18sKtr6VI492kBhUfhDJNI= 12 | github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= 13 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 14 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 15 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 16 | github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= 17 | github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= 18 | github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= 19 | github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= 20 | github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= 21 | github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= 22 | github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI= 23 | github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= 24 | github.com/go-redis/redis/v8 v8.11.4 h1:kHoYkfZP6+pe04aFTnhDH6GDROa5yJdHJVNxV3F46Tg= 25 | github.com/go-redis/redis/v8 v8.11.4/go.mod h1:2Z2wHZXdQpCDXEGzqMockDpNyYvi2l4Pxt6RJr792+w= 26 | github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= 27 | github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= 28 | github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= 29 | github.com/gogf/gf/v2 v2.0.4 h1:m5F/f2lX+etXhI6rAQCR6szQoHE1ulAYlIvH0UXa2wM= 30 | github.com/gogf/gf/v2 v2.0.4/go.mod h1:apktt6TleWtCIwpz63vBqUnw8MX8gWKoZyxgDpXFtgM= 31 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 32 | github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= 33 | github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= 34 | github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= 35 | github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= 36 | github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= 37 | github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= 38 | github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= 39 | github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= 40 | github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 41 | github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 42 | github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 43 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 44 | github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 45 | github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= 46 | github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 47 | github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= 48 | github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= 49 | github.com/grokify/html-strip-tags-go v0.0.1 h1:0fThFwLbW7P/kOiTBs03FsJSV9RM2M/Q/MOnCQxKMo0= 50 | github.com/grokify/html-strip-tags-go v0.0.1/go.mod h1:2Su6romC5/1VXOQMaWL2yb618ARB8iVo6/DR99A6d78= 51 | github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec h1:qv2VnGeEQHchGaZ/u7lxST/RaJw+cv273q79D81Xbog= 52 | github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68= 53 | github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= 54 | github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= 55 | github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= 56 | github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= 57 | github.com/mattn/go-colorable v0.1.9 h1:sqDoxXbdeALODt0DAeJCVp38ps9ZogZEAXjus69YV3U= 58 | github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= 59 | github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= 60 | github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= 61 | github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= 62 | github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= 63 | github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= 64 | github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= 65 | github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= 66 | github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= 67 | github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4= 68 | github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= 69 | github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= 70 | github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= 71 | github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= 72 | github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= 73 | github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= 74 | github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= 75 | github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= 76 | github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= 77 | github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= 78 | github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= 79 | github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= 80 | github.com/onsi/gomega v1.16.0 h1:6gjqkI8iiRHMvdccRJM8rVKjCWk6ZIm6FTm3ddIe4/c= 81 | github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= 82 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 83 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 84 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 85 | github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= 86 | github.com/rivo/uniseg v0.3.4 h1:3Z3Eu6FGHZWSfNKJTOUiPatWwfc7DzJRU04jFUqJODw= 87 | github.com/rivo/uniseg v0.3.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= 88 | github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= 89 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 90 | github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= 91 | github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 92 | github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= 93 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 94 | github.com/tufanbarisyildirim/gonginx v0.0.0-20220829083426-44da4d61ef9a h1:UGvkOP/bikNA5olcJYWl7vPFIZljRaG//vuXPINI5wY= 95 | github.com/tufanbarisyildirim/gonginx v0.0.0-20220829083426-44da4d61ef9a/go.mod h1:+uQMU+LMBHOQermcm/ICplG+r35Ypb6Up9iYKlvKuTE= 96 | github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 97 | github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= 98 | go.opentelemetry.io/otel v1.0.0 h1:qTTn6x71GVBvoafHK/yaRUmFzI4LcONZD0/kXxl5PHI= 99 | go.opentelemetry.io/otel v1.0.0/go.mod h1:AjRVh9A5/5DE7S+mZtTR6t8vpKKryam+0lREnfmS4cg= 100 | go.opentelemetry.io/otel/sdk v1.0.0 h1:BNPMYUONPNbLneMttKSjQhOTlFLOD9U22HNG1KrIN2Y= 101 | go.opentelemetry.io/otel/sdk v1.0.0/go.mod h1:PCrDHlSy5x1kjezSdL37PhbFUMjrsLRshJ2zCzeXwbM= 102 | go.opentelemetry.io/otel/trace v1.0.0 h1:TSBr8GTEtKevYMG/2d21M989r5WJYVimhTHBKVEZuh4= 103 | go.opentelemetry.io/otel/trace v1.0.0/go.mod h1:PXTWqayeFUlJV1YDNhsJYB184+IvAH814St6o6ajzIs= 104 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 105 | golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 106 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 107 | golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 108 | golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 109 | golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 110 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 111 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 112 | golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 113 | golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= 114 | golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= 115 | golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 116 | golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 117 | golang.org/x/net v0.0.0-20220812174116-3211cb980234 h1:RDqmgfe7SvlMWoqC3xwQ2blLO3fcWcxMa3eBLRdRW7E= 118 | golang.org/x/net v0.0.0-20220812174116-3211cb980234/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= 119 | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 120 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 121 | golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 122 | golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 123 | golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 124 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 125 | golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 126 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 127 | golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 128 | golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 129 | golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 130 | golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 131 | golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 132 | golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 133 | golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 134 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 135 | golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 136 | golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 137 | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 138 | golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 139 | golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 140 | golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 141 | golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 142 | golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 143 | golang.org/x/sys v0.0.0-20220817070843-5a390386f1f2 h1:fqTvyMIIj+HRzMmnzr9NtpHP6uVpvB5fkHcgPDC4nu8= 144 | golang.org/x/sys v0.0.0-20220817070843-5a390386f1f2/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 145 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 146 | golang.org/x/term v0.0.0-20210503060354-a79de5458b56/go.mod h1:tfny5GFUkzUvx4ps4ajbZsCe5lw1metzhBm9T3x7oIY= 147 | golang.org/x/term v0.0.0-20220722155259-a9ba230a4035 h1:Q5284mrmYTpACcm+eAKjKJH48BBwSyfJqmmGDTtT8Vc= 148 | golang.org/x/term v0.0.0-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= 149 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 150 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 151 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 152 | golang.org/x/text v0.3.8-0.20211105212822-18b340fc7af2 h1:GLw7MR8AfAG2GmGcmVgObFOHXYypgGjnGno25RDwn3Y= 153 | golang.org/x/text v0.3.8-0.20211105212822-18b340fc7af2/go.mod h1:EFNZuWvGYxIRUEX+K8UmCFwYmZjqcrnq15ZuVldZkZ0= 154 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 155 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 156 | golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= 157 | golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= 158 | golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= 159 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 160 | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 161 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 162 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 163 | google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= 164 | google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= 165 | google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= 166 | google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= 167 | google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= 168 | google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 169 | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= 170 | google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= 171 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= 172 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 173 | gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= 174 | gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= 175 | gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= 176 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 177 | gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 178 | gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 179 | gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= 180 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= 181 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 182 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= 183 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 184 | gotest.tools/v3 v3.2.0 h1:I0DwBVMGAx26dttAj1BtJLAkVGncrkkUXfJLC4Flt/I= 185 | gotest.tools/v3 v3.2.0/go.mod h1:Mcr9QNxkg0uMvy/YElmo4SpXgJKWgQvYrT7Kw5RzJ1A= 186 | -------------------------------------------------------------------------------- /assistant/internal/cmd/docker_cmd.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "os" 7 | "strings" 8 | 9 | "assistant/utility" 10 | "github.com/AlecAivazis/survey/v2" 11 | "github.com/gogf/gf/v2/os/gcmd" 12 | "github.com/gogf/gf/v2/os/gproc" 13 | ) 14 | 15 | var ( 16 | UpCmd = &gcmd.Command{ 17 | Name: "up", 18 | Usage: "xii up -参数", 19 | Brief: "封装docker-compose up 命令,\n\n首次使用请执行: xii up -h 查看下使用说明。", 20 | Examples: `# 创建并且启动所有容器: xii up 21 | # 创建并且(后台运行方式)启动所有容器: xii up -d 22 | # 创建并且启动nginx、php、mysql的多个容器: xii up -php -nginx -mysql 23 | # 创建并且(后台运行方式)启动nginx、php、mysql的多个容器: xii up -d -php -nginx -mysql 24 | `, 25 | Func: func(ctx context.Context, parser *gcmd.Parser) (err error) { 26 | dockerComposeRun("up", parser) 27 | return nil 28 | }, 29 | } 30 | 31 | StartCmd = &gcmd.Command{ 32 | Name: "start", 33 | Usage: "xii start -容器名", 34 | Brief: "封装docker-compose start 命令,启动服务。范例:xii start -php \n", 35 | Func: func(ctx context.Context, parser *gcmd.Parser) (err error) { 36 | dockerComposeRun("start", parser) 37 | return nil 38 | }, 39 | } 40 | 41 | StopCmd = &gcmd.Command{ 42 | Name: "stop", 43 | Usage: "xii stop -容器名", 44 | Brief: "封装docker-compose stop 命令,停止指定容器服务。范例:xii stop -php\n", 45 | Func: func(ctx context.Context, parser *gcmd.Parser) (err error) { 46 | dockerComposeRun("stop", parser) 47 | return nil 48 | }, 49 | } 50 | RestartCmd = &gcmd.Command{ 51 | Name: "restart", 52 | Usage: "xii restart -容器名", 53 | Brief: "封装docker-compose stop 命令,重启指定容器服务。范例:xii restart -php\n", 54 | Func: func(ctx context.Context, parser *gcmd.Parser) (err error) { 55 | dockerComposeRun("restart", parser) 56 | return nil 57 | }, 58 | } 59 | 60 | BuildCmd = &gcmd.Command{ 61 | Name: "build", 62 | Usage: "xii build -容器名", 63 | Brief: "封装docker-compose build 命令,构建或者重新构建服务。范例:xii build -php\n-\n-\n---------以下为快速进入某个容器内部的快捷方法-------\n-", 64 | Func: func(ctx context.Context, parser *gcmd.Parser) (err error) { 65 | dockerComposeRun("build", parser) 66 | return nil 67 | }, 68 | } 69 | 70 | RmCmd = &gcmd.Command{ 71 | Name: "rm", 72 | Usage: "xii rm -容器名", 73 | Brief: "封装docker-compose rm 命令,删除并且停止php容器。但不会删除挂载的数据卷\n", 74 | Func: func(ctx context.Context, parser *gcmd.Parser) (err error) { 75 | dockerComposeRun("rm", parser) 76 | return nil 77 | }, 78 | } 79 | RmAllCmd = &gcmd.Command{ 80 | Name: "rmall", 81 | Usage: "xii rmall", 82 | Brief: "停止并删除所有容器、所有镜像,但不会删除挂载的数据卷.\n", 83 | Func: func(ctx context.Context, parser *gcmd.Parser) (err error) { 84 | 85 | // 二次确认 86 | confirm := false 87 | survey.AskOne(&survey.Confirm{ 88 | Message: "确定要删除所有容器、所有镜像吗?", 89 | Default: false, 90 | }, &confirm) 91 | if !confirm { 92 | fmt.Println("取消删除") 93 | os.Exit(0) 94 | } 95 | 96 | // 停止所有的容器 97 | r, e := gproc.ShellExec(`docker stop $(docker ps -aq)`) 98 | if e != nil { 99 | fmt.Println(e.Error()) 100 | os.Exit(1) 101 | } 102 | fmt.Println(r) 103 | 104 | // 删除所有的容器 105 | r, e = gproc.ShellExec(`docker rm $(docker ps -aq)`) 106 | if e != nil { 107 | fmt.Println(e.Error()) 108 | os.Exit(1) 109 | } 110 | fmt.Println(r) 111 | 112 | // 删除所有的镜像 113 | r, e = gproc.ShellExec(`docker rmi $(docker images -q)`) 114 | if e != nil { 115 | fmt.Println(e.Error()) 116 | os.Exit(1) 117 | } 118 | fmt.Println(r) 119 | os.Exit(0) 120 | return nil 121 | }, 122 | } 123 | 124 | DownCmd = &gcmd.Command{ 125 | Name: "down", 126 | Usage: "xii down", 127 | Brief: "封装docker-compose down 命令,停止并删除容器,网络,图像。注意:不会删除挂载的数据卷。\n", 128 | Func: func(ctx context.Context, parser *gcmd.Parser) (err error) { 129 | dockerComposeRun("down", parser) 130 | return nil 131 | }, 132 | } 133 | 134 | RebuildCmd = &gcmd.Command{ 135 | Name: "rebuild", 136 | Usage: "xii rebuild -容器名", 137 | Brief: "重现编译某指定容器,用于在修改docker-compose.yml后。\n", 138 | Func: func(ctx context.Context, parser *gcmd.Parser) (err error) { 139 | 140 | // 获取参数 141 | om := parser.GetOptAll() 142 | containers := []string{} 143 | imagesIds := []string{} 144 | if len(om) >= 0 { 145 | for k, _ := range om { 146 | containers = append(containers, k) 147 | // 获取镜像id 148 | iid, _ := gproc.ShellExec(`docker ps -a| grep ` + k + ` | awk '{print $2}'`) 149 | if iid != "" { 150 | imagesIds = append(imagesIds, iid) 151 | } 152 | } 153 | } 154 | if len(containers) == 0 { 155 | fmt.Println("请输入一个或以上的容器名") 156 | os.Exit(1) 157 | } 158 | containersStr := strings.Join(containers, " ") 159 | imagesIdsStr := strings.Join(imagesIds, " ") 160 | 161 | // 停止所有的容器 162 | fmt.Println("开始停止容器:" + containersStr) 163 | r, e := gproc.ShellExec(`docker stop ` + containersStr) 164 | if e != nil { 165 | fmt.Println("停止容器(container)失败,失败原因:" + e.Error()) 166 | os.Exit(1) 167 | } 168 | fmt.Println(r) 169 | 170 | // 删除所有的容器 171 | fmt.Println("开始删除容器:" + containersStr) 172 | r, e = gproc.ShellExec(`docker rm ` + containersStr) 173 | if e != nil { 174 | fmt.Println("删除容器(container)失败,失败原因:" + e.Error()) 175 | os.Exit(1) 176 | } 177 | fmt.Println(r) 178 | 179 | // 删除所有的镜像 180 | fmt.Println("开始停止容器对应镜像:" + containersStr) 181 | r, e = gproc.ShellExec(`docker rmi ` + imagesIdsStr) 182 | if e != nil { 183 | fmt.Println("删除镜像(images)失败,执行命令:" + `docker rmi ` + imagesIdsStr) 184 | os.Exit(1) 185 | } 186 | 187 | // 重新编译 188 | fmt.Println("开始") 189 | doker := utility.Docker{} 190 | argSlice := []string{"-d", "--no-deps", "--build"} 191 | argSlice = append(argSlice, containers...) 192 | doker.DockerActionShell("up", argSlice) 193 | fmt.Println("重新编译完成") 194 | os.Exit(0) 195 | return nil 196 | }, 197 | } 198 | 199 | PsCmd = &gcmd.Command{ 200 | Name: "ps", 201 | Usage: "xii ps", 202 | Brief: "封装docker ps 命令,经常顺手操作,所以封装一下。\n", 203 | Func: func(ctx context.Context, parser *gcmd.Parser) (err error) { 204 | dockerRun("ps", parser) 205 | return nil 206 | }, 207 | } 208 | ) 209 | 210 | // 执行docker-compose命令参数 211 | func dockerComposeRun(typ string, parser *gcmd.Parser) { 212 | // 获取参数 213 | om := parser.GetOptAll() 214 | d := "" 215 | containers := []string{} 216 | if len(om) >= 0 { 217 | for k, _ := range om { 218 | if "d" == strings.ToLower(k) { 219 | d = "-d" 220 | } else { 221 | containers = append(containers, k) 222 | } 223 | 224 | } 225 | } 226 | 227 | dstr := []string{} 228 | if d != "" { 229 | dstr = append(dstr, "-d") 230 | } 231 | 232 | if len(containers) > 0 { 233 | dstr = append(dstr, containers...) 234 | } 235 | 236 | docker := utility.Docker{} 237 | docker.Auto() 238 | docker.DockerActionShell(typ, dstr) 239 | } 240 | 241 | // 执行docker命令参数 242 | func dockerRun(typ string, parser *gcmd.Parser) { 243 | // 获取参数 244 | om := parser.GetOptAll() 245 | containers := []string{} 246 | if len(om) >= 0 { 247 | for k, _ := range om { 248 | containers = append(containers, "-"+k) 249 | } 250 | } 251 | docker := utility.Docker{} 252 | docker.Auto() 253 | docker.DockerActionShell(typ, containers) 254 | } 255 | -------------------------------------------------------------------------------- /assistant/internal/cmd/docker_quick_cmd.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "os" 7 | "strings" 8 | 9 | "assistant/utility" 10 | "github.com/AlecAivazis/survey/v2" 11 | "github.com/gogf/gf/v2/os/gcmd" 12 | ) 13 | 14 | var ( 15 | NginxCmd = &gcmd.Command{ 16 | Name: "nginx", 17 | Usage: "xii nginx", 18 | Brief: "快速进入nginx容器", 19 | Func: func(ctx context.Context, parser *gcmd.Parser) (err error) { 20 | utility.Enter("nginx") 21 | return nil 22 | }, 23 | } 24 | 25 | ContainerCmd = &gcmd.Command{ 26 | Name: "go", 27 | Usage: "xii go", 28 | Brief: "快速进入容器, 直接xii go 将罗列所有存活容器选择,可以xii go -关键字 加以过滤,缩小选择范围.\n部分容器的入口不是/bin/sh,则会进入失败", 29 | Func: func(ctx context.Context, parser *gcmd.Parser) (err error) { 30 | om := parser.GetOptAll() 31 | keyword := "" 32 | if len(om) >= 0 { 33 | for k, _ := range om { 34 | keyword = k 35 | } 36 | } 37 | 38 | d := utility.Docker{} 39 | d.Auto() 40 | s, e := d.ContainerName() 41 | if e != nil { 42 | fmt.Println(e.Error()) 43 | } 44 | s2 := []string{} 45 | if len(s) > 0 { 46 | for _, v := range s { 47 | if utility.IsContainerLive(v) { 48 | if keyword != "" { 49 | if strings.Contains(v, keyword) { 50 | s2 = append(s2, v) 51 | } 52 | } else { 53 | s2 = append(s2, v) 54 | } 55 | } 56 | } 57 | } 58 | 59 | if len(s2) == 0 { 60 | fmt.Println("没找到存活的容器,无法进入") 61 | os.Exit(1) 62 | return nil 63 | } 64 | 65 | if len(s2) == 1 { 66 | utility.Enter(s2[0]) 67 | } else { 68 | c := "" 69 | alf := &survey.Select{ 70 | Message: "请选择容器进入:", 71 | Options: s2, 72 | } 73 | survey.AskOne(alf, &c) 74 | utility.Enter(c) 75 | } 76 | 77 | return nil 78 | }, 79 | } 80 | 81 | PhpCmd = &gcmd.Command{ 82 | Name: "php", 83 | Usage: "xii php", 84 | Brief: "快速进入*php*容器,多项目时需选择", 85 | Func: func(ctx context.Context, parser *gcmd.Parser) (err error) { 86 | QuickEnter("php") 87 | return nil 88 | }, 89 | } 90 | 91 | MysqlCmd = &gcmd.Command{ 92 | Name: "mysql", 93 | Usage: "xii mysql", 94 | Brief: "快速进入mysql*容器,多项目时需选择", 95 | Func: func(ctx context.Context, parser *gcmd.Parser) (err error) { 96 | QuickEnter("mysql") 97 | return nil 98 | }, 99 | } 100 | 101 | RedisCmd = &gcmd.Command{ 102 | Name: "redis", 103 | Usage: "xii redis", 104 | Brief: "快速进入*redis*容器,多项目时需选择", 105 | Func: func(ctx context.Context, parser *gcmd.Parser) (err error) { 106 | QuickEnter("redis") 107 | return nil 108 | }, 109 | } 110 | 111 | SupervisorCmd = &gcmd.Command{ 112 | Name: "supervisor", 113 | Usage: "xii supervisor", 114 | Brief: "快速进入*supervisor*容器,多项目时需选择", 115 | Func: func(ctx context.Context, parser *gcmd.Parser) (err error) { 116 | QuickEnter("supervisor") 117 | return nil 118 | }, 119 | } 120 | 121 | MongodbCmd = &gcmd.Command{ 122 | Name: "mongodb", 123 | Usage: "xii mongodb", 124 | Brief: "快速进入*mongodb*容器,多项目时需选择", 125 | Func: func(ctx context.Context, parser *gcmd.Parser) (err error) { 126 | QuickEnter("mongodb") 127 | return nil 128 | }, 129 | } 130 | 131 | NodeCmd = &gcmd.Command{ 132 | Name: "node", 133 | Usage: "xii node", 134 | Brief: "快速进入*node*容器,多项目时需选择", 135 | Func: func(ctx context.Context, parser *gcmd.Parser) (err error) { 136 | QuickEnter("node") 137 | return nil 138 | }, 139 | } 140 | 141 | GoCmd = &gcmd.Command{ 142 | Name: "golang", 143 | Usage: "xii golang", 144 | Brief: "快速进入*golang*容器,多项目时需选择", 145 | Func: func(ctx context.Context, parser *gcmd.Parser) (err error) { 146 | QuickEnter("go") 147 | return nil 148 | }, 149 | } 150 | 151 | EsCmd = &gcmd.Command{ 152 | Name: "elasticsearch", 153 | Usage: "xii es", 154 | Brief: "快速进入*elasticsearch*容器,多项目时需选择", 155 | Func: func(ctx context.Context, parser *gcmd.Parser) (err error) { 156 | QuickEnter("elasticsearch") 157 | return nil 158 | }, 159 | } 160 | 161 | KibanaCmd = &gcmd.Command{ 162 | Name: "kibana", 163 | Usage: "xii kibana", 164 | Brief: "快速进入*elasticsearch*容器,多项目时需选择", 165 | Func: func(ctx context.Context, parser *gcmd.Parser) (err error) { 166 | QuickEnter("kibana") 167 | return nil 168 | }, 169 | } 170 | 171 | LogstashCmd = &gcmd.Command{ 172 | Name: "logstash", 173 | Usage: "xii logstash", 174 | Brief: "快速进入*logstash*容器,多项目时需选择", 175 | Func: func(ctx context.Context, parser *gcmd.Parser) (err error) { 176 | QuickEnter("logstash") 177 | return nil 178 | }, 179 | } 180 | ) 181 | 182 | // QuickEnter 快入进入一个指定的容器 183 | func QuickEnter(keyword string) { 184 | d := utility.Docker{} 185 | s, e := d.ContainerName() 186 | if e != nil { 187 | fmt.Println(e.Error()) 188 | } 189 | s2 := []string{} 190 | if len(s) > 0 { 191 | for _, v := range s { 192 | if utility.IsContainerLive(v) { 193 | if strings.Contains(v, keyword) { 194 | s2 = append(s2, v) 195 | } 196 | } 197 | } 198 | } 199 | 200 | if len(s2) == 0 { 201 | fmt.Println("没找到存活的" + keyword + "容器,无法进入") 202 | os.Exit(1) 203 | } 204 | 205 | if len(s2) == 1 { 206 | utility.Enter(s2[0]) 207 | } else { 208 | c := "" 209 | alf := &survey.Select{ 210 | Message: "请选择容器进入:", 211 | Options: s2, 212 | } 213 | survey.AskOne(alf, &c) 214 | utility.Enter(c) 215 | } 216 | } 217 | -------------------------------------------------------------------------------- /assistant/internal/cmd/init_cmd.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "os" 7 | 8 | "assistant/utility" 9 | "github.com/AlecAivazis/survey/v2" 10 | "github.com/gogf/gf/v2/os/gcmd" 11 | "github.com/gogf/gf/v2/os/gfile" 12 | "github.com/gogf/gf/v2/text/gstr" 13 | ) 14 | 15 | var ( 16 | InitCmd = &gcmd.Command{ 17 | Name: "init", 18 | Usage: "xii init", 19 | Brief: "可多次选择所需的镜像容器组件。该命令不删任何生产数据。", 20 | Func: func(ctx context.Context, parser *gcmd.Parser) (err error) { 21 | 22 | // 检索仓库模板 23 | p := utility.GetInstallDir() + "/repo" 24 | c := []string{} 25 | rset, _ := gfile.ScanDir(p, "*") 26 | for _, v := range rset { 27 | v2 := gfile.Basename(v) 28 | if v2 != "base" && gfile.IsDir(v) { 29 | c = append(c, v2) 30 | } 31 | } 32 | 33 | // 选择区块 34 | defaultSelect := utility.GetExistDockerFile() 35 | cSlice := []string{} 36 | alf := &survey.MultiSelect{ 37 | Message: " 请选择你所需的镜像容器组件,他将重新生成配置文件。\n 如果已经在用的镜像,将保存现有配置。!\n", 38 | PageSize: 20, 39 | Options: c, 40 | Default: defaultSelect, 41 | } 42 | survey.AskOne(alf, &cSlice) 43 | 44 | fmt.Println("你选择的容器组件是:" + gstr.Join(cSlice, ",")) 45 | 46 | utility.GenerateDockerComposeFile(cSlice) 47 | utility.GenerateEnvFile(cSlice) 48 | utility.CopyDirIfExist(cSlice) 49 | 50 | fmt.Println("\n\n") 51 | fmt.Println("------------------") 52 | fmt.Println("初始化/修改完成") 53 | fmt.Println("注 意:谨慎起见,移除容器组件不会删除已经存在的数据,你需要手动删除数据和容器/镜像") 54 | fmt.Println("建议1:【第一次初始化】,请执行:xii up 或 xii up -d 来启动容器实例") 55 | fmt.Println("建议2:【新增】容器组件的,可以执行 xii up -容器组件 来单独启动容器组件,或者 xii up 直接启动所有容器组件,已存活的容器组件将被忽略") 56 | fmt.Println("建议3:【移除】容器组件的,可以执行 xii stop -容器组件 来停止容器组件,然后执行 xii rm -容器组件 来移除容器/镜像,然后手动删除配置文件,数据文件等(/data,/env/容器组件名)") 57 | fmt.Println("------------------") 58 | fmt.Println("\n\n") 59 | 60 | os.Exit(0) 61 | return nil 62 | }, 63 | } 64 | 65 | InitClearCmd = &gcmd.Command{ 66 | Name: "clear", 67 | Usage: "xii clear", 68 | Brief: "清理镜像除配置外的所有数据\n-\n-\n---------以下为封装docker-compose/docker相关命令---------\n封装原因是:docker-compose通常需要进入目录或带-f参数,操作过于麻烦。\n使用上注意所有容器名字需要带-,比如php容器就写做-php。\n-", 69 | Func: func(ctx context.Context, parser *gcmd.Parser) (err error) { 70 | 71 | // 一期限定 72 | basePath := utility.GetInstallDir() 73 | 74 | op := false 75 | alf := &survey.Confirm{ 76 | Message: "确认清理镜像除配置外的所有数据?\n 他将清理掉data/目录、www/目录、logs/目录下的所有数据。\n 原理是删除后重建,操作不可逆,请谨慎选择!", 77 | Default: false, 78 | } 79 | survey.AskOne(alf, &op) 80 | if op { 81 | gfile.Remove(gfile.Join(basePath, "data/")) 82 | gfile.Remove(gfile.Join(basePath, "logs/")) 83 | gfile.Remove(gfile.Join(basePath, "www/")) 84 | gfile.Mkdir(gfile.Join(basePath, "data/")) 85 | gfile.Mkdir(gfile.Join(basePath, "logs/")) 86 | gfile.Mkdir(gfile.Join(basePath, "www/")) 87 | 88 | fmt.Println("清理完成! 请重新启动镜像") 89 | } 90 | 91 | return nil 92 | }, 93 | } 94 | ) 95 | -------------------------------------------------------------------------------- /assistant/internal/cmd/vhost_cmd.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "os" 7 | 8 | "assistant/utility" 9 | "github.com/AlecAivazis/survey/v2" 10 | "github.com/gogf/gf/v2/os/gcmd" 11 | "github.com/gogf/gf/v2/os/gfile" 12 | ) 13 | 14 | var ( 15 | VhostCmd = &gcmd.Command{ 16 | Name: "vhost", 17 | Usage: "新增网站:xii vhost -add 删除网站:xii vhost -del 查看所有网站:xii vhost -list", 18 | Brief: "新增、删除、罗列所有网站", 19 | Func: func(ctx context.Context, parser *gcmd.Parser) (err error) { 20 | fmt.Println("") 21 | fmt.Println("为名为nginx的容器增删查网站。\n注意,如需修改具体网站nginx配置,请自己编辑nginx配置文件。一般配置文件地址为:env/nginx/vhost/域名.conf") 22 | fmt.Println("用法:") 23 | fmt.Println(" 新增网站:xii vhost add") 24 | fmt.Println(" 删除网站:xii vhost del") 25 | fmt.Println(" 查看所有网站:xii vhost list") 26 | fmt.Println("") 27 | return nil 28 | }, 29 | } 30 | VhostAddCmd = &gcmd.Command{ 31 | Name: "add", 32 | Usage: "新增网站: xii vhost add", 33 | Brief: "新增网站", 34 | Func: func(ctx context.Context, parser *gcmd.Parser) (err error) { 35 | v, e := utility.AskForVhost() 36 | if e != nil { 37 | fmt.Println(e.Error()) 38 | } 39 | v.AddVhost() 40 | return nil 41 | }, 42 | } 43 | VhostDelCmd = &gcmd.Command{ 44 | Name: "del", 45 | Usage: "删除网站(只删除nginx配置信息,日志): xii vhost del", 46 | Brief: "删除网站", 47 | Func: func(ctx context.Context, parser *gcmd.Parser) (err error) { 48 | none := "不删除任何网站" 49 | websites := []string{none} 50 | site := "" 51 | rset, _ := gfile.ScanDir(utility.GetInstallDir()+"/env/nginx/vhost", "*.conf") 52 | for _, v := range rset { 53 | websites = append(websites, gfile.Name(v)) 54 | } 55 | alf := &survey.Select{ 56 | Message: "请选择一个网站进行删除:", 57 | Options: websites, 58 | } 59 | survey.AskOne(alf, &site) 60 | if site == none { 61 | fmt.Println("你已取消操作") 62 | os.Exit(0) 63 | } 64 | 65 | gfile.Remove(utility.GetInstallDir() + "/env/nginx/vhost/" + site + ".conf") 66 | gfile.Remove(utility.GetInstallDir() + "env/nginx/ssl/" + site) 67 | gfile.Remove(utility.GetInstallDir() + "logs/nginx/" + site) 68 | fmt.Println("删除网站成功,如需删除网站文件,请自行删除") 69 | 70 | return nil 71 | }, 72 | } 73 | VhostListCmd = &gcmd.Command{ 74 | Name: "list", 75 | Usage: "查看所有网站: xii vhost list", 76 | Brief: "查看所有网站", 77 | Func: func(ctx context.Context, parser *gcmd.Parser) (err error) { 78 | // rewriteRules := []string{"none"} 79 | rset, _ := gfile.ScanDir(utility.GetInstallDir()+"env/nginx/vhost", "*.conf") 80 | for _, v := range rset { 81 | // rewriteRules = append(rewriteRules, gfile.Name(v)) 82 | fmt.Println(gfile.Name(v)) 83 | } 84 | return nil 85 | }, 86 | } 87 | ) 88 | -------------------------------------------------------------------------------- /assistant/internal/consts/consts.go: -------------------------------------------------------------------------------- 1 | package consts 2 | -------------------------------------------------------------------------------- /assistant/internal/controller/hello.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/gogf/gf/v2/frame/g" 7 | 8 | "core/api/v1" 9 | ) 10 | 11 | var ( 12 | Hello = cHello{} 13 | ) 14 | 15 | type cHello struct{} 16 | 17 | func (c *cHello) Hello(ctx context.Context, req *v1.HelloReq) (res *v1.HelloRes, err error) { 18 | g.RequestFromCtx(ctx).Response.Writeln("Hello World!") 19 | return 20 | } 21 | -------------------------------------------------------------------------------- /assistant/internal/model/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiiapp/xii/7d7c08c767774fb203b6289d901ee026c613510f/assistant/internal/model/.gitkeep -------------------------------------------------------------------------------- /assistant/internal/model/entity/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiiapp/xii/7d7c08c767774fb203b6289d901ee026c613510f/assistant/internal/model/entity/.gitkeep -------------------------------------------------------------------------------- /assistant/internal/packed/packed.go: -------------------------------------------------------------------------------- 1 | package packed 2 | -------------------------------------------------------------------------------- /assistant/internal/service/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiiapp/xii/7d7c08c767774fb203b6289d901ee026c613510f/assistant/internal/service/.gitkeep -------------------------------------------------------------------------------- /assistant/internal/service/internal/dao/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiiapp/xii/7d7c08c767774fb203b6289d901ee026c613510f/assistant/internal/service/internal/dao/.gitkeep -------------------------------------------------------------------------------- /assistant/internal/service/internal/do/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiiapp/xii/7d7c08c767774fb203b6289d901ee026c613510f/assistant/internal/service/internal/do/.gitkeep -------------------------------------------------------------------------------- /assistant/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "os/signal" 7 | "syscall" 8 | 9 | "assistant/internal/cmd" 10 | "github.com/gogf/gf/v2/os/gcmd" 11 | "github.com/gogf/gf/v2/os/gctx" 12 | ) 13 | 14 | var ( 15 | Main = &gcmd.Command{ 16 | Name: "main", 17 | Brief: "XII助手", 18 | Description: "XII助手:管理网站新增/删除/罗列,以及封装docker的快捷操作方式", 19 | } 20 | ) 21 | 22 | func main() { 23 | SetupCloseHandler() 24 | 25 | // vhost 管理相关 26 | vhostCmd := cmd.VhostCmd 27 | vhostCmd.AddCommand(cmd.VhostAddCmd, cmd.VhostDelCmd, cmd.VhostListCmd) 28 | Main.AddCommand(vhostCmd, cmd.DbCmd, cmd.InitCmd, cmd.RebuildCmd, cmd.InitClearCmd) 29 | 30 | Main.AddCommand(cmd.PsCmd, cmd.RmAllCmd) 31 | Main.AddCommand(cmd.UpCmd, cmd.DownCmd, cmd.StartCmd, cmd.StopCmd, cmd.RestartCmd, cmd.RmCmd, cmd.BuildCmd) 32 | 33 | // docker 便捷操作 34 | Main.AddCommand(cmd.ContainerCmd) 35 | Main.AddCommand(cmd.NginxCmd, cmd.PhpCmd, cmd.MysqlCmd, cmd.MongodbCmd, cmd.RedisCmd, cmd.SupervisorCmd, cmd.EsCmd, cmd.KibanaCmd, cmd.LogstashCmd, cmd.NodeCmd, cmd.GoCmd) 36 | 37 | Main.Run(gctx.New()) 38 | 39 | } 40 | 41 | // SetupCloseHandler 42 | // ref:twle.cn/t/381 43 | func SetupCloseHandler() { 44 | c := make(chan os.Signal, 2) 45 | signal.Notify(c, os.Interrupt, syscall.SIGTERM) 46 | go func() { 47 | <-c 48 | fmt.Println("\r- Ctrl+C pressed in Terminal") 49 | os.Exit(0) 50 | }() 51 | } 52 | -------------------------------------------------------------------------------- /assistant/manifest/config/config.yaml: -------------------------------------------------------------------------------- 1 | server: 2 | address: ":8000" 3 | # openapiPath: "/api.json" 4 | # swaggerPath: "/swagger" 5 | 6 | logger: 7 | level : "all" 8 | stdout: true 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /assistant/manifest/deploy/kustomize/base/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: template-single 5 | labels: 6 | app: template-single 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: template-single 12 | template: 13 | metadata: 14 | labels: 15 | app: template-single 16 | spec: 17 | containers: 18 | - name : main 19 | image: template-single 20 | imagePullPolicy: Always 21 | 22 | -------------------------------------------------------------------------------- /assistant/manifest/deploy/kustomize/base/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | resources: 4 | - deployment.yaml 5 | - service.yaml 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /assistant/manifest/deploy/kustomize/base/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: template-single 5 | spec: 6 | ports: 7 | - port: 80 8 | protocol: TCP 9 | targetPort: 8000 10 | selector: 11 | app: template-single 12 | 13 | -------------------------------------------------------------------------------- /assistant/manifest/deploy/kustomize/overlays/develop/configmap.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: template-single-configmap 5 | data: 6 | config.yaml: | 7 | server: 8 | address: ":8000" 9 | openapiPath: "/api.json" 10 | swaggerPath: "/swagger" 11 | 12 | logger: 13 | level : "all" 14 | stdout: true 15 | -------------------------------------------------------------------------------- /assistant/manifest/deploy/kustomize/overlays/develop/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: template-single 5 | spec: 6 | template: 7 | spec: 8 | containers: 9 | - name : main 10 | image: template-single:develop -------------------------------------------------------------------------------- /assistant/manifest/deploy/kustomize/overlays/develop/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | 4 | resources: 5 | - ../../base 6 | - configmap.yaml 7 | 8 | patchesStrategicMerge: 9 | - deployment.yaml 10 | 11 | namespace: default 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /assistant/manifest/docker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM loads/alpine:3.8 2 | 3 | ############################################################################### 4 | # INSTALLATION 5 | ############################################################################### 6 | 7 | ENV WORKDIR /app 8 | ADD resource $WORKDIR/ 9 | ADD ./temp/linux_amd64/main $WORKDIR/main 10 | RUN chmod +x $WORKDIR/main 11 | 12 | ############################################################################### 13 | # START 14 | ############################################################################### 15 | WORKDIR $WORKDIR 16 | CMD ./main 17 | -------------------------------------------------------------------------------- /assistant/manifest/docker/docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This shell is executed before docker build. 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /assistant/readme.md: -------------------------------------------------------------------------------- 1 | # 助手程序 2 | 为整个环境提供一个辅助助手工具,用于协助用户快捷设置。 3 | 4 | 5 | 6 | ## 一期功能如下 7 | ```shell 8 | 用法 9 | xii 命令 [参数] 10 | 11 | 命令 12 | vhost 新增、删除、罗列所有网站 13 | clear 清理镜像除配置外的所有数据 14 | 15 | ---------以下为封装docker-compose相关命令--------- 16 | 封装原因是:docker-compose通常需要进入目录或带-f参数,操作过于麻烦。 17 | 使用上注意所有容器名字需要带-,比如php容器就写做-php。 18 | 19 | up 封装docker-compose up 命令, 20 | 首次使用请执行: xii up -h 查看下使用说明。 21 | down 封装docker-compose down 命令,停止并删除容器,网络,图像和挂载卷 22 | start 封装docker-compose start 命令,启动服务。范例:xii start -php 23 | stop 封装docker-compose stop 命令,停止指定容器服务。范例:xii stop -php 24 | restart 封装docker-compose stop 命令,重启指定容器服务。范例:xii restart -php 25 | rm 封装docker-compose rm 命令,删除并且停止php容器 26 | build 封装docker-compose build 命令,构建或者重新构建服务。范例:xii build -php 27 | 28 | 29 | ---------以下为快速进入某个容器内部的快捷方法------- 30 | 31 | go 快速进入容器, 直接xii go 将罗列所有存活容器选择,可以xii go -关键字加以过滤,缩小选择范围. 32 | 部分容器的入口不是/bin/sh,则会进入失败 33 | nginx 快速进入nginx容器 34 | php 快速进入*php*容器,多项目时需选择 35 | mysql 快速进入mysql*容器,多项目时需选择 36 | mongodb 快速进入*mongodb*容器,多项目时需选择 37 | redis 快速进入*redis*容器,多项目时需选择 38 | supervisor 快速进入*supervisor*容器,多项目时需选择 39 | elasticsearch 快速进入*elasticsearch*容器,多项目时需选择 40 | kibana 快速进入*elasticsearch*容器,多项目时需选择 41 | logstash 快速进入*logstash*容器,多项目时需选择 42 | node 快速进入*node*容器,多项目时需选择 43 | golang 快速进入*golang*容器,多项目时需选择 44 | 45 | ``` 46 | 47 | ## 二期功能如下 48 | - [ ] 安装任意位置 49 | - [ ] 自由选装组件 50 | - [ ] 多语言 51 | - [ ] 增加对常用的命令支持,比如mysql,sftp等 -------------------------------------------------------------------------------- /assistant/resource/i18n/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiiapp/xii/7d7c08c767774fb203b6289d901ee026c613510f/assistant/resource/i18n/.gitkeep -------------------------------------------------------------------------------- /assistant/resource/public/html/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiiapp/xii/7d7c08c767774fb203b6289d901ee026c613510f/assistant/resource/public/html/.gitkeep -------------------------------------------------------------------------------- /assistant/resource/public/plugin/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiiapp/xii/7d7c08c767774fb203b6289d901ee026c613510f/assistant/resource/public/plugin/.gitkeep -------------------------------------------------------------------------------- /assistant/resource/public/resource/css/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiiapp/xii/7d7c08c767774fb203b6289d901ee026c613510f/assistant/resource/public/resource/css/.gitkeep -------------------------------------------------------------------------------- /assistant/resource/public/resource/image/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiiapp/xii/7d7c08c767774fb203b6289d901ee026c613510f/assistant/resource/public/resource/image/.gitkeep -------------------------------------------------------------------------------- /assistant/resource/public/resource/js/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiiapp/xii/7d7c08c767774fb203b6289d901ee026c613510f/assistant/resource/public/resource/js/.gitkeep -------------------------------------------------------------------------------- /assistant/resource/template/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiiapp/xii/7d7c08c767774fb203b6289d901ee026c613510f/assistant/resource/template/.gitkeep -------------------------------------------------------------------------------- /assistant/utility/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiiapp/xii/7d7c08c767774fb203b6289d901ee026c613510f/assistant/utility/.gitkeep -------------------------------------------------------------------------------- /assistant/utility/container.go: -------------------------------------------------------------------------------- 1 | // Package main 2 | // @Description: docker 容器管理相关 3 | // 4 | 5 | package utility 6 | 7 | import ( 8 | "os" 9 | "os/exec" 10 | 11 | "github.com/gogf/gf/v2/os/gproc" 12 | "github.com/gogf/gf/v2/text/gstr" 13 | ) 14 | 15 | type Docker struct { 16 | ComposeFile string // docker-compose.yml文件路径,没有就默认是当前 17 | } 18 | 19 | func (d *Docker) Auto() { 20 | d.ComposeFile = GetDockerComposeFile() 21 | } 22 | 23 | // DockerAction 包装docker-compose命令 24 | // @Description: 容器实例操作 25 | // @example: 26 | // docker-compose up # 创建并且启动所有容器 27 | // docker-compose up -d # 创建并且后台运行方式启动所有容器 28 | // docker-compose up nginx php mysql # 创建并且启动nginx、php、mysql的多个容器 29 | // docker-compose up -d nginx php mysql # 创建并且已后台运行的方式启动nginx、php、mysql容器 30 | // docker-compose start php # 启动服务 31 | // docker-compose stop php # 停止服务 32 | // docker-compose restart php # 重启服务 33 | // docker-compose build php # 构建或者重新构建服务 34 | // docker-compose rm php # 删除并且停止php容器 35 | // docker-compose down # 停止并删除容器,网络,图像和挂载卷 36 | // @param action restart|stop|start|kill 37 | // @param container 38 | // @return string 39 | // @return error 40 | func (d *Docker) DockerAction(action string, arg string) (string, error) { 41 | if d.ComposeFile == "" { 42 | d.Auto() 43 | } 44 | if d.ComposeFile == "" { 45 | return gproc.ShellExec(`docker-compose ` + action + ` ` + arg) 46 | } else { 47 | return gproc.ShellExec(`docker-compose -f ` + d.ComposeFile + ` ` + action + ` ` + arg) 48 | } 49 | } 50 | 51 | func (d *Docker) DockerActionShell(action string, arg []string) { 52 | if d.ComposeFile == "" { 53 | d.Auto() 54 | } 55 | 56 | if d.ComposeFile == "" { 57 | argSlice := []string{action} 58 | argSlice = append(argSlice, arg...) 59 | cmd := exec.Command("docker-compose", argSlice...) 60 | cmd.Stdin = os.Stdin 61 | cmd.Stdout = os.Stdout 62 | cmd.Stderr = os.Stderr 63 | cmd.Run() 64 | 65 | } else { 66 | argSlice := []string{"-f", d.ComposeFile, action} 67 | argSlice = append(argSlice, arg...) 68 | // fmt.Println(argSlice) 69 | cmd := exec.Command("docker-compose", argSlice...) 70 | cmd.Stdin = os.Stdin 71 | cmd.Stdout = os.Stdout 72 | cmd.Stderr = os.Stderr 73 | cmd.Run() 74 | } 75 | } 76 | 77 | // 执行 docker xxxx 命令 78 | func (d *Docker) DockerCmd(arg []string) { 79 | cmd := exec.Command("docker", arg...) 80 | cmd.Stdin = os.Stdin 81 | cmd.Stdout = os.Stdout 82 | cmd.Stderr = os.Stderr 83 | cmd.Run() 84 | } 85 | 86 | // ContainerName 87 | // @Description: 获取所有容器名称,不管容器是否运行 88 | // @return []string 89 | // @return error 90 | func (d *Docker) ContainerName() ([]string, error) { 91 | if d.ComposeFile == "" { 92 | d.Auto() 93 | } 94 | r, e := gproc.ShellExec(`docker inspect --format='{{.Name}}' $( docker ps -aq --no-trunc) | cut -c2-`) 95 | if e != nil { 96 | return nil, e 97 | } 98 | result := gstr.SplitAndTrim(r, "\n") 99 | return result, nil 100 | } 101 | 102 | // IsContainerLive 检查容器是否正在运行 103 | func IsContainerLive(container string) bool { 104 | r, e := gproc.ShellExec(`docker ps -q -f "name=^` + container + `$"`) 105 | if e != nil { 106 | return false 107 | } 108 | if r == "" { 109 | return false 110 | } 111 | return true 112 | } 113 | 114 | // Enter 快捷进入某个容器 115 | func Enter(container string) { 116 | cmd := exec.Command("docker", "exec", "-it", container, "/bin/sh") 117 | cmd.Stdin = os.Stdin 118 | cmd.Stdout = os.Stdout 119 | cmd.Stderr = os.Stderr 120 | cmd.Run() 121 | } 122 | -------------------------------------------------------------------------------- /assistant/utility/dir.go: -------------------------------------------------------------------------------- 1 | package utility 2 | 3 | import ( 4 | "log" 5 | "os/user" 6 | "runtime" 7 | ) 8 | 9 | // GetInstallDir 获取系统安装目录 10 | func GetInstallDir() string { 11 | 12 | // for dev 13 | // return "/Users/mou/goProjects/xii" 14 | 15 | switch runtime.GOOS { 16 | case "darwin": 17 | u, err := user.Current() 18 | if err != nil { 19 | log.Fatal(err) 20 | } 21 | return u.HomeDir + "/xii" 22 | case "linux": 23 | return "/home/xii" 24 | } 25 | return "暂未支持" 26 | } 27 | 28 | func GetDockerComposeFile() string { 29 | return GetInstallDir() + "/docker-compose.yml" 30 | } 31 | 32 | func GetEnvFile() string { 33 | return GetInstallDir() + "/.env" 34 | } 35 | -------------------------------------------------------------------------------- /assistant/utility/init.go: -------------------------------------------------------------------------------- 1 | // Package utility 2 | // @Description: 生成配置文件/目录 3 | // 4 | package utility 5 | 6 | import ( 7 | "fmt" 8 | "os" 9 | "strings" 10 | 11 | "github.com/gogf/gf/v2/os/gfile" 12 | "github.com/gogf/gf/v2/text/gregex" 13 | "github.com/gogf/gf/v2/text/gstr" 14 | ) 15 | 16 | // GenerateDockerComposeFile 生成docker-compose.yml 17 | func GenerateDockerComposeFile(components []string) { 18 | p := GetInstallDir() 19 | // for dev 20 | existDcMap := parseDockerComposeFileOrEnvFile(true) 21 | 22 | // pre-check 23 | if len(components) == 0 { 24 | fmt.Println("请指定需要生成的组件") 25 | os.Exit(0) 26 | } 27 | 28 | fmt.Println("正在生成docker-compose.yml...") 29 | cStr := []string{} 30 | gfile.ReadLines(p+"/repo/base/compose.yml", func(line string) error { 31 | cStr = append(cStr, line) 32 | return nil 33 | }) 34 | for _, v := range components { 35 | // 已有的不修改 36 | if len(existDcMap) > 0 { 37 | if value, ok := existDcMap[v]; ok { 38 | cStr = append(cStr, "\n\n\n#clearfix") 39 | cStr = append(cStr, value) 40 | continue 41 | } 42 | } 43 | 44 | // 新增的 45 | cStr = append(cStr, "\n\n#clearfix\n#app:"+v+"\n") 46 | gfile.ReadLines(p+"/repo/"+v+"/compose.yml", func(line string) error { 47 | cStr = append(cStr, line) 48 | return nil 49 | }) 50 | } 51 | 52 | gfile.PutContents(p+"/docker-compose.yml", strings.ReplaceAll(strings.Join(cStr, "\n"), "\n\n", "\n")) 53 | 54 | } 55 | 56 | // GenerateEnvFile 生成.env文件 57 | func GenerateEnvFile(components []string) { 58 | p := GetInstallDir() 59 | // for dev 60 | existDcMap := parseDockerComposeFileOrEnvFile(false) 61 | 62 | // pre-check 63 | if len(components) == 0 { 64 | fmt.Println("请指定需要生成的组件") 65 | os.Exit(0) 66 | } 67 | 68 | fmt.Println("正在生成.env文件(.env存储docker启动时所需变量,可自行修改)...") 69 | cStr := []string{} 70 | gfile.ReadLines(p+"/repo/base/env.sample", func(line string) error { 71 | cStr = append(cStr, line) 72 | return nil 73 | }) 74 | for _, v := range components { 75 | // 已有的不修改 76 | if len(existDcMap) > 0 { 77 | if value, ok := existDcMap[v]; ok { 78 | cStr = append(cStr, "\n\n\n#clearfix") 79 | cStr = append(cStr, value) 80 | continue 81 | } 82 | } 83 | 84 | // 新增的 85 | if gfile.Exists(p + "/repo/" + v + "/env.sample") { 86 | cStr = append(cStr, "\n\n#clearfix\n#app:"+v+"\n") 87 | gfile.ReadLines(p+"/repo/"+v+"/env.sample", func(line string) error { 88 | cStr = append(cStr, line) 89 | return nil 90 | }) 91 | } 92 | } 93 | 94 | gfile.PutContents(p+"/.env", strings.ReplaceAll(strings.Join(cStr, "\n"), "\n\n", "\n")) 95 | 96 | } 97 | 98 | // CopyDirIfExist 复制目录,如果目录存在 99 | func CopyDirIfExist(components []string) { 100 | fmt.Println("正在生成拷贝配置文件/目录...") 101 | p := GetInstallDir() 102 | for _, v := range components { 103 | src := p + "/repo/" + v + "/build" 104 | dst := p + "/env/" + v 105 | if gfile.Exists(src) && gfile.IsDir(src) && !gfile.Exists(dst) { 106 | gfile.CopyDir(src, dst) 107 | } 108 | } 109 | } 110 | 111 | // 解析docker-compose.yml或者env文件。 112 | // 因为为了保存注释,检测断点标志,所以不能用包解析。只能字符串切割 113 | func parseDockerComposeFileOrEnvFile(isCompose bool) map[string]string { 114 | p := GetEnvFile() 115 | if isCompose { 116 | p = GetDockerComposeFile() 117 | } 118 | 119 | rest := make(map[string]string) 120 | if !gfile.IsFile(p) { 121 | return rest 122 | } 123 | 124 | str := gfile.GetContents(p) 125 | strSlice := gstr.Split(str, "#clearfix") 126 | for _, v := range strSlice { 127 | t, _ := gregex.Match(`#app:(\w+)`, []byte(v)) 128 | if len(t) >= 2 { 129 | // fmt.Println(string(t[1])) 130 | rest[string(t[1])] = gstr.TrimLeft(v, "\n") 131 | } 132 | } 133 | return rest 134 | } 135 | 136 | // GetExistDockerFile 获取已经部署的组件 137 | func GetExistDockerFile() []string { 138 | p := GetDockerComposeFile() 139 | rest := []string{} 140 | if !gfile.IsFile(p) { 141 | return rest 142 | } 143 | 144 | str := gfile.GetContents(p) 145 | strSlice := gstr.Split(str, "#clearfix") 146 | for _, v := range strSlice { 147 | t, _ := gregex.Match(`#app:(\w+)`, []byte(v)) 148 | if len(t) >= 2 { 149 | rest = append(rest, string(t[1])) 150 | } 151 | } 152 | return rest 153 | } 154 | -------------------------------------------------------------------------------- /assistant/utility/vhost.go: -------------------------------------------------------------------------------- 1 | package utility 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "os" 7 | "path/filepath" 8 | "strings" 9 | 10 | _ "assistant/internal/packed" 11 | "github.com/AlecAivazis/survey/v2" 12 | "github.com/gogf/gf/v2/os/gfile" 13 | "github.com/gogf/gf/v2/os/gproc" 14 | "github.com/tufanbarisyildirim/gonginx" 15 | "github.com/tufanbarisyildirim/gonginx/parser" 16 | ) 17 | 18 | var docker = Docker{} 19 | 20 | type Vhost struct { 21 | Domain string // 主域名 22 | OtherDomains string // 多个域名用空格分隔 23 | Root string // 项目根目录 24 | 25 | VhostType string // 5种类型类型,php,html,python,node,reverse 26 | PhpContainer string // php容器名称 27 | 28 | Ssl bool // 是否开启https 29 | FoursHttps bool // 强制302跳转到https 30 | FreeSsl bool // 是否使用免费证书 31 | FreeSslCa string // 免费证书ca 32 | SslCert string // 证书文件路径 33 | SslKey string // 私钥文件路径 34 | 35 | PathInfo bool // 是否开启pathinfo 36 | Rewrite string // 重写规则 37 | 38 | ErrorLog bool // 错误日志 39 | AccessLog bool // 访问日志 40 | AccessLogFormat string // 访问日志格式,默认main,还有一个选择是cloudflare 41 | 42 | Gzip bool // 是否开启gzip 43 | Brotli bool // 是否开启brotli 44 | Security bool // 是否开启安全头 45 | DisableHtmlCache bool // 是否禁用html缓存 46 | 47 | } 48 | 49 | // 获取302跳转到https的配置 50 | func (v *Vhost) get302Server() string { 51 | return `server { 52 | listen 80; 53 | listen [::]:80; 54 | server_name ` + v.Domain + `; 55 | 56 | location / { 57 | return https://$host$request_uri; 58 | } 59 | }` 60 | } 61 | 62 | func (v *Vhost) getServerBlock(port string) string { 63 | 64 | // 预先处理ssl证书部分 65 | sslConf := "" 66 | var e error 67 | if v.Ssl && port == "443" { 68 | if v.FreeSsl { 69 | sslConf, e = v.createFreeSsl(v.Domain, v.Root) 70 | if e != nil { 71 | fmt.Println("创建免费证书失败,程序退出,错误信息如下:") 72 | fmt.Println(e.Error()) 73 | os.Exit(1) 74 | } else { 75 | fmt.Println("免费证书创建成功") 76 | } 77 | } else { 78 | sslConf = v.createCustomSsl() 79 | } 80 | } 81 | 82 | if port == "443" { 83 | port = "443 ssl http2" 84 | } 85 | 86 | finalDomain := v.Domain 87 | if v.OtherDomains != "" { 88 | finalDomain = v.Domain + " " + v.OtherDomains 89 | } 90 | 91 | // 主要配置开始 92 | str := `server { 93 | listen ` + port + `; 94 | listen [::]:` + port + `; 95 | server_name ` + finalDomain + `;` 96 | 97 | // index page 98 | if v.VhostType == "php" { 99 | str += ` 100 | index index.php index.html index.htm;` 101 | } else if v.VhostType == "html" { 102 | str += ` 103 | index index.html index.htm;` 104 | } 105 | 106 | // root 107 | str += ` 108 | root /www/` + v.Domain + `;` 109 | 110 | // logs 111 | if v.AccessLog { 112 | str += ` 113 | access_log /var/log/nginx/` + v.Domain + `/access.log ` + v.AccessLogFormat + `;` 114 | } else { 115 | str += ` 116 | access_log off;` 117 | } 118 | 119 | // error log 120 | if v.ErrorLog { 121 | str += ` 122 | error_log /var/log/nginx/` + v.Domain + `/error.log warn;` 123 | } else { 124 | str += ` 125 | error_log off;` 126 | } 127 | str += ` 128 | #error_page 404 /404.html;` 129 | 130 | // rewrite 131 | if v.Rewrite != "none" { 132 | str += ` 133 | include rewrite/` + v.Rewrite + `.conf;` 134 | } 135 | 136 | // gzip 137 | if v.Gzip { 138 | str += ` 139 | include other/gzip.conf;` 140 | } 141 | 142 | // brotil 143 | if v.Brotli { 144 | str += ` 145 | include other/brotli.conf;` 146 | } 147 | 148 | // security header 149 | if v.Security { 150 | str += ` 151 | include other/security.conf;` 152 | } 153 | 154 | // disable html cache 155 | if v.DisableHtmlCache { 156 | str += ` 157 | include other/disable_html_cache.conf;` 158 | } 159 | 160 | // general path 161 | str += ` 162 | include other/general.conf;` 163 | 164 | // inluce letsencrypt ssl's rules 165 | str += ` 166 | include other/wellknow.conf;` 167 | 168 | // vhost type 169 | if v.VhostType == "php" { 170 | if v.PathInfo { 171 | str += ` 172 | location ~ [^/]\.php(/|$) 173 | { 174 | try_files $uri =404; 175 | fastcgi_pass ` + v.PhpContainer + `:9000; 176 | fastcgi_index index.php; 177 | include fastcgi_params; 178 | }` 179 | } else { 180 | str += ` 181 | location ~ [^/]\.php(/|$) { 182 | fastcgi_pass ` + v.PhpContainer + `:9000; 183 | include fastcgi-php.conf; 184 | include fastcgi_params; 185 | }` 186 | } 187 | 188 | } else if v.VhostType == "python" { 189 | str += ` 190 | location / { 191 | include other/python_uwsgi.conf; 192 | uwsgi_pass 127.0.0.1:8000; #此处应该改为你的python程序ip和端口,或者容器名:端口 193 | uwsgi_param Host $host; 194 | uwsgi_param X-Real-IP $remote_addr; 195 | uwsgi_param X-Forwarded-For $proxy_add_x_forwarded_for; 196 | uwsgi_param X-Forwarded-Proto $http_x_forwarded_proto; 197 | }` 198 | } else if v.VhostType == "reverse proxy" { 199 | str += ` 200 | # reverse proxy 201 | location / { 202 | proxy_pass http://127.0.0.1:3000; ##此处应该改为你反向代理ip和端口,或者容器名:端口 203 | proxy_set_header Host $host; 204 | include other/proxy.conf; 205 | }` 206 | 207 | } else if v.VhostType == "node" { 208 | str += ` 209 | #node 210 | location / { 211 | proxy_pass http://127.0.0.1:3000; ##此处应该改为你反向代理ip和端口,或者容器名:端口 212 | }` 213 | } else if v.VhostType == "html" { 214 | str += `location / { 215 | root /www/` + v.Domain + `; 216 | }` 217 | } 218 | 219 | // ssl 220 | if len(sslConf) > 0 { 221 | str += sslConf 222 | } 223 | 224 | str += `}` 225 | 226 | // 格式化返回 227 | p := parser.NewStringParser(str) 228 | c := p.Parse() 229 | return gonginx.DumpConfig(c, gonginx.IndentedStyle) 230 | 231 | // 原始返回 232 | // return str 233 | } 234 | 235 | // 添加网站 236 | func (v *Vhost) AddVhost() { 237 | // @todo:告知用户操作流程 238 | 239 | // fmt.Printf("%+v", v) 240 | 241 | // 1.先检测ssl和域名是否存在 242 | if gfile.Exists(GetInstallDir() + "/env/nginx/vhost/" + v.Domain + ".conf") { 243 | or := false 244 | prompt := &survey.Confirm{ 245 | Message: "存在同名配置文件,是否要覆盖,配置文件路径:" + GetInstallDir() + "/env/nginx/vhost/" + v.Domain + ".conf", 246 | Default: true, 247 | } 248 | survey.AskOne(prompt, &or) 249 | if or { 250 | gfile.Remove(GetInstallDir() + "/env/nginx/vhost/" + v.Domain + ".conf") 251 | } else { 252 | fmt.Println("您已取消操作,终止添加网站") 253 | os.Exit(0) 254 | } 255 | } 256 | if gfile.Exists(GetInstallDir() + "/env/nginx/ssl/" + v.Domain) { 257 | or := false 258 | prompt := &survey.Confirm{ 259 | Message: "发现储存SSL配置目录,如继续将删除该存放ssl证书的目录。目录路径:" + GetInstallDir() + "/env/nginx/ssl/" + v.Domain, 260 | Default: true, 261 | } 262 | survey.AskOne(prompt, &or) 263 | if or { 264 | gfile.Remove(GetInstallDir() + "/env/nginx/ssl/" + v.Domain) 265 | } else { 266 | fmt.Println("您已取消操作,终止添加网站") 267 | os.Exit(0) 268 | } 269 | } 270 | 271 | // 2.创建日志目录、创建网站目录,80端口的nginx配置文件 272 | if !gfile.Exists(GetInstallDir() + "/logs/nginx/" + v.Domain) { 273 | gfile.Mkdir(GetInstallDir() + "/logs/nginx/" + v.Domain) 274 | } 275 | 276 | // 2.1 定位网站目录 277 | if v.Root == "" { 278 | v.Root = "/www/" + v.Domain 279 | } 280 | if !gfile.Exists(GetInstallDir() + v.Root) { 281 | gfile.Mkdir(GetInstallDir() + v.Root) 282 | } 283 | str80 := v.getServerBlock("80") 284 | err := gfile.PutContents(GetInstallDir()+"/env/nginx/vhost/"+v.Domain+".conf", str80) 285 | if err != nil { 286 | fmt.Println("生成网站配置文件失败,错误信息:") 287 | os.Exit(0) 288 | } 289 | gfile.Chmod(GetInstallDir()+"/env/nginx/vhost/"+v.Domain+".conf", 0755) 290 | 291 | // 3.重启nginx 292 | res, e := docker.DockerAction("restart", "nginx") 293 | fmt.Println(res, e) 294 | if IsContainerLive("nginx") { 295 | fmt.Println("nginx重启成功") 296 | } else { 297 | fmt.Println("nginx重启失败,请手动检查。") 298 | fmt.Println("推荐参考检查方法1:使用docker logs nginx查看日志") 299 | fmt.Println("推荐参考检查方法2:删除掉env/nginx/vhost/" + v.Domain + ".conf文件,重启再执行xii restart nginx 或进入项目目录执行docker-compose restart nginx") 300 | fmt.Println("最后,如果排查完成后,确定非自己引入的问题,敬请方便时反馈到项目issue中,感谢您的支持。") 301 | os.Exit(0) 302 | } 303 | 304 | // 4.创建ssl证书流程 305 | if v.Ssl { 306 | // 4.1. 如果需要,生成dhparam.pem 307 | // if !gfile.Exists(GetInstallDir() + "/env/nginx/dhparam.pem") { 308 | // fmt.Println("发现dhparam.pem文件不存在,需要生成一次dhparam.pem文件,这个过程可能需要一段时间,请耐心等待。") 309 | // _, err := gproc.ShellExec(`docker exec -it nginx /bin/sh openssl dhparam -out /etc/nginx/dhparam.pem 2048`) 310 | // if err != nil { 311 | // fmt.Println("生成dhparam.pem文件失败,请手动执行docker exec -it nginx /bin/sh openssl dhparam -out /etc/nginx/dhparam.pem 2048") 312 | // os.Exit(0) 313 | // } 314 | // } 315 | 316 | // 4.1 检测acme.sh是否存在 317 | if v.FreeSsl { 318 | if !gfile.Exists(GetInstallDir() + "/env/acme.sh/acme.sh") { 319 | r, e := gproc.ShellExec(`docker exec -ti nginx /bin/sh /root/acme_install.sh`) 320 | if e != nil { 321 | fmt.Println("安装acme.sh失败,任务终止!\n 1.请手动执行docker exec -ti nginx /bin/sh /root/acme_install.sh 进行安装\n 2.或者不选免费证书,改为自己配置证书") 322 | os.Exit(0) 323 | } 324 | if strings.Contains(r, "Install success") { 325 | fmt.Println("acme.sh安装成功") 326 | } else { 327 | fmt.Println("acme.sh安装失败,任务终止!\n 1.请手动执行docker exec -ti nginx /bin/sh /root/acme_install.sh 进行安装\n 2.或者不选免费证书,改为自己配置证书") 328 | os.Exit(0) 329 | } 330 | } 331 | } 332 | 333 | // 4.2. 创建ssl证书目录 334 | fmt.Println("开始创建ssl证书目录") 335 | gfile.Mkdir(GetInstallDir() + "/env/nginx/ssl/" + v.Domain) 336 | 337 | // 4.3. 判断是否要302跳转 338 | str80 := "" 339 | if v.FoursHttps { 340 | str80 = v.get302Server() 341 | } 342 | 343 | // 4.4. 重新生成nginx的80、443端口配置文件,替换原有的配置文件 344 | if !v.FoursHttps { 345 | str80 = v.getServerBlock("80") 346 | } 347 | str443 := v.getServerBlock("443") 348 | 349 | finalStr := str80 + "\n" + str443 350 | gfile.PutContents(GetInstallDir()+"/env/nginx/vhost/"+v.Domain+".conf", finalStr) 351 | gfile.Chmod(GetInstallDir()+"/env/nginx/vhost/"+v.Domain+".conf", 0755) 352 | 353 | // 4.5. 重启nginx 354 | docker.DockerAction("restart", "nginx") 355 | } 356 | 357 | fmt.Println("") 358 | fmt.Println("") 359 | fmt.Println("添加网站成功") 360 | fmt.Println("") 361 | 362 | } 363 | 364 | // AskForVhost cli交互获取Vhost信息 365 | func AskForVhost() (vh *Vhost, e error) { 366 | fmt.Println(" ") 367 | fmt.Printf("\033[34m注意:如果你生成的是php网站,当前助手程序默认指定的是php80,端口号为9000的镜像,\n如果你需要使用其他版本的php容器,请生成后手动调整下env/nginx/vhost/域名.conf中的fastcgi_pass php80:9000;为你需要的php版本,并重启nginx\033[0m") 368 | fmt.Println("\n ") 369 | 370 | vhost := Vhost{} 371 | 372 | // 询问架构 373 | t := &survey.Select{ 374 | Message: "当前网站/项目的技术类型是:", 375 | Options: []string{"php", "html", "python", "node", "reverse proxy"}, 376 | } 377 | survey.AskOne(t, &vhost.VhostType) 378 | 379 | if vhost.VhostType == "php" { 380 | s, e := docker.ContainerName() 381 | if e != nil { 382 | fmt.Println("看起来没有容器在运行,请先运行起来后再添加。") 383 | os.Exit(1) 384 | } 385 | s2 := []string{} 386 | if len(s) > 0 { 387 | for _, v := range s { 388 | if IsContainerLive(v) { 389 | if strings.Contains(v, vhost.VhostType) { 390 | s2 = append(s2, v) 391 | } 392 | } 393 | } 394 | } 395 | if len(s2) == 0 { 396 | fmt.Println("没找到存活的" + vhost.VhostType + "容器,无法进入") 397 | os.Exit(1) 398 | } 399 | 400 | // 选择php版本 401 | t := &survey.Select{ 402 | Message: "选择php版本,如需其版本,请先确保对应的容器有在运行。:", 403 | Options: s2, 404 | } 405 | survey.AskOne(t, &vhost.PhpContainer) 406 | } 407 | 408 | var qs = []*survey.Question{ 409 | { 410 | Name: "Domain", 411 | Prompt: &survey.Input{Message: "请输入主域名:"}, 412 | Validate: survey.Required, 413 | }, 414 | { 415 | Name: "OtherDomains", 416 | Prompt: &survey.Input{Message: "请输入其他域名或者回车跳过:"}, 417 | }, 418 | { 419 | Name: "Root", 420 | Prompt: &survey.Input{Message: "请输入网站根目录,不输入默认为/www/主域名:"}, 421 | }, 422 | { 423 | Name: "PathInfo", 424 | Prompt: &survey.Confirm{Message: "是否开启pathinfo:"}, 425 | }, { 426 | Name: "Rewrite", 427 | Prompt: &survey.Select{ 428 | Message: "是否需要网址重写,无需选none:", 429 | Options: rewriteRules(), 430 | }, 431 | }, { 432 | Name: "Gzip", 433 | Prompt: &survey.Confirm{ 434 | Message: "是否开启Gzip压缩,提高网页访问传输速度,默认开启:", 435 | Default: true, 436 | }, 437 | }, { 438 | Name: "Brotli", 439 | Prompt: &survey.Confirm{ 440 | Message: "是否开启Brotli压缩(当前nginx镜像不一定支持,建议开启,程序会自动判断),提高网页访问传输速度,默认开启:", 441 | Default: true, 442 | }, 443 | }, { 444 | Name: "Security", 445 | Prompt: &survey.Confirm{ 446 | Message: "是否开启通用安全信息头(Security Header),提高网站安全性,默认否:", 447 | Default: false, 448 | }, 449 | }, { 450 | Name: "DisableHtmlCache", 451 | Prompt: &survey.Confirm{ 452 | Message: "是否禁止浏览器缓存网页内容,开启后,每个网页都会追加一个header信息告知浏览器不要缓存。可自己在代码里控制。默认否:", 453 | Default: false, 454 | }, 455 | }, { 456 | Name: "ErrorLog", 457 | Prompt: &survey.Confirm{ 458 | Message: "是否开启错误日志,默认开启:", 459 | Default: false, 460 | }, 461 | }, { 462 | Name: "AccessLog", 463 | Prompt: &survey.Confirm{ 464 | Message: "是否开启访问日志,默认开启:", 465 | Default: false, 466 | }, 467 | }, 468 | } 469 | if err := survey.Ask(qs, &vhost); err != nil { 470 | os.Exit(1) 471 | return nil, err 472 | } 473 | 474 | if vhost.AccessLog { 475 | alf := &survey.Select{ 476 | Message: "访问日志格式,如果有使用cloudflare的服务,建议选择cloudflare:", 477 | Options: []string{"main", "cloudflare"}, 478 | } 479 | survey.AskOne(alf, &vhost.AccessLogFormat) 480 | } 481 | 482 | // ssl是否开启 483 | prompt := &survey.Confirm{ 484 | Message: "使用启用SSL?:", 485 | Default: true, 486 | } 487 | survey.AskOne(prompt, &vhost.Ssl) 488 | 489 | // 是否开启强制https跳转 490 | if vhost.Ssl { 491 | prompt := &survey.Confirm{ 492 | Message: "强制302 http跳https", 493 | Default: true, 494 | } 495 | survey.AskOne(prompt, &vhost.FoursHttps) 496 | 497 | // 是否使用免费证书 498 | prompt = &survey.Confirm{ 499 | Message: "使用免费证书\n :", 500 | Default: true, 501 | } 502 | survey.AskOne(prompt, &vhost.FreeSsl) 503 | 504 | // Free CA 505 | if vhost.FreeSsl { 506 | ca := &survey.Select{ 507 | Message: "选择免费证书颁发机构:\n部分特殊域名后缀(如.io ,.app,.dev),注册局直接强制80端口转443的,请优先选择letsencrypt's SSL申请。", 508 | Options: []string{"letsencrypt", "zerossl"}, 509 | } 510 | survey.AskOne(ca, &vhost.FreeSslCa) 511 | } 512 | 513 | // Custom cert and key 514 | if !vhost.FreeSsl { 515 | s := &survey.Input{ 516 | Message: "请输入证书文件路径:", 517 | } 518 | survey.AskOne(s, &vhost.SslCert) 519 | s = &survey.Input{ 520 | Message: "请输入私钥文件路径:", 521 | } 522 | survey.AskOne(s, &vhost.SslKey) 523 | } 524 | 525 | } 526 | 527 | return &vhost, nil 528 | } 529 | 530 | // 获取可以rewrite规则 531 | func rewriteRules() []string { 532 | rewriteRules := []string{"none"} 533 | rset, _ := gfile.ScanDir(GetInstallDir()+"/env/nginx/rewrite", "*.conf") 534 | for _, v := range rset { 535 | rewriteRules = append(rewriteRules, gfile.Name(v)) 536 | } 537 | return rewriteRules 538 | } 539 | 540 | // 获取项目所在目录 541 | func getProjectFolder() string { 542 | curPath, _ := os.Executable() 543 | return filepath.Dir(filepath.Dir(curPath)) 544 | } 545 | 546 | // 根据vhost信息生成文件夹等 547 | func (v *Vhost) createFolder() { 548 | p := getProjectFolder() 549 | f := []string{ 550 | p + "/logs/nginx/" + v.Domain, 551 | p + "/www/" + v.Domain, 552 | p + "/env/nginx/ssl/" + v.Domain, 553 | } 554 | for _, v := range f { 555 | gfile.Mkdir(v) 556 | } 557 | } 558 | 559 | // createFreeSsl 生成证书 560 | // @Description: 创建证书 561 | // @receiver v 562 | // @param domain 域名 563 | // @param webroot 域名所在目录 564 | // @return string conf配置文件内容 565 | // @return error 错误信息 566 | func (v *Vhost) createFreeSsl(domain string, webroot string) (string, error) { 567 | fmt.Println("正在开生成免费证书:" + domain) 568 | fmt.Println("可能会花费2-10分钟时间,请耐心等待,如失败会明确告知!") 569 | 570 | // split other domains 571 | secondDomains := "" 572 | if v.OtherDomains != "" { 573 | domains := strings.Split(v.OtherDomains, " ") 574 | for _, d := range domains { 575 | secondDomains = secondDomains + " -d " + d + " " 576 | } 577 | } 578 | 579 | // --server letsencrypt 580 | cmd := `docker exec -it nginx /bin/sh ~/.acme.sh/acme.sh --issue -d ` + domain + secondDomains + ` --webroot ` + webroot + ` --force` 581 | if v.FreeSslCa == "letsencrypt" { 582 | cmd = `docker exec -it nginx /bin/sh ~/.acme.sh/acme.sh --issue -d ` + domain + secondDomains + ` --webroot ` + webroot + ` --force --server letsencrypt` 583 | } 584 | 585 | fmt.Println("执行生成命令:" + cmd) 586 | r, err := gproc.ShellExec(cmd) 587 | if strings.Contains(r, "Your cert is in") || strings.Contains(r, "Cert success.") { 588 | r, err = gproc.ShellExec(`docker exec -it nginx /bin/sh ~/.acme.sh/acme.sh --install-cert -d ` + domain + ` --key-file /etc/nginx/ssl/` + domain + `/key.pem --fullchain-file /etc/nginx/ssl/` + domain + `/cert.pem`) 589 | if err == nil { 590 | // if strings.Contains(r, "Installing key to") { 591 | fmt.Println("证书安装成功") 592 | return ` 593 | ssl_certificate /etc/nginx/ssl/` + domain + `/cert.pem; 594 | ssl_certificate_key /etc/nginx/ssl/` + domain + `/key.pem; 595 | ssl_session_timeout 5m; 596 | ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; 597 | ssl_prefer_server_ciphers on; 598 | ssl_ciphers "TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256:TLS13-AES-128-CCM-8-SHA256:TLS13-AES-128-CCM-SHA256:EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5"; 599 | ssl_session_cache builtin:1000 shared:SSL:10m; 600 | ssl_dhparam dhparam.pem; 601 | `, nil 602 | 603 | // } 604 | } else { 605 | return "", err 606 | } 607 | 608 | } else { 609 | fmt.Println("Error occured:", err) 610 | fmt.Println("result:", r) 611 | return "", errors.New("证书生成失败") 612 | } 613 | 614 | return "", nil 615 | } 616 | 617 | // getCustomSslConf 生成自定义证书配置 618 | func (v *Vhost) createCustomSsl() string { 619 | gfile.Copy(v.SslKey, GetInstallDir()+"/env/nginx/ssl/"+v.Domain+"/key.pem") 620 | gfile.Copy(v.SslCert, GetInstallDir()+"/env/nginx/ssl/"+v.Domain+"/cert.pem") 621 | return ` 622 | ssl_certificate /etc/nginx/ssl/` + v.Domain + `/cert.pem; 623 | ssl_certificate_key /etc/nginx/ssl/` + v.Domain + `/key.pem; 624 | ssl_session_timeout 5m; 625 | ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; 626 | ssl_prefer_server_ciphers on; 627 | ssl_ciphers "TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256:TLS13-AES-128-CCM-8-SHA256:TLS13-AES-128-CCM-SHA256:EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5"; 628 | ssl_session_cache builtin:1000 shared:SSL:10m; 629 | ssl_dhparam dhparam.pem; 630 | ` 631 | } 632 | -------------------------------------------------------------------------------- /dev.md: -------------------------------------------------------------------------------- 1 | # 增加dev分支,用来迭代新功能。 2 | 3 | -------------------------------------------------------------------------------- /docs/php.md: -------------------------------------------------------------------------------- 1 | ### PHP版本 2 | 3 | 仅支持7.2及以上版本 4 | 5 | ### 安装扩展 6 | 7 | 1. 修改.env文件里的PHP80_EXTENSIONS的值,添加需要的扩展 8 | 注意:80换成你需要的版本号。 9 | 10 | 2. 已经跑起来的容器,需要删除重建才能生效。 11 | 12 | ### 快速安装php扩展 13 | 14 | 1.进入容器: 15 | 16 | ```sh 17 | docker exec -it php /bin/sh 18 | 19 | install-php-extensions apcu 20 | 21 | ``` 22 | 23 | 2.支持快速安装扩展列表 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | | Extension | PHP 5.5 | PHP 5.6 | PHP 7.0 | PHP 7.1 | PHP 7.2 | PHP 7.3 | PHP 7.4 | PHP 8.0 | PHP 8.1 | 34 | |:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:| 35 | | amqp | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 36 | | apcu | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 37 | | apcu_bc | | | ✓ | ✓ | ✓ | ✓ | ✓ | | | 38 | | ast | | | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 39 | | bcmath | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 40 | | blackfire | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 41 | | bz2 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 42 | | calendar | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 43 | | cmark | | | ✓ | ✓ | ✓ | ✓ | ✓ | | | 44 | | csv | | | | | | ✓ | ✓ | ✓ | ✓ | 45 | | dba | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 46 | | decimal | | | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 47 | | ds | | | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 48 | | enchant | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 49 | | ev | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 50 | | event | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 51 | | excimer | | | | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 52 | | exif | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 53 | | ffi | | | | | | | ✓ | ✓ | ✓ | 54 | | gd | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 55 | | gearman | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | 56 | | geoip | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | | 57 | | geospatial | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 58 | | gettext | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 59 | | gmagick | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 60 | | gmp | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 61 | | gnupg | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 62 | | grpc | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 63 | | http | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 64 | | igbinary | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 65 | | imagick | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 66 | | imap | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 67 | | inotify | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 68 | | interbase | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | | | 69 | | intl | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 70 | | ioncube_loader | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | | 71 | | jsmin | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | | 72 | | json_post | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 73 | | ldap | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 74 | | lzf | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 75 | | mailparse | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 76 | | maxminddb | | | | | ✓ | ✓ | ✓ | ✓ | ✓ | 77 | | mcrypt | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 78 | | memcache | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 79 | | memcached | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 80 | | mongo | ✓ | ✓ | | | | | | | | 81 | | mongodb | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 82 | | mosquitto | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | | 83 | | msgpack | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 84 | | mssql | ✓ | ✓ | | | | | | | | 85 | | mysql | ✓ | ✓ | | | | | | | | 86 | | mysqli | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 87 | | oauth | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 88 | | oci8 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 89 | | odbc | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 90 | | opcache | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 91 | | opencensus | | | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 92 | | openswoole | | | | | ✓ | ✓ | ✓ | ✓ | ✓ | 93 | | parallel[*](#special-requirements-for-parallel) | | | | ✓ | ✓ | ✓ | ✓ | | | 94 | | pcntl | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 95 | | pcov | | | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 96 | | pdo_dblib | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | 97 | | pdo_firebird | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 98 | | pdo_mysql | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 99 | | pdo_oci | | | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 100 | | pdo_odbc | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 101 | | pdo_pgsql | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 102 | | pdo_sqlsrv[*](#special-requirements-for-pdo_sqlsrv) | | | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 103 | | pgsql | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 104 | | propro | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | | 105 | | protobuf | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | 106 | | pspell | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 107 | | pthreads[*](#special-requirements-for-pthreads) | ✓ | ✓ | ✓ | | | | | | | 108 | | raphf | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 109 | | rdkafka | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 110 | | recode | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | | | 111 | | redis | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 112 | | seaslog | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 113 | | shmop | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 114 | | smbclient | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 115 | | snmp | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 116 | | snuffleupagus | | | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 117 | | soap | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 118 | | sockets | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 119 | | solr | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 120 | | sourceguardian | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | 121 | | spx | | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 122 | | sqlsrv[*](#special-requirements-for-sqlsrv) | | | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 123 | | ssh2 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 124 | | stomp | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | | 125 | | swoole | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 126 | | sybase_ct | ✓ | ✓ | | | | | | | | 127 | | sysvmsg | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 128 | | sysvsem | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 129 | | sysvshm | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 130 | | tensor[*](#special-requirements-for-tensor) | | | | | ✓ | ✓ | ✓ | ✓ | | 131 | | tidy | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 132 | | timezonedb | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 133 | | uopz | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 134 | | uploadprogress | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 135 | | uuid | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 136 | | vips[*](#special-requirements-for-vips) | | | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 137 | | wddx | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | | | 138 | | xdebug | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 139 | | xhprof | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 140 | | xlswriter | | | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 141 | | xmldiff | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 142 | | xmlrpc | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 143 | | xsl | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 144 | | yac | | | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 145 | | yaml | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 146 | | yar | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 147 | | zephir_parser | | | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 148 | | zip | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 149 | | zookeeper | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 150 | | zstd | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 151 | 152 | *Number of supported extensions: 116* 153 | 154 | 此扩展来自[https://github.com/mlocati/docker-php-extension-installer](https://github.com/mlocati/docker-php-extension-installer) 155 | 参考示例文件 -------------------------------------------------------------------------------- /docs/仓库操作流程.md: -------------------------------------------------------------------------------- 1 | ### 本文主要写给自己操作流程,非仓库维护人员无需查看 2 | 3 | 1. github上创建预发布包,将出action生成安装包。 4 | 2. action生成安装包后,将自动发布到下载区。 -------------------------------------------------------------------------------- /docs/开发流程.md: -------------------------------------------------------------------------------- 1 | # 如何成为一个贡献者 2 | 3 | 1. fork 本项目, 并clone到本地。 4 | 2. 拷贝script/install.sh和manual.sh各一份,并修改里面的github下载地址为你自己的项目地址.(关键字:https://github.com/xiiapp/xii) 。注意将这2份新脚本添加到gitignore中。 5 | 3. 进行功能的调整后,执行script/make.sh,该脚本将打包成相应平台的zip包。存放在relase.zip下。这就是最终用户需要安装的程序。 6 | 4. 测试开发功能后,提交PR,等待合并。 7 | 8 | 9 | # 项目结构 10 | 11 | ```shell 12 | . 13 | ├── assistant 项目辅助程序 xii的源码存放在这里。 14 | ├── data 项目数据存放目录,包括mysql,redis,mongodb等数据。提交到git时应该留空 15 | ├── docs 项目文档 16 | ├── env dockerfile等配置信息,由xii助手生成 17 | ├── logs 日志文件,提交到git时应该为空 18 | ├── release 最终提供给用户安装的压缩包 19 | ├── script 开发辅脚本 20 | ├── repo 存储各个镜像,构建代码,参数等。xii助手会根据这里的内容生成docker-compose.yml文件、env文件、nginx配置文件等。 21 | ├── www 网站存放目录,其他node或者项目的存放目录。 22 | └── .github CI脚本,暂时没启用。占坑。 23 | 24 | ``` 25 | 26 | 27 | # 技术栈 28 | 29 | - xii助手程序是golang语言和goframe框架开发 30 | - 脚本主要是bash脚本 31 | 32 | 33 | # 如何将一个docker镜像构建加入到xii中 34 | 35 | - 在repo中新建一个仓库,仓库名字为镜像名字(这里假设是abc). 36 | - 将该镜像的docker-compose的构建代码片段,存为abc/compose.yml 37 | - 将该镜像的自定义变量(一般是放在.env文件),存为abc/env.sample,没有就不用创建这个文件。 38 | - 在abc目录中新建一个build目录,如果有dockerfile、镜像自定义配置、配置挂载目录等的话,如果没有,目录也无需创建 39 | 40 | > 如果你觉得可以贡献该配置,欢迎提交PR。 -------------------------------------------------------------------------------- /docs/快速安装.md: -------------------------------------------------------------------------------- 1 | ## 安装 2 | 3 | ## 1.Linux 系统 4 | 5 | ### 一键安装脚本 6 | 7 | > wget -qO- xii.app/install.sh | bash 8 | 9 | 或 10 | 11 | > curl -Lso- xii.app/install.sh |bash 12 | 13 | 14 | 15 | ### 安装脚本细节说明 16 | 17 | - 一键脚本会安装docker-compose, docker,git 三个软件 18 | - 一键脚本会创建**/home/xii**目录,并下载助手程序**xii**到该目录里,并创建2个软连接**xii** 和**xxi** 指向助手程序xii 19 | 20 | 21 | 22 | ## 2.Windows 系统(待补充完成) 23 | TBD 24 | 25 | 26 | 27 | ## 3.MacOS 系统(待补充完成) 28 | 29 | DESCRIPTION 30 | XII助手:管理网站新增/删除/罗列,以及封装docker的快捷操作方式 -------------------------------------------------------------------------------- /docs/系统需求.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## 安装需求 4 | 5 | - **服务器最低需要1G或以上内存** 6 | - **服务器最低需要5G剩余空间** 7 | - **操作系统最低需为Linux,Windows 10 Build 15063+,或MacOS 10.12+,且必须要`64`位,支持Mac arm芯片组,即M1、M2等** 8 | 9 | ### 补充说明 10 | 11 | - MySQL 5.6或5.7及MariaDB 10必须1G以上内存,更高版本至少要2G内存 12 | - PHP7起需要1Gb以上内存 13 | - 如启用mysql5.7、MariaDB 10 需要9G以上, Mysql8 最新版确保至少有25Gb剩余可用。 14 | 15 | -------------------------------------------------------------------------------- /docs/约定规范.md: -------------------------------------------------------------------------------- 1 | # 编写修改docker-compose.yml时,简单约定 2 | 3 | 4 | ## 容器名称 5 | 6 | - 多版本的一律使用 名+2位版本,比如php74,php80 ,mysql57,mysql80等,方便识别。 7 | - 单版本的一律直接使用 服务名,比如nginx,redis 8 | 9 | ## 端口映射 10 | - php系列 ,端口一律使用95+两位版本号,比如php74对应端口就是9574,php80对应端口就是9580 11 | (注意:php-fpm的端口是9000,不要修改) 12 | - mysql系列,端口一律使用96+两位版本号,比如mysql57对应端口就是9657,mysql80对应端口就是9680 13 | (注意:mysql内部端口是3306,不要修改) -------------------------------------------------------------------------------- /docs/路线图.md: -------------------------------------------------------------------------------- 1 | # 后续路线图 2 | 3 | 4 | ## 全局 5 | [ ] 1. 提供编译、预编译两种不同镜像 6 | [ ] 2. 加速下载 7 | 8 | ## xii助手 9 | [ ] 1. 增加切换镜像,加速下载 10 | [ ] 2. 增加自由选换dokcer镜像 11 | [ ] 3. 增加docker镜像同步升级 12 | [ ] 4. 增加快速创建数据库、用户名、等 13 | [ ] 5. 增加快速sftp/ftp服务 14 | [ ] 6. 优化代码结构和操作体验流程 15 | [ ] 7. 提供自适应网页前端编写管理 16 | [ ] 8. 提供Api管理 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /env/readme.md: -------------------------------------------------------------------------------- 1 | 默认空目录 2 | 3 | 1. 调用xii init命令,初始化项目,会将对应镜像的dockerfile ,配置文件等存放于此。 4 | 2. 用户可在此目录修改镜像配置文件等。 -------------------------------------------------------------------------------- /release/xii_linux.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiiapp/xii/7d7c08c767774fb203b6289d901ee026c613510f/release/xii_linux.zip -------------------------------------------------------------------------------- /release/xii_linux_arm.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiiapp/xii/7d7c08c767774fb203b6289d901ee026c613510f/release/xii_linux_arm.zip -------------------------------------------------------------------------------- /release/xii_linux_arm64.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiiapp/xii/7d7c08c767774fb203b6289d901ee026c613510f/release/xii_linux_arm64.zip -------------------------------------------------------------------------------- /release/xii_mac.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiiapp/xii/7d7c08c767774fb203b6289d901ee026c613510f/release/xii_mac.zip -------------------------------------------------------------------------------- /release/xii_mac_arm.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiiapp/xii/7d7c08c767774fb203b6289d901ee026c613510f/release/xii_mac_arm.zip -------------------------------------------------------------------------------- /repo/base/compose.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | services: -------------------------------------------------------------------------------- /repo/base/env.sample: -------------------------------------------------------------------------------- 1 | SOURCE_DIR=./www 2 | DATA_DIR=./data 3 | TZ=Asia/Shanghai 4 | ALPINE_VERSION=3.16 5 | 6 | # 7 | # Container package fetch url 8 | # 9 | # Can be empty, followings or others: 10 | # mirrors.163.com 11 | # mirrors.aliyun.com 12 | # mirrors.ustc.edu.cn 13 | # dl-cdn.alpinelinux.org 14 | # 15 | CONTAINER_PACKAGE_URL=mirrors.ustc.edu.cn -------------------------------------------------------------------------------- /repo/base/readme.md: -------------------------------------------------------------------------------- 1 | 存储构建docker-compose.yml文件 和 .env 文件的头部信息。 2 | 3 | 即通用的。 4 | 5 | -------------------------------------------------------------------------------- /repo/memcached/compose.yml: -------------------------------------------------------------------------------- 1 | memcached: 2 | image: memcached:${MEMCACHED_VERSION} 3 | container_name: memcached 4 | ports: 5 | - "${MEMCACHED_HOST_PORT}:11211" 6 | environment: 7 | MEMCACHED_CACHE_SIZE: "${MEMCACHED_CACHE_SIZE}" 8 | networks: 9 | - default 10 | labels: 11 | "type": "memcached" -------------------------------------------------------------------------------- /repo/memcached/env.sample: -------------------------------------------------------------------------------- 1 | # 2 | # Memcached 3 | # 4 | MEMCACHED_VERSION=alpine 5 | MEMCACHED_HOST_PORT=11211 6 | MEMCACHED_CACHE_SIZE=128 -------------------------------------------------------------------------------- /repo/mongo/compose.yml: -------------------------------------------------------------------------------- 1 | mongodb: 2 | image: mongo:${MONGODB_VERSION} 3 | container_name: mongodb 4 | environment: 5 | MONGO_INITDB_ROOT_USERNAME: "${MONGODB_INITDB_ROOT_USERNAME}" 6 | MONGO_INITDB_ROOT_PASSWORD: "${MONGODB_INITDB_ROOT_PASSWORD}" 7 | TZ: "$TZ" 8 | volumes: 9 | - ${DATA_DIR}/mongo:/data/db:rw 10 | - ${DATA_DIR}/mongo_key:/mongo:rw 11 | ports: 12 | - "${MONGODB_HOST_PORT}:27017" 13 | networks: 14 | - default 15 | labels: 16 | "type": "mongodb" 17 | command: 18 | --auth -------------------------------------------------------------------------------- /repo/mongo/env.sample: -------------------------------------------------------------------------------- 1 | # 2 | # MONGODB 3 | # 版本信息:https://github.com/docker-library/docs/blob/master/mongo/README.md#supported-tags-and-respective-dockerfile-links 4 | # 5 | MONGODB_VERSION=6.0.2-focal 6 | MONGODB_HOST_PORT=27017 7 | MONGODB_INITDB_ROOT_USERNAME=root 8 | MONGODB_INITDB_ROOT_PASSWORD=123456 -------------------------------------------------------------------------------- /repo/mysql55/build/mysql.cnf: -------------------------------------------------------------------------------- 1 | # For advice on how to change settings please see 2 | # http://dev.mysql.com/doc/refman/5.6/en/server-configuration-defaults.html 3 | 4 | [client] 5 | port = 3306 6 | default-character-set = utf8mb4 7 | 8 | 9 | [mysqld] 10 | user = mysql 11 | port = 3306 12 | sql_mode = "" 13 | 14 | default-storage-engine = InnoDB 15 | default-authentication-plugin = mysql_native_password 16 | character-set-server = utf8mb4 17 | collation-server = utf8mb4_unicode_ci 18 | init_connect = 'SET NAMES utf8mb4' 19 | 20 | disable-log-bin 21 | skip-character-set-client-handshake 22 | explicit_defaults_for_timestamp 23 | 24 | slow_query_log 25 | long_query_time = 3 26 | slow-query-log-file = /var/log/mysql/mysql.slow.log 27 | log-error = /var/log/mysql/mysql.error.log 28 | 29 | default-time-zone = '+8:00' 30 | 31 | # Remove leading # to set options mainly useful for reporting servers. 32 | # The server defaults are faster for transactions and fast SELECTs. 33 | # Adjust sizes as needed, experiment to find the optimal values. 34 | # join_buffer_size = 128M 35 | # sort_buffer_size = 2M 36 | # read_rnd_buffer_size = 2M 37 | 38 | 39 | [mysql] 40 | default-character-set = utf8mb4 41 | -------------------------------------------------------------------------------- /repo/mysql55/compose.yml: -------------------------------------------------------------------------------- 1 | # mysql5.6 2 | mysql55: 3 | image: mysql/mysql-server:${MYSQL55_VERSION} 4 | container_name: mysql55 5 | ports: 6 | - "${MYSQL55_HOST_PORT}:3306" 7 | volumes: 8 | - ${MYSQL55_CONF_FILE}:/etc/mysql/conf.d/mysql.cnf:ro 9 | - ${DATA_DIR}/mysql55:/var/lib/mysql/:rw 10 | - ${MYSQL55_LOG_DIR}:/var/log/mysql/:rw 11 | restart: always 12 | networks: 13 | - default 14 | labels: 15 | "type": "mysql" 16 | environment: 17 | MYSQL_ROOT_PASSWORD: "${MYSQL55_ROOT_PASSWORD}" 18 | MYSQL_ROOT_HOST: "${MYSQL55_ROOT_HOST}" 19 | TZ: "$TZ" 20 | -------------------------------------------------------------------------------- /repo/mysql55/env.sample: -------------------------------------------------------------------------------- 1 | # 2 | # MySQL5.6.51 3 | # 4 | MYSQL55_VERSION=5.5.62 5 | MYSQL55_HOST_PORT=3355 6 | MYSQL55_ROOT_PASSWORD=123456 7 | MYSQL55_ROOT_HOST=% 8 | MYSQL55_CONF_FILE=./env/mysql55/mysql.cnf 9 | MYSQL55_LOG_DIR=./logs/mysql55 10 | -------------------------------------------------------------------------------- /repo/mysql56/build/mysql.cnf: -------------------------------------------------------------------------------- 1 | # For advice on how to change settings please see 2 | # http://dev.mysql.com/doc/refman/5.6/en/server-configuration-defaults.html 3 | 4 | [client] 5 | port = 3306 6 | default-character-set = utf8mb4 7 | 8 | 9 | [mysqld] 10 | user = mysql 11 | port = 3306 12 | sql_mode = "" 13 | 14 | default-storage-engine = InnoDB 15 | default-authentication-plugin = mysql_native_password 16 | character-set-server = utf8mb4 17 | collation-server = utf8mb4_unicode_ci 18 | init_connect = 'SET NAMES utf8mb4' 19 | 20 | disable-log-bin 21 | skip-character-set-client-handshake 22 | explicit_defaults_for_timestamp 23 | 24 | slow_query_log 25 | long_query_time = 3 26 | slow-query-log-file = /var/log/mysql/mysql.slow.log 27 | log-error = /var/log/mysql/mysql.error.log 28 | 29 | default-time-zone = '+8:00' 30 | 31 | # Remove leading # to set options mainly useful for reporting servers. 32 | # The server defaults are faster for transactions and fast SELECTs. 33 | # Adjust sizes as needed, experiment to find the optimal values. 34 | # join_buffer_size = 128M 35 | # sort_buffer_size = 2M 36 | # read_rnd_buffer_size = 2M 37 | 38 | 39 | [mysql] 40 | default-character-set = utf8mb4 41 | -------------------------------------------------------------------------------- /repo/mysql56/compose.yml: -------------------------------------------------------------------------------- 1 | # mysql5.6 2 | mysql56: 3 | image: mysql/mysql-server:${MYSQL56_VERSION} 4 | container_name: mysql56 5 | ports: 6 | - "${MYSQL56_HOST_PORT}:3306" 7 | volumes: 8 | - ${MYSQL56_CONF_FILE}:/etc/mysql/conf.d/mysql.cnf:ro 9 | - ${DATA_DIR}/mysql56:/var/lib/mysql/:rw 10 | - ${MYSQL56_LOG_DIR}:/var/log/mysql/:rw 11 | restart: always 12 | networks: 13 | - default 14 | labels: 15 | "type": "mysql" 16 | environment: 17 | MYSQL_ROOT_PASSWORD: "${MYSQL56_ROOT_PASSWORD}" 18 | MYSQL_ROOT_HOST: "${MYSQL56_ROOT_HOST}" 19 | TZ: "$TZ" 20 | -------------------------------------------------------------------------------- /repo/mysql56/env.sample: -------------------------------------------------------------------------------- 1 | # 2 | # MySQL5.6.51 3 | # 4 | MYSQL56_VERSION=5.6.51 5 | MYSQL56_HOST_PORT=3356 6 | MYSQL56_ROOT_PASSWORD=123456 7 | MYSQL56_ROOT_HOST=% 8 | MYSQL56_CONF_FILE=./env/mysql56/mysql.cnf 9 | MYSQL56_LOG_DIR=./logs/mysql56 10 | -------------------------------------------------------------------------------- /repo/mysql57/build/mysql.cnf: -------------------------------------------------------------------------------- 1 | # For advice on how to change settings please see 2 | # http://dev.mysql.com/doc/refman/5.6/en/server-configuration-defaults.html 3 | 4 | [client] 5 | port = 3306 6 | default-character-set = utf8mb4 7 | 8 | 9 | [mysqld] 10 | user = mysql 11 | port = 3306 12 | sql_mode = "" 13 | 14 | default-storage-engine = InnoDB 15 | default-authentication-plugin = mysql_native_password 16 | character-set-server = utf8mb4 17 | collation-server = utf8mb4_unicode_ci 18 | init_connect = 'SET NAMES utf8mb4' 19 | 20 | disable-log-bin 21 | skip-character-set-client-handshake 22 | explicit_defaults_for_timestamp 23 | 24 | slow_query_log 25 | long_query_time = 3 26 | slow-query-log-file = /var/log/mysql/mysql.slow.log 27 | log-error = /var/log/mysql/mysql.error.log 28 | 29 | default-time-zone = '+8:00' 30 | 31 | # Remove leading # to set options mainly useful for reporting servers. 32 | # The server defaults are faster for transactions and fast SELECTs. 33 | # Adjust sizes as needed, experiment to find the optimal values. 34 | # join_buffer_size = 128M 35 | # sort_buffer_size = 2M 36 | # read_rnd_buffer_size = 2M 37 | 38 | 39 | [mysql] 40 | default-character-set = utf8mb4 41 | -------------------------------------------------------------------------------- /repo/mysql57/compose.yml: -------------------------------------------------------------------------------- 1 | # mysql5.7 需要1g内存才可以安装。 2 | mysql57: 3 | image: mysql/mysql-server:${MYSQL5_VERSION} 4 | container_name: mysql5 5 | ports: 6 | - "${MYSQL5_HOST_PORT}:3306" 7 | volumes: 8 | - ${MYSQL5_CONF_FILE}:/etc/mysql/conf.d/mysql.cnf:ro 9 | - ${DATA_DIR}/mysql5:/var/lib/mysql/:rw 10 | - ${MYSQL5_LOG_DIR}:/var/log/mysql/:rw 11 | restart: always 12 | networks: 13 | - default 14 | labels: 15 | "type": "mysql" 16 | environment: 17 | MYSQL_ROOT_PASSWORD: "${MYSQL5_ROOT_PASSWORD}" 18 | MYSQL_ROOT_HOST: "${MYSQL5_ROOT_HOST}" 19 | TZ: "$TZ" 20 | -------------------------------------------------------------------------------- /repo/mysql57/env.sample: -------------------------------------------------------------------------------- 1 | # 2 | # MySQL5.7 3 | # 4 | MYSQL5_VERSION=5.7.28 5 | MYSQL5_HOST_PORT=3305 6 | MYSQL5_ROOT_PASSWORD=123456 7 | MYSQL5_ROOT_HOST=% 8 | MYSQL5_CONF_FILE=./env/mysql5/mysql.cnf 9 | MYSQL5_LOG_DIR=./logs/mysql5 10 | -------------------------------------------------------------------------------- /repo/mysql80/build/mysql.cnf: -------------------------------------------------------------------------------- 1 | # For advice on how to change settings please see 2 | # http://dev.mysql.com/doc/refman/5.6/en/server-configuration-defaults.html 3 | 4 | [client] 5 | port = 3306 6 | default-character-set = utf8mb4 7 | 8 | 9 | [mysqld] 10 | user = mysql 11 | port = 3306 12 | sql_mode = NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES 13 | 14 | default-storage-engine = InnoDB 15 | default-authentication-plugin = mysql_native_password 16 | character-set-server = utf8mb4 17 | collation-server = utf8mb4_unicode_ci 18 | init_connect = 'SET NAMES utf8mb4' 19 | 20 | disable-log-bin 21 | skip-character-set-client-handshake 22 | explicit_defaults_for_timestamp 23 | 24 | slow_query_log 25 | long_query_time = 3 26 | slow-query-log-file = /var/log/mysql/mysql.slow.log 27 | log-error = /var/log/mysql/mysql.error.log 28 | 29 | default-time-zone = '+8:00' 30 | 31 | # Remove leading # to set options mainly useful for reporting servers. 32 | # The server defaults are faster for transactions and fast SELECTs. 33 | # Adjust sizes as needed, experiment to find the optimal values. 34 | # join_buffer_size = 128M 35 | # sort_buffer_size = 2M 36 | # read_rnd_buffer_size = 2M 37 | 38 | [mysql] 39 | default-character-set = utf8mb4 40 | -------------------------------------------------------------------------------- /repo/mysql80/compose.yml: -------------------------------------------------------------------------------- 1 | # mysql8.x 需要2g内存才可以安装。 2 | mysql80: 3 | # 停用docker官方出的mysql8, 4 | # image: mysql:${MYSQL80_VERSION} 5 | image: mysql/mysql-server:${MYSQL80_VERSION} 6 | container_name: mysql80 7 | ports: 8 | - "${MYSQL80_HOST_PORT}:3306" 9 | volumes: 10 | - ${MYSQL80_CONF_FILE}:/etc/mysql/conf.d/mysql.cnf:ro 11 | - ${DATA_DIR}/mysql:/var/lib/mysql/:rw 12 | - ${MYSQL80_LOG_DIR}:/var/log/mysql/:rw 13 | restart: always 14 | networks: 15 | - default 16 | labels: 17 | "type": "mysql" 18 | environment: 19 | MYSQL_ROOT_PASSWORD: "${MYSQL80_ROOT_PASSWORD}" 20 | MYSQL_ROOT_HOST: "${MYSQL80_ROOT_HOST}" 21 | TZ: "#$TZ" -------------------------------------------------------------------------------- /repo/mysql80/env.sample: -------------------------------------------------------------------------------- 1 | # MySQL8 2 | MYSQL80_VERSION=8.0.30 3 | MYSQL80_HOST_PORT=3306 4 | MYSQL80_ROOT_PASSWORD=123456 5 | MYSQL80_ROOT_HOST=% 6 | MYSQL80_CONF_FILE=./env/mysql80/mysql.cnf 7 | MYSQL80_LOG_DIR=./logs/mysql80 8 | -------------------------------------------------------------------------------- /repo/nginx/build/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG NGINX_VERSION 2 | FROM ${NGINX_VERSION} 3 | 4 | ARG TZ 5 | ARG NGINX_VERSION 6 | ARG CONTAINER_PACKAGE_URL 7 | ARG NGINX_INSTALL_APPS 8 | 9 | 10 | RUN if [ "${CONTAINER_PACKAGE_URL}" != "" ]; then \ 11 | sed -i "s/dl-cdn.alpinelinux.org/${CONTAINER_PACKAGE_URL}/g" /etc/apk/repositories; \ 12 | fi 13 | 14 | COPY acme_install.sh /root/acme_install.sh 15 | 16 | # Install acme.sh 17 | RUN apk add openssl 18 | RUN sh /root/acme_install.sh 19 | 20 | 21 | WORKDIR /www 22 | -------------------------------------------------------------------------------- /repo/nginx/build/acme/readme.md: -------------------------------------------------------------------------------- 1 | 占位符 -------------------------------------------------------------------------------- /repo/nginx/build/acme_install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | curl https://get.acme.sh | sh -s email=xii@exmaple.com && alias acme.sh=~/.acme.sh/acme.sh -------------------------------------------------------------------------------- /repo/nginx/build/dhparam.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN DH PARAMETERS----- 2 | MIIBCAKCAQEA8Ut8wXFhhPNuSQHJzuRy0eRwIA7t4lR/gyiXk0Txg3YXMXD1F37+ 3 | dcKS6ulD/8xaD25vf7JIwvm3fP0RiscnjB8HrpMQdR1jiYqK//2KbqNyTf791G4d 4 | Eg2gLRIh+I9oBDXt/1Ue9jGbxnaSYYvW2jU/3ddQXI+Udv7XfmimToIdl6f7eXZi 5 | vxDmKrdFpODWghp0VWXAulJdGG75ZGqpsJZrgTUklUmXfEsxUdHy2TFflaIZDIBN 6 | NqxB6yYtJz1EoVqmowUVr8Srd/46CLi3t2TZ/yzjyBVRl+ku07bqNhzGYWqmpJ++ 7 | MAcjIqkr4C7kxono6g6zknEJgL/fNLNXiwIBAg== 8 | -----END DH PARAMETERS----- 9 | -------------------------------------------------------------------------------- /repo/nginx/build/fastcgi-php.conf: -------------------------------------------------------------------------------- 1 | 2 | # regex to split $uri to $fastcgi_script_name and $fastcgi_path 3 | # fastcgi_split_path_info ^(.+\.php)(/.+)$; 4 | 5 | # 改用lnmp.org的配置 6 | fastcgi_split_path_info ^(.+?\.php)(/.*)$; 7 | 8 | # Check that the PHP script exists before passing it 9 | try_files $fastcgi_script_name =404; 10 | 11 | # Bypass the fact that try_files resets $fastcgi_path_info 12 | # see: http://trac.nginx.org/nginx/ticket/321 13 | set $path_info $fastcgi_path_info; 14 | 15 | #fastcgi_param PATH_INFO $path_info; 16 | fastcgi_read_timeout 3600; 17 | 18 | fastcgi_index index.php; 19 | -------------------------------------------------------------------------------- /repo/nginx/build/fastcgi_params: -------------------------------------------------------------------------------- 1 | 2 | fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; 3 | fastcgi_param QUERY_STRING $query_string; 4 | fastcgi_param REQUEST_METHOD $request_method; 5 | fastcgi_param CONTENT_TYPE $content_type; 6 | fastcgi_param CONTENT_LENGTH $content_length; 7 | 8 | fastcgi_param SCRIPT_NAME $fastcgi_script_name; 9 | fastcgi_param REQUEST_URI $request_uri; 10 | fastcgi_param DOCUMENT_URI $document_uri; 11 | fastcgi_param DOCUMENT_ROOT $document_root; 12 | fastcgi_param SERVER_PROTOCOL $server_protocol; 13 | fastcgi_param REQUEST_SCHEME $scheme; 14 | fastcgi_param HTTPS $https if_not_empty; 15 | 16 | fastcgi_param GATEWAY_INTERFACE CGI/1.1; 17 | fastcgi_param SERVER_SOFTWARE nginx/$nginx_version; 18 | 19 | fastcgi_param REMOTE_ADDR $remote_addr; 20 | fastcgi_param REMOTE_PORT $remote_port; 21 | fastcgi_param REMOTE_PORT $remote_port; 22 | fastcgi_param SERVER_ADDR $server_addr; 23 | fastcgi_param SERVER_PORT $server_port; 24 | fastcgi_param SERVER_NAME $server_name; 25 | 26 | # PHP only, required if PHP was built with --enable-force-cgi-redirect 27 | fastcgi_param REDIRECT_STATUS 200; 28 | -------------------------------------------------------------------------------- /repo/nginx/build/helper/cut_log.sh: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiiapp/xii/7d7c08c767774fb203b6289d901ee026c613510f/repo/nginx/build/helper/cut_log.sh -------------------------------------------------------------------------------- /repo/nginx/build/helper/readme.md: -------------------------------------------------------------------------------- 1 | 存放一些nginx用得到的辅助脚本。构建image时会用到。 -------------------------------------------------------------------------------- /repo/nginx/build/nginx.conf: -------------------------------------------------------------------------------- 1 | 2 | user nginx; 3 | worker_processes 1; 4 | 5 | pid /var/run/nginx.pid; 6 | error_log /var/log/nginx/nginx.error.log warn; 7 | 8 | events { 9 | worker_connections 1024; 10 | } 11 | 12 | 13 | http { 14 | include /etc/nginx/mime.types; 15 | default_type application/octet-stream; 16 | 17 | log_format main '$remote_addr - $remote_user [$time_local] "$request" ' 18 | '$status $body_bytes_sent "$http_referer" ' 19 | '"$http_user_agent" "$http_x_forwarded_for"'; 20 | 21 | log_format cloudflare '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $http_cf_ray $http_cf_connecting_ip $http_x_forwarded_for $http_x_forwarded_proto $http_true_client_ip $http_cf_ipcountry $http_cf_visitor $http_cdn_loop'; 22 | 23 | 24 | access_log /dev/null; 25 | #access_log /var/log/dnmp/nginx.access.log main; 26 | 27 | # hide verson string 28 | server_tokens off; 29 | sendfile on; 30 | #tcp_nopush on; 31 | client_max_body_size 100M; 32 | keepalive_timeout 65; 33 | 34 | # OCSP Stapling 35 | ssl_stapling on; 36 | ssl_stapling_verify on; 37 | resolver 1.1.1.1 1.0.0.1 [2606:4700:4700::1111] [2606:4700:4700::1001] 8.8.8.8 8.8.4.4 [2001:4860:4860::8888] [2001:4860:4860::8844] 208.67.222.222 208.67.220.220 [2620:119:35::35] [2620:119:53::53] 9.9.9.9 149.112.112.112 [2620:fe::fe] [2620:fe::9] 64.6.64.6 64.6.65.6 [2620:74:1b::1:1] [2620:74:1c::2:2] valid=60s; 38 | resolver_timeout 2s; 39 | 40 | include /etc/nginx/vhost/*.conf; 41 | } 42 | -------------------------------------------------------------------------------- /repo/nginx/build/other/brotli.conf: -------------------------------------------------------------------------------- 1 | # brotli 2 | 3 | #brotli on; 4 | #brotli_comp_level 6; 5 | #brotli_types text/plain text/css text/xml application/json application/javascript application/rss+xml application/atom+xml image/svg+xml; 6 | -------------------------------------------------------------------------------- /repo/nginx/build/other/disable_html_cache.conf: -------------------------------------------------------------------------------- 1 | # Disable HTML caching 2 | location ~* \.(?:html?)$ { 3 | add_header Cache-Control "no-cache"; 4 | access_log off; 5 | } -------------------------------------------------------------------------------- /repo/nginx/build/other/general.conf: -------------------------------------------------------------------------------- 1 | #站点通用设置,内容有: 2 | #1.图标、robot.txt的日志记录配置。 3 | #2.资源文件的缓存配置。 4 | #3.字体文件的苦cors配置。 5 | 6 | # favicon.ico 7 | location = /favicon.ico { 8 | log_not_found off; 9 | access_log off; 10 | } 11 | 12 | # robots.txt 13 | location = /robots.txt { 14 | log_not_found off; 15 | access_log off; 16 | } 17 | 18 | # assets, media 19 | location ~* \.(?:css(\.map)?|js(\.map)?|jpe?g|png|gif|ico|cur|heic|webp|tiff?|mp3|m4a|aac|ogg|midi?|wav|mp4|mov|webm|mpe?g|avi|ogv|flv|wmv)$ { 20 | expires 7d; 21 | access_log off; 22 | } 23 | 24 | 25 | 26 | # svg, fonts 27 | location ~* \.(?:svgz?|ttf|ttc|otf|eot|woff2?)$ { 28 | add_header Access-Control-Allow-Origin "*"; 29 | expires 7d; 30 | access_log off; 31 | } -------------------------------------------------------------------------------- /repo/nginx/build/other/gzip.conf: -------------------------------------------------------------------------------- 1 | # gzip 2 | gzip on; 3 | gzip_vary on; 4 | gzip_proxied any; 5 | gzip_comp_level 6; 6 | gzip_types text/plain text/css text/xml application/json application/javascript application/rss+xml application/atom+xml image/svg+xml; -------------------------------------------------------------------------------- /repo/nginx/build/other/proxy.conf: -------------------------------------------------------------------------------- 1 | # 反向代理通用设置 2 | 3 | proxy_http_version 1.1; 4 | proxy_cache_bypass $http_upgrade; 5 | 6 | # Proxy SSL 7 | proxy_ssl_server_name on; 8 | 9 | # Proxy headers 10 | proxy_set_header Upgrade $http_upgrade; 11 | proxy_set_header Connection $connection_upgrade; 12 | proxy_set_header X-Real-IP $remote_addr; 13 | proxy_set_header Forwarded $proxy_add_forwarded; 14 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 15 | proxy_set_header X-Forwarded-Proto $scheme; 16 | proxy_set_header X-Forwarded-Host $host; 17 | proxy_set_header X-Forwarded-Port $server_port; 18 | 19 | # Proxy timeouts 20 | proxy_connect_timeout 60s; 21 | proxy_send_timeout 60s; 22 | proxy_read_timeout 60s; -------------------------------------------------------------------------------- /repo/nginx/build/other/python_uwsgi.conf: -------------------------------------------------------------------------------- 1 | # default uwsgi_params 2 | include uwsgi_params; 3 | 4 | # uwsgi settings 5 | # uwsgi_pass unix:/tmp/uwsgi.sock; 6 | uwsgi_pass 127.0.0.1:8000; 7 | uwsgi_param Host $host; 8 | uwsgi_param X-Real-IP $remote_addr; 9 | uwsgi_param X-Forwarded-For $proxy_add_x_forwarded_for; 10 | uwsgi_param X-Forwarded-Proto $http_x_forwarded_proto; -------------------------------------------------------------------------------- /repo/nginx/build/other/security.conf: -------------------------------------------------------------------------------- 1 | # 不发送Nginx版本号 2 | server_tokens off; 3 | 4 | 5 | # 启用大部分现代浏览器内置的 the Cross-site scripting (XSS) 过滤. 6 | # 通常缺省情况下已经启用, 所以本选项为为本网站重启过滤器,以防其被用户禁用. 7 | # https://www.owasp.org/index.php/List_of_useful_HTTP_headers 8 | add_header X-XSS-Protection "1; mode=block" always; 9 | 10 | # 服务用户提供的内容时, 包含 X-Content-Type-Options: nosniff 头选项,配合 Content-Type: 头选项, 11 | # 来禁用某些浏览器的 content-type 探测. 12 | # https://www.owasp.org/index.php/List_of_useful_HTTP_headers 13 | # 当前支持 IE > 8 http://blogs.msdn.com/b/ie/archive/2008/09/02/ie8-security-part-vi-beta-2-update.aspx 14 | # http://msdn.microsoft.com/en-us/library/ie/gg622941(v=vs.85).aspx 15 | # 火狐 '不久'支持 https://bugzilla.mozilla.org/show_bug.cgi?id=471020 16 | add_header X-Content-Type-Options "nosniff" always; 17 | 18 | # Referrer-Policy 首部用来监管哪些访问来源信息——会在 Referer 中发送——应该被包含在生成的请求当中。 19 | # https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Referrer-Policy 20 | add_header Referrer-Policy "no-referrer-when-downgrade" always; 21 | 22 | # 启用 Content Security Policy (CSP) (和支持它的浏览器(http://caniuse.com/#feat=contentsecuritypolicy)后, 23 | # 你可以告诉浏览器它仅能从你明确允许的域名下载内容 24 | # http://www.html5rocks.com/en/tutorials/security/content-security-policy/ 25 | # https://www.owasp.org/index.php/Content_Security_Policy 26 | # 修改应用代码, 通过禁用css和js的 'unsafe-inline' 'unsafe-eval' 指标提高安全性 27 | # (对内联css和js同样适用). 28 | # 更多: http://www.html5rocks.com/en/tutorials/security/content-security-policy/#inline-code-considered-harmful 29 | add_header Content-Security-Policy "default-src 'self' http: https: ws: wss: data: blob: 'unsafe-inline'; frame-ancestors 'self';" always; 30 | 31 | 32 | # Permissions-Policy 是一个新标头,允许站点控制可以在浏览器中使用哪些 API 或功能 33 | # example: add_header Permissions-Policy "geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment= ()"; 34 | # 35 | # 为区分不同用户群体,更加精准的推送广告,谷歌启用了新的追踪技术FLoC(同类群组联合学习 Federated Learning of Cohorts)以替代 cookie。 36 | # 谷歌表示,不希望加入 FLoC 的网站可以发送以下 HTTP 标头:permissions-policy: interest-cohort=() 37 | add_header Permissions-Policy "interest-cohort=()" always; 38 | 39 | # 启用 HSTS(HTTP Strict Transport Security) https://developer.mozilla.org/en-US/docs/Security/HTTP_Strict_Transport_Security 40 | # 避免 ssl stripping https://en.wikipedia.org/wiki/SSL_stripping#SSL_stripping 41 | # 或 https://hstspreload.org/ 42 | add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; 43 | 44 | -------------------------------------------------------------------------------- /repo/nginx/build/other/wellknow.conf: -------------------------------------------------------------------------------- 1 | location ~ /.well-known { 2 | allow all; 3 | } -------------------------------------------------------------------------------- /repo/nginx/build/rewrite/codeigniter.conf: -------------------------------------------------------------------------------- 1 | location / { 2 | try_files $uri $uri/ /index.php$is_args$args; 3 | } 4 | -------------------------------------------------------------------------------- /repo/nginx/build/rewrite/dabr.conf: -------------------------------------------------------------------------------- 1 | location / { 2 | if (!-e $request_filename) { 3 | rewrite ^/(.*)$ /index.php?q=$1 last; 4 | } 5 | } -------------------------------------------------------------------------------- /repo/nginx/build/rewrite/dedecms.conf: -------------------------------------------------------------------------------- 1 | location / { 2 | rewrite "^/index.html$" /index.php last; 3 | rewrite "^/list-([0-9]+)\.html$" /plus/list.php?tid=$1 last; 4 | rewrite "^/list-([0-9]+)-([0-9]+)-([0-9]+)\.html$" /plus/list.php?tid=$1&totalresult=$2&PageNo=$3 last; 5 | rewrite "^/view-([0-9]+)-1\.html$" /plus/view.php?arcID=$1 last; 6 | rewrite "^/view-([0-9]+)-([0-9]+)\.html$" /plus/view.php?aid=$1&pageno=$2 last; 7 | rewrite "^/tags.html$" /tags.php last; 8 | rewrite "^/tag-([0-9]+)-([0-9]+)\.html$" /tags.php?/$1/$2/ last; 9 | break; 10 | } -------------------------------------------------------------------------------- /repo/nginx/build/rewrite/discuz.conf: -------------------------------------------------------------------------------- 1 | location / { 2 | rewrite ^/archiver/((fid|tid)-[\w\-]+\.html)$ /archiver/index.php?$1 last; 3 | rewrite ^/forum-([0-9]+)-([0-9]+)\.html$ /forumdisplay.php?fid=$1&page=$2 last; 4 | rewrite ^/thread-([0-9]+)-([0-9]+)-([0-9]+)\.html$ /viewthread.php?tid=$1&extra=page%3D$3&page=$2 last; 5 | rewrite ^/space-(username|uid)-(.+)\.html$ /space.php?$1=$2 last; 6 | rewrite ^/tag-(.+)\.html$ /tag.php?name=$1 last; 7 | } -------------------------------------------------------------------------------- /repo/nginx/build/rewrite/discuzx.conf: -------------------------------------------------------------------------------- 1 | rewrite ^([^\.]*)/topic-(.+)\.html$ $1/portal.php?mod=topic&topic=$2 last; 2 | rewrite ^([^\.]*)/article-([0-9]+)-([0-9]+)\.html$ $1/portal.php?mod=view&aid=$2&page=$3 last; 3 | rewrite ^([^\.]*)/forum-(\w+)-([0-9]+)\.html$ $1/forum.php?mod=forumdisplay&fid=$2&page=$3 last; 4 | rewrite ^([^\.]*)/thread-([0-9]+)-([0-9]+)-([0-9]+)\.html$ $1/forum.php?mod=viewthread&tid=$2&extra=page%3D$4&page=$3 last; 5 | rewrite ^([^\.]*)/group-([0-9]+)-([0-9]+)\.html$ $1/forum.php?mod=group&fid=$2&page=$3 last; 6 | rewrite ^([^\.]*)/space-(username|uid)-(.+)\.html$ $1/home.php?mod=space&$2=$3 last; 7 | rewrite ^([^\.]*)/blog-([0-9]+)-([0-9]+)\.html$ $1/home.php?mod=space&uid=$2&do=blog&id=$3 last; 8 | rewrite ^([^\.]*)/archiver/(fid|tid)-([0-9]+)\.html$ $1/archiver/index.php?action=$2&value=$3 last; 9 | rewrite ^([^\.]*)/([a-z]+[a-z0-9_]*)-([a-z0-9_\-]+)\.html$ $1/plugin.php?id=$2:$3 last; 10 | if (!-e $request_filename) { 11 | return 404; 12 | } 13 | -------------------------------------------------------------------------------- /repo/nginx/build/rewrite/discuzx2.conf: -------------------------------------------------------------------------------- 1 | location /bbs/ { 2 | rewrite ^([^\.]*)/topic-(.+)\.html$ $1/portal.php?mod=topic&topic=$2 last; 3 | rewrite ^([^\.]*)/article-([0-9]+)-([0-9]+)\.html$ $1/portal.php?mod=view&aid=$2&page=$3 last; 4 | rewrite ^([^\.]*)/forum-(\w+)-([0-9]+)\.html$ $1/forum.php?mod=forumdisplay&fid=$2&page=$3 last; 5 | rewrite ^([^\.]*)/thread-([0-9]+)-([0-9]+)-([0-9]+)\.html$ $1/forum.php?mod=viewthread&tid=$2&extra=page%3D$4&page=$3 last; 6 | rewrite ^([^\.]*)/group-([0-9]+)-([0-9]+)\.html$ $1/forum.php?mod=group&fid=$2&page=$3 last; 7 | rewrite ^([^\.]*)/space-(username|uid)-(.+)\.html$ $1/home.php?mod=space&$2=$3 last; 8 | rewrite ^([^\.]*)/blog-([0-9]+)-([0-9]+)\.html$ $1/home.php?mod=space&uid=$2&do=blog&id=$3 last; 9 | rewrite ^([^\.]*)/(fid|tid)-([0-9]+)\.html$ $1/index.php?action=$2&value=$3 last; 10 | rewrite ^([^\.]*)/([a-z]+[a-z0-9_]*)-([a-z0-9_\-]+)\.html$ $1/plugin.php?id=$2:$3 last; 11 | if (!-e $request_filename) { 12 | return 404; 13 | } 14 | } -------------------------------------------------------------------------------- /repo/nginx/build/rewrite/drupal.conf: -------------------------------------------------------------------------------- 1 | if (!-e $request_filename) { 2 | rewrite ^/(.*)$ /index.php?q=$1 last; 3 | } -------------------------------------------------------------------------------- /repo/nginx/build/rewrite/ecshop.conf: -------------------------------------------------------------------------------- 1 | if (!-e $request_filename) 2 | { 3 | rewrite "^/index\.html" /index.php last; 4 | rewrite "^/category$" /index.php last; 5 | rewrite "^/feed-c([0-9]+)\.xml$" /feed.php?cat=$1 last; 6 | rewrite "^/feed-b([0-9]+)\.xml$" /feed.php?brand=$1 last; 7 | rewrite "^/feed\.xml$" /feed.php last; 8 | rewrite "^/category-([0-9]+)-b([0-9]+)-min([0-9]+)-max([0-9]+)-attr([^-]*)-([0-9]+)-(.+)-([a-zA-Z]+)(.*)\.html$" /category.php?id=$1&brand=$2&price_min=$3&price_max=$4&filter_attr=$5&page=$6&sort=$7&order=$8 last; 9 | rewrite "^/category-([0-9]+)-b([0-9]+)-min([0-9]+)-max([0-9]+)-attr([^-]*)(.*)\.html$" /category.php?id=$1&brand=$2&price_min=$3&price_max=$4&filter_attr=$5 last; 10 | rewrite "^/category-([0-9]+)-b([0-9]+)-([0-9]+)-(.+)-([a-zA-Z]+)(.*)\.html$" /category.php?id=$1&brand=$2&page=$3&sort=$4&order=$5 last; 11 | rewrite "^/category-([0-9]+)-b([0-9]+)-([0-9]+)(.*)\.html$" /category.php?id=$1&brand=$2&page=$3 last; 12 | rewrite "^/category-([0-9]+)-b([0-9]+)(.*)\.html$" /category.php?id=$1&brand=$2 last; 13 | rewrite "^/category-([0-9]+)(.*)\.html$" /category.php?id=$1 last; 14 | rewrite "^/goods-([0-9]+)(.*)\.html" /goods.php?id=$1 last; 15 | rewrite "^/article_cat-([0-9]+)-([0-9]+)-(.+)-([a-zA-Z]+)(.*)\.html$" /article_cat.php?id=$1&page=$2&sort=$3&order=$4 last; 16 | rewrite "^/article_cat-([0-9]+)-([0-9]+)(.*)\.html$" /article_cat.php?id=$1&page=$2 last; 17 | rewrite "^/article_cat-([0-9]+)(.*)\.html$" /article_cat.php?id=$1 last; 18 | rewrite "^/article-([0-9]+)(.*)\.html$" /article.php?id=$1 last; 19 | rewrite "^/brand-([0-9]+)-c([0-9]+)-([0-9]+)-(.+)-([a-zA-Z]+)\.html" /brand.php?id=$1&cat=$2&page=$3&sort=$4&order=$5 last; 20 | rewrite "^/brand-([0-9]+)-c([0-9]+)-([0-9]+)(.*)\.html" /brand.php?id=$1&cat=$2&page=$3 last; 21 | rewrite "^/brand-([0-9]+)-c([0-9]+)(.*)\.html" /brand.php?id=$1&cat=$2 last; 22 | rewrite "^/brand-([0-9]+)(.*)\.html" /brand.php?id=$1 last; 23 | rewrite "^/tag-(.*)\.html" /search.php?keywords=$1 last; 24 | rewrite "^/snatch-([0-9]+)\.html$" /snatch.php?id=$1 last; 25 | rewrite "^/group_buy-([0-9]+)\.html$" /group_buy.php?act=view&id=$1 last; 26 | rewrite "^/auction-([0-9]+)\.html$" /auction.php?act=view&id=$1 last; 27 | rewrite "^/exchange-id([0-9]+)(.*)\.html$" /exchange.php?id=$1&act=view last; 28 | rewrite "^/exchange-([0-9]+)-min([0-9]+)-max([0-9]+)-([0-9]+)-(.+)-([a-zA-Z]+)(.*)\.html$" /exchange.php?cat_id=$1&integral_min=$2&integral_max=$3&page=$4&sort=$5&order=$6 last; 29 | rewrite ^/exchange-([0-9]+)-([0-9]+)-(.+)-([a-zA-Z]+)(.*)\.html$" /exchange.php?cat_id=$1&page=$2&sort=$3&order=$4 last; 30 | rewrite "^/exchange-([0-9]+)-([0-9]+)(.*)\.html$" /exchange.php?cat_id=$1&page=$2 last; 31 | rewrite "^/exchange-([0-9]+)(.*)\.html$" /exchange.php?cat_id=$1 last; 32 | } -------------------------------------------------------------------------------- /repo/nginx/build/rewrite/joomla.conf: -------------------------------------------------------------------------------- 1 | location / { 2 | try_files $uri $uri/ /index.php?$args; 3 | } -------------------------------------------------------------------------------- /repo/nginx/build/rewrite/laravel.conf: -------------------------------------------------------------------------------- 1 | location / { 2 | try_files $uri $uri/ /index.php?$query_string; 3 | } -------------------------------------------------------------------------------- /repo/nginx/build/rewrite/phpwind.conf: -------------------------------------------------------------------------------- 1 | location / { 2 | rewrite ^(.*)-htm-(.*)$ $1.php?$2 last; 3 | rewrite ^(.*)/simple/([a-z0-9\_]+\.html)$ $1/simple/index.php?$2 last; 4 | } -------------------------------------------------------------------------------- /repo/nginx/build/rewrite/sablog.conf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiiapp/xii/7d7c08c767774fb203b6289d901ee026c613510f/repo/nginx/build/rewrite/sablog.conf -------------------------------------------------------------------------------- /repo/nginx/build/rewrite/shopex.conf: -------------------------------------------------------------------------------- 1 | location / { 2 | if (!-e $request_filename) { 3 | rewrite ^/(.+\.(html|xml|json|htm|php|jsp|asp|shtml))$ /index.php?$1 last; 4 | } 5 | } -------------------------------------------------------------------------------- /repo/nginx/build/rewrite/thinkphp.conf: -------------------------------------------------------------------------------- 1 | location / { 2 | if (!-e $request_filename) { 3 | rewrite ^(.*)$ /index.php?s=/$1 last; 4 | break; 5 | } 6 | } -------------------------------------------------------------------------------- /repo/nginx/build/rewrite/typecho.conf: -------------------------------------------------------------------------------- 1 | if (!-e $request_filename) { 2 | rewrite ^(.*)$ /index.php$1 last; 3 | } 4 | -------------------------------------------------------------------------------- /repo/nginx/build/rewrite/typecho2.conf: -------------------------------------------------------------------------------- 1 | location /typecho/ { 2 | if (!-e $request_filename) { 3 | rewrite ^(.*)$ /typecho/index.php$1 last; 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /repo/nginx/build/rewrite/wordpress.conf: -------------------------------------------------------------------------------- 1 | location / { 2 | try_files $uri $uri/ /index.php?$args; 3 | } 4 | 5 | # Add trailing slash to */wp-admin requests. 6 | rewrite /wp-admin$ $scheme://$host$uri/ permanent; -------------------------------------------------------------------------------- /repo/nginx/build/rewrite/wp2.conf: -------------------------------------------------------------------------------- 1 | location /wp/ { 2 | try_files $uri $uri/ /wp/index.php?$args; 3 | } 4 | 5 | # Add trailing slash to */wp-admin requests. 6 | rewrite /wp-admin$ $scheme://$host$uri/ permanent; -------------------------------------------------------------------------------- /repo/nginx/build/rewrite/yii2.conf: -------------------------------------------------------------------------------- 1 | location / { 2 | # Redirect everything that isn't a real file to index.php 3 | try_files $uri $uri/ /index.php$is_args$args; 4 | } -------------------------------------------------------------------------------- /repo/nginx/build/rewrite/zblog.conf: -------------------------------------------------------------------------------- 1 | if (-f $request_filename/index.html){ 2 | rewrite (.*) $1/index.html break; 3 | } 4 | if (-f $request_filename/index.php){ 5 | rewrite (.*) $1/index.php; 6 | } 7 | if (!-f $request_filename){ 8 | rewrite (.*) /index.php; 9 | } 10 | -------------------------------------------------------------------------------- /repo/nginx/build/vhost/localhost.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80 default; 3 | server_name localhost; 4 | root /www/localhost; 5 | index index.php index.html index.htm; 6 | 7 | access_log /dev/null; 8 | error_log /var/log/nginx/nginx.localhost.error.log warn; 9 | error_page 500 502 503 504 /50x.html; 10 | location = /50x.html { 11 | root /usr/share/nginx/html; 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /repo/nginx/compose.yml: -------------------------------------------------------------------------------- 1 | nginx: 2 | build: 3 | context: ./env/nginx 4 | args: 5 | NGINX_VERSION: nginx:${NGINX_VERSION} 6 | CONTAINER_PACKAGE_URL: ${CONTAINER_PACKAGE_URL} 7 | NGINX_INSTALL_APPS: ${NGINX_INSTALL_APPS} 8 | container_name: nginx 9 | ports: 10 | - "${NGINX_HTTP_HOST_PORT}:80" 11 | - "${NGINX_HTTPS_HOST_PORT}:443" 12 | volumes: 13 | - ${SOURCE_DIR}:/www/:rw 14 | - ${NGINX_SSL_CERTIFICATE_DIR}:/etc/nginx/ssl:rw 15 | - ${NGINX_REWRITE_DIR}:/etc/nginx/rewrite/:rw 16 | - ${NGINX_OTHER_DIR}:/etc/nginx/other/:rw 17 | - ${NGINX_VHOST_DIR}:/etc/nginx/vhost/:rw 18 | - ${NGINX_CONF_FILE}:/etc/nginx/nginx.conf:rw 19 | - ${NGINX_FASTCGI_PHP_CONF}:/etc/nginx/fastcgi-php.conf:rw 20 | - ${NGINX_FASTCGI_PARAMS}:/etc/nginx/fastcgi_params:rw 21 | - ${NGINX_DHPARAM_PARAMS}:/etc/nginx/dhparam.pem:rw 22 | - ${NGINX_LOG_DIR}:/var/log/nginx/:rw 23 | - ${NGINX_ACME_DIR}:/root/.acme.sh/:rw 24 | - ${NGINX_CRONTAB_DIR}:/var/spool/cron/crontabs:rw 25 | environment: 26 | TZ: "$TZ" 27 | restart: always 28 | labels: 29 | "type": "nginx" 30 | networks: 31 | - default -------------------------------------------------------------------------------- /repo/nginx/env.sample: -------------------------------------------------------------------------------- 1 | #nginx配置 2 | NGINX_VERSION=1.23.1-alpine 3 | NGINX_HTTP_HOST_PORT=80 4 | NGINX_HTTPS_HOST_PORT=443 5 | NGINX_REWRITE_DIR=./env/nginx/rewrite 6 | NGINX_VHOST_DIR=./env/nginx/vhost 7 | NGINX_CONF_FILE=./env/nginx/nginx.conf 8 | NGINX_FASTCGI_PHP_CONF=./env/nginx/fastcgi-php.conf 9 | NGINX_FASTCGI_PARAMS=./env/nginx/fastcgi_params 10 | NGINX_DHPARAM_PARAMS=./env/nginx/dhparam.pem 11 | NGINX_SSL_CERTIFICATE_DIR=./env/nginx/ssl 12 | NGINX_OTHER_DIR=./env/nginx/other 13 | NGINX_LOG_DIR=./logs/nginx 14 | NGINX_ACME_DIR=./env/nginx/acme 15 | NGINX_CRONTAB_DIR=./env/nginx/crontab 16 | NGINX_INSTALL_APPS= -------------------------------------------------------------------------------- /repo/node10/compose.yml: -------------------------------------------------------------------------------- 1 | node: 2 | image: node:${NODE10_VERSION} 3 | environment: 4 | - NODE_ENV=production 5 | volumes: 6 | - ${SOURCE_DIR}:/www/:rw 7 | expose: 8 | - "8081" 9 | networks: 10 | - default 11 | stdin_open: true 12 | # 解决 docker-compose.yml 启动容器秒停 出错停止问题,加tty:true 13 | tty: true 14 | labels: 15 | "type": "node" -------------------------------------------------------------------------------- /repo/node10/env.sample: -------------------------------------------------------------------------------- 1 | # 2 | # Node环境 3 | # 版本信息:https://hub.docker.com/_/node 4 | # 直接查看版本信息:https://raw.githubusercontent.com/docker-library/official-images/master/library/node 5 | # 6 | NODE10_VERSION=10.16.1-alpine -------------------------------------------------------------------------------- /repo/node14/compose.yml: -------------------------------------------------------------------------------- 1 | node: 2 | image: node:${NODE14_VERSION} 3 | environment: 4 | - NODE_ENV=production 5 | volumes: 6 | - ${SOURCE_DIR}:/www/:rw 7 | expose: 8 | - "8081" 9 | networks: 10 | - default 11 | stdin_open: true 12 | # 解决 docker-compose.yml 启动容器秒停 出错停止问题,加tty:true 13 | tty: true 14 | labels: 15 | "type": "node" -------------------------------------------------------------------------------- /repo/node14/env.sample: -------------------------------------------------------------------------------- 1 | # 2 | # Node环境 3 | # 版本信息:https://hub.docker.com/_/node 4 | # 直接查看版本信息:https://raw.githubusercontent.com/docker-library/official-images/master/library/node 5 | # 6 | NODE14_VERSION=14-alpine3.15 -------------------------------------------------------------------------------- /repo/node16/compose.yml: -------------------------------------------------------------------------------- 1 | node: 2 | image: node:${NODE16_VERSION} 3 | environment: 4 | - NODE_ENV=production 5 | volumes: 6 | - ${SOURCE_DIR}:/www/:rw 7 | expose: 8 | - "8081" 9 | networks: 10 | - default 11 | stdin_open: true 12 | # 解决 docker-compose.yml 启动容器秒停 出错停止问题,加tty:true 13 | tty: true 14 | labels: 15 | "type": "node" -------------------------------------------------------------------------------- /repo/node16/env.sample: -------------------------------------------------------------------------------- 1 | # 2 | # Node环境 3 | # 版本信息:https://hub.docker.com/_/node 4 | # 直接查看版本信息:https://raw.githubusercontent.com/docker-library/official-images/master/library/node 5 | # 6 | NODE16_VERSION=16-alpine3.16 -------------------------------------------------------------------------------- /repo/node18/compose.yml: -------------------------------------------------------------------------------- 1 | node: 2 | image: node:${NODE18_VERSION} 3 | environment: 4 | - NODE_ENV=production 5 | volumes: 6 | - ${SOURCE_DIR}:/www/:rw 7 | expose: 8 | - "8081" 9 | networks: 10 | - default 11 | stdin_open: true 12 | # 解决 docker-compose.yml 启动容器秒停 出错停止问题,加tty:true 13 | tty: true 14 | labels: 15 | "type": "node" -------------------------------------------------------------------------------- /repo/node18/env.sample: -------------------------------------------------------------------------------- 1 | # 2 | # Node环境 3 | # 版本信息:https://hub.docker.com/_/node 4 | # 直接查看版本信息:https://raw.githubusercontent.com/docker-library/official-images/master/library/node 5 | # 6 | NODE18_VERSION=18-alpine -------------------------------------------------------------------------------- /repo/php73/build/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG PHP_VERSION 2 | FROM ${PHP_VERSION} 3 | 4 | ARG TZ 5 | ARG PHP_EXTENSIONS 6 | ARG CONTAINER_PACKAGE_URL 7 | 8 | 9 | RUN if [ $CONTAINER_PACKAGE_URL ] ; then sed -i "s/dl-cdn.alpinelinux.org/${CONTAINER_PACKAGE_URL}/g" /etc/apk/repositories ; fi 10 | 11 | 12 | COPY extensions /tmp/extensions 13 | WORKDIR /tmp/extensions 14 | RUN chmod +x install.sh \ 15 | && sh install.sh 16 | 17 | ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/ 18 | 19 | 20 | ADD extensions/install-php-extensions /usr/local/bin/ 21 | 22 | RUN chmod uga+x /usr/local/bin/install-php-extensions 23 | 24 | RUN apk --no-cache add tzdata \ 25 | && cp "/usr/share/zoneinfo/$TZ" /etc/localtime \ 26 | && echo "$TZ" > /etc/timezone 27 | 28 | 29 | # Fix: https://github.com/docker-library/php/issues/1121 30 | RUN apk add --no-cache --repository http://${CONTAINER_PACKAGE_URL}/alpine/v3.13/community/ gnu-libiconv=1.15-r3 31 | ENV LD_PRELOAD /usr/lib/preloadable_libiconv.so php 32 | 33 | 34 | # Install composer and change it's cache home 35 | RUN chmod +x install-composer.sh \ 36 | && sh install-composer.sh \ 37 | && rm -rf /tmp/extensions 38 | ENV COMPOSER_HOME=/tmp/composer 39 | 40 | # php image's www-data user uid & gid are 82, change them to 1000 (primary user) 41 | RUN apk --no-cache add shadow && usermod -u 1000 www-data && groupmod -g 1000 www-data 42 | 43 | 44 | WORKDIR /www 45 | -------------------------------------------------------------------------------- /repo/php73/build/extensions/install-composer.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # The latest mirror's composer version only support for PHP 7.2.5 4 | # And if your PHP version is lesser than that, will be download supported version. 5 | supportLatest=$(php -r "echo version_compare(PHP_VERSION, '7.2.5', '>');") 6 | 7 | if [ "$supportLatest" -eq "1" ]; then 8 | curl -o /usr/bin/composer https://mirrors.aliyun.com/composer/composer.phar \ 9 | && chmod +x /usr/bin/composer 10 | else 11 | curl -o /tmp/composer-setup.php https://getcomposer.org/installer \ 12 | && php /tmp/composer-setup.php --install-dir=/tmp \ 13 | && mv /tmp/composer.phar /usr/bin/composer \ 14 | && chmod +x /usr/bin/composer \ 15 | && rm -rf /tmp/composer-setup.php 16 | fi -------------------------------------------------------------------------------- /repo/php73/changelog.md: -------------------------------------------------------------------------------- 1 | 2022-10-18 新增php73, 更新安装php扩展的安装脚本到最新。 -------------------------------------------------------------------------------- /repo/php73/compose.yml: -------------------------------------------------------------------------------- 1 | php73: 2 | build: 3 | context: ./env/php73 4 | args: 5 | PHP_VERSION: php:${PHP73_VERSION}-fpm-alpine 6 | CONTAINER_PACKAGE_URL: ${CONTAINER_PACKAGE_URL} 7 | PHP_EXTENSIONS: ${PHP73_EXTENSIONS} 8 | TZ: "$TZ" 9 | container_name: php73 10 | expose: 11 | - 9573 12 | volumes: 13 | - ${SOURCE_DIR}:/www/:rw 14 | - ${PHP73_PHP_CONF_FILE}:/usr/local/etc/php/php.ini:ro 15 | - ${PHP73_FPM_CONF_FILE}:/usr/local/etc/php-fpm.d/www.conf:rw 16 | - ${PHP73_LOG_DIR}:/var/log/php 17 | - ${DATA_DIR}/composer:/tmp/composer 18 | restart: always 19 | labels: 20 | "type": "php" 21 | cap_add: 22 | - SYS_PTRACE 23 | networks: 24 | - default -------------------------------------------------------------------------------- /repo/php73/env.sample: -------------------------------------------------------------------------------- 1 | # 2 | # PHP7 3 | # 4 | # Available PHP_EXTENSIONS: 5 | # 支持很多扩展,可以自行添加。建议查看xii.app 6 | # 7 | PHP73_VERSION=7.3.33 8 | PHP73_PHP_CONF_FILE=./env/php73/php.ini 9 | PHP73_FPM_CONF_FILE=./env/php73/php-fpm.conf 10 | PHP73_LOG_DIR=./logs/php73 11 | PHP73_EXTENSIONS=pdo_mysql,mysqli,mbstring,gd,curl,opcache -------------------------------------------------------------------------------- /repo/php74/build/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG PHP_VERSION 2 | FROM ${PHP_VERSION} 3 | 4 | ARG TZ 5 | ARG PHP_EXTENSIONS 6 | ARG CONTAINER_PACKAGE_URL 7 | 8 | 9 | RUN if [ $CONTAINER_PACKAGE_URL ] ; then sed -i "s/dl-cdn.alpinelinux.org/${CONTAINER_PACKAGE_URL}/g" /etc/apk/repositories ; fi 10 | 11 | 12 | COPY extensions /tmp/extensions 13 | WORKDIR /tmp/extensions 14 | RUN chmod +x install.sh \ 15 | && sh install.sh 16 | 17 | ADD extensions/install-php-extensions /usr/local/bin/ 18 | 19 | RUN chmod uga+x /usr/local/bin/install-php-extensions 20 | 21 | RUN apk --no-cache add tzdata \ 22 | && cp "/usr/share/zoneinfo/$TZ" /etc/localtime \ 23 | && echo "$TZ" > /etc/timezone 24 | 25 | 26 | # Fix: https://github.com/docker-library/php/issues/1121 27 | RUN apk add --no-cache --repository http://${CONTAINER_PACKAGE_URL}/alpine/v3.13/community/ gnu-libiconv=1.15-r3 28 | ENV LD_PRELOAD /usr/lib/preloadable_libiconv.so php 29 | 30 | 31 | # Install composer and change it's cache home 32 | RUN chmod +x install-composer.sh \ 33 | && sh install-composer.sh \ 34 | && rm -rf /tmp/extensions 35 | ENV COMPOSER_HOME=/tmp/composer 36 | 37 | # php image's www-data user uid & gid are 82, change them to 1000 (primary user) 38 | RUN apk --no-cache add shadow && usermod -u 1000 www-data && groupmod -g 1000 www-data 39 | 40 | 41 | WORKDIR /www 42 | -------------------------------------------------------------------------------- /repo/php74/build/extensions/amqp-1.10.2.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiiapp/xii/7d7c08c767774fb203b6289d901ee026c613510f/repo/php74/build/extensions/amqp-1.10.2.tgz -------------------------------------------------------------------------------- /repo/php74/build/extensions/apcu-5.1.17.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiiapp/xii/7d7c08c767774fb203b6289d901ee026c613510f/repo/php74/build/extensions/apcu-5.1.17.tgz -------------------------------------------------------------------------------- /repo/php74/build/extensions/event-2.5.6.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiiapp/xii/7d7c08c767774fb203b6289d901ee026c613510f/repo/php74/build/extensions/event-2.5.6.tgz -------------------------------------------------------------------------------- /repo/php74/build/extensions/install-composer.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # The latest mirror's composer version only support for PHP 7.2.5 4 | # And if your PHP version is lesser than that, will be download supported version. 5 | supportLatest=$(php -r "echo version_compare(PHP_VERSION, '7.2.5', '>');") 6 | 7 | if [ "$supportLatest" -eq "1" ]; then 8 | curl -o /usr/bin/composer https://mirrors.aliyun.com/composer/composer.phar \ 9 | && chmod +x /usr/bin/composer 10 | else 11 | curl -o /tmp/composer-setup.php https://getcomposer.org/installer \ 12 | && php /tmp/composer-setup.php --install-dir=/tmp \ 13 | && mv /tmp/composer.phar /usr/bin/composer \ 14 | && chmod +x /usr/bin/composer \ 15 | && rm -rf /tmp/composer-setup.php 16 | fi -------------------------------------------------------------------------------- /repo/php74/build/extensions/memcache-2.2.6.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiiapp/xii/7d7c08c767774fb203b6289d901ee026c613510f/repo/php74/build/extensions/memcache-2.2.6.tgz -------------------------------------------------------------------------------- /repo/php74/build/extensions/memcache-4.0.5.2.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiiapp/xii/7d7c08c767774fb203b6289d901ee026c613510f/repo/php74/build/extensions/memcache-4.0.5.2.tgz -------------------------------------------------------------------------------- /repo/php74/build/extensions/mongodb-1.7.4.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiiapp/xii/7d7c08c767774fb203b6289d901ee026c613510f/repo/php74/build/extensions/mongodb-1.7.4.tgz -------------------------------------------------------------------------------- /repo/php74/build/extensions/redis-5.2.2.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiiapp/xii/7d7c08c767774fb203b6289d901ee026c613510f/repo/php74/build/extensions/redis-5.2.2.tgz -------------------------------------------------------------------------------- /repo/php74/build/extensions/swoole-2.0.11.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiiapp/xii/7d7c08c767774fb203b6289d901ee026c613510f/repo/php74/build/extensions/swoole-2.0.11.tgz -------------------------------------------------------------------------------- /repo/php74/build/extensions/swoole-4.5.2.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiiapp/xii/7d7c08c767774fb203b6289d901ee026c613510f/repo/php74/build/extensions/swoole-4.5.2.tgz -------------------------------------------------------------------------------- /repo/php74/build/extensions/xdebug-2.5.5.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiiapp/xii/7d7c08c767774fb203b6289d901ee026c613510f/repo/php74/build/extensions/xdebug-2.5.5.tgz -------------------------------------------------------------------------------- /repo/php74/build/extensions/xdebug-2.6.1.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiiapp/xii/7d7c08c767774fb203b6289d901ee026c613510f/repo/php74/build/extensions/xdebug-2.6.1.tgz -------------------------------------------------------------------------------- /repo/php74/build/extensions/xdebug-2.9.2.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiiapp/xii/7d7c08c767774fb203b6289d901ee026c613510f/repo/php74/build/extensions/xdebug-2.9.2.tgz -------------------------------------------------------------------------------- /repo/php74/build/extensions/xhprof-2.2.0.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiiapp/xii/7d7c08c767774fb203b6289d901ee026c613510f/repo/php74/build/extensions/xhprof-2.2.0.tgz -------------------------------------------------------------------------------- /repo/php74/build/extensions/yaf-2.3.5.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiiapp/xii/7d7c08c767774fb203b6289d901ee026c613510f/repo/php74/build/extensions/yaf-2.3.5.tgz -------------------------------------------------------------------------------- /repo/php74/compose.yml: -------------------------------------------------------------------------------- 1 | php74: 2 | build: 3 | context: ./env/php74 4 | args: 5 | PHP_VERSION: php:${PHP74_VERSION}-fpm-alpine 6 | CONTAINER_PACKAGE_URL: ${CONTAINER_PACKAGE_URL} 7 | PHP_EXTENSIONS: ${PHP74_EXTENSIONS} 8 | TZ: "$TZ" 9 | container_name: php74 10 | expose: 11 | - 9574 12 | volumes: 13 | - ${SOURCE_DIR}:/www/:rw 14 | - ${PHP74_PHP_CONF_FILE}:/usr/local/etc/php/php.ini:ro 15 | - ${PHP74_FPM_CONF_FILE}:/usr/local/etc/php-fpm.d/www.conf:rw 16 | - ${PHP74_LOG_DIR}:/var/log/php 17 | - ${DATA_DIR}/composer:/tmp/composer 18 | restart: always 19 | labels: 20 | "type": "php" 21 | cap_add: 22 | - SYS_PTRACE 23 | networks: 24 | - default -------------------------------------------------------------------------------- /repo/php74/env.sample: -------------------------------------------------------------------------------- 1 | # 2 | # PHP7 3 | # 4 | # Available PHP_EXTENSIONS: 5 | # 支持很多扩展,可以自行添加。建议查看xii.app 6 | # 7 | PHP74_VERSION=7.4.27 8 | PHP74_PHP_CONF_FILE=./env/php74/php.ini 9 | PHP74_FPM_CONF_FILE=./env/php74/php-fpm.conf 10 | PHP74_LOG_DIR=./logs/php74 11 | PHP74_EXTENSIONS=pdo_mysql,mysqli,mbstring,gd,curl,opcache -------------------------------------------------------------------------------- /repo/php80/build/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG PHP_VERSION 2 | FROM ${PHP_VERSION} 3 | 4 | ARG TZ 5 | ARG PHP_EXTENSIONS 6 | ARG CONTAINER_PACKAGE_URL 7 | 8 | 9 | RUN if [ $CONTAINER_PACKAGE_URL ] ; then sed -i "s/dl-cdn.alpinelinux.org/${CONTAINER_PACKAGE_URL}/g" /etc/apk/repositories ; fi 10 | 11 | COPY extensions /tmp/extensions 12 | WORKDIR /tmp/extensions 13 | RUN chmod +x install.sh \ 14 | && sh install.sh \ 15 | && rm -rf /tmp/extensions 16 | 17 | ADD extensions/install-php-extensions /usr/local/bin/ 18 | 19 | RUN chmod uga+x /usr/local/bin/install-php-extensions 20 | 21 | RUN apk --no-cache add tzdata \ 22 | && cp "/usr/share/zoneinfo/$TZ" /etc/localtime \ 23 | && echo "$TZ" > /etc/timezone 24 | 25 | 26 | # Fix: https://github.com/docker-library/php/issues/240 27 | RUN apk add gnu-libiconv=1.15-r3 libstdc++ --no-cache --repository http://${CONTAINER_PACKAGE_URL}/alpine/edge/community/ --allow-untrusted 28 | ENV LD_PRELOAD /usr/lib/preloadable_libiconv.so php 29 | 30 | 31 | # Install composer and change it's cache home 32 | RUN curl -o /usr/bin/composer https://mirrors.aliyun.com/composer/composer.phar \ 33 | && chmod +x /usr/bin/composer 34 | ENV COMPOSER_HOME=/tmp/composer 35 | 36 | # php image's www-data user uid & gid are 82, change them to 1000 (primary user) 37 | RUN apk --no-cache add shadow && usermod -u 1000 www-data && groupmod -g 1000 www-data 38 | 39 | 40 | WORKDIR /www 41 | -------------------------------------------------------------------------------- /repo/php80/build/extensions/event-3.0.5.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiiapp/xii/7d7c08c767774fb203b6289d901ee026c613510f/repo/php80/build/extensions/event-3.0.5.tgz -------------------------------------------------------------------------------- /repo/php80/build/php-fpm-dnmp.conf: -------------------------------------------------------------------------------- 1 | [www] 2 | user = www-data 3 | group = www-data 4 | listen = 127.0.0.1:9000 5 | pm = dynamic 6 | pm.max_children = 10 7 | pm.start_servers = 2 8 | pm.min_spare_servers = 1 9 | slowlog = /var/log/php/fpm.slow.log 10 | request_slowlog_timeout = 3 11 | catch_workers_output = yes 12 | 13 | -------------------------------------------------------------------------------- /repo/php80/build/php-fpm.conf: -------------------------------------------------------------------------------- 1 | [global] 2 | error_log = /var/log/php/php-fpm.error.log 3 | log_level = notice 4 | 5 | [www] 6 | user = www-data 7 | group = www-data 8 | listen = 127.0.0.1:9000 9 | pm = dynamic 10 | pm.max_children = 580 11 | pm.start_servers = 80 12 | pm.min_spare_servers = 80 13 | pm.max_spare_servers = 580 14 | pm.max_requests = 10240 15 | pm.process_idle_timeout = 10s 16 | request_terminate_timeout = 100 17 | request_slowlog_timeout = 0 18 | slowlog = /var/log/php/fpm.slow.log 19 | ;catch_workers_output = yes 20 | 21 | -------------------------------------------------------------------------------- /repo/php80/compose.yml: -------------------------------------------------------------------------------- 1 | php80: 2 | build: 3 | context: ./env/php80 4 | args: 5 | PHP_VERSION: php:${PHP80_VERSION}-fpm-alpine3.13 6 | CONTAINER_PACKAGE_URL: ${CONTAINER_PACKAGE_URL} 7 | PHP_EXTENSIONS: ${PHP80_EXTENSIONS} 8 | TZ: "$TZ" 9 | container_name: php80 10 | expose: 11 | - 9580 12 | volumes: 13 | - ${SOURCE_DIR}:/www/:rw 14 | - ${PHP80_PHP_CONF_FILE}:/usr/local/etc/php/php.ini:ro 15 | - ${PHP80_FPM_CONF_FILE}:/usr/local/etc/php-fpm.d/www.conf:rw 16 | - ${PHP80_LOG_DIR}:/var/log/php 17 | - ${DATA_DIR}/composer:/tmp/composer 18 | restart: always 19 | labels: 20 | "type": "php" 21 | cap_add: 22 | - SYS_PTRACE 23 | networks: 24 | - default -------------------------------------------------------------------------------- /repo/php80/env.sample: -------------------------------------------------------------------------------- 1 | #php8的参数 2 | PHP80_VERSION=8.0.9 3 | PHP80_PHP_CONF_FILE=./env/php80/php.ini 4 | PHP80_FPM_CONF_FILE=./env/php80/php-fpm.conf 5 | PHP80_LOG_DIR=./logs/php80 6 | PHP80_EXTENSIONS=pdo_mysql,mysqli,mbstring,gd,curl,opcache,bcmath,exif,gettext,intl,redis,sockets,zip,xsl,imapmimageick,mongodb,event,xlswriter 7 | -------------------------------------------------------------------------------- /repo/php81/build/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG PHP_VERSION 2 | FROM ${PHP_VERSION} 3 | 4 | ARG TZ 5 | ARG PHP_EXTENSIONS 6 | ARG CONTAINER_PACKAGE_URL 7 | 8 | 9 | RUN if [ $CONTAINER_PACKAGE_URL ] ; then sed -i "s/dl-cdn.alpinelinux.org/${CONTAINER_PACKAGE_URL}/g" /etc/apk/repositories ; fi 10 | 11 | COPY extensions /tmp/extensions 12 | WORKDIR /tmp/extensions 13 | RUN chmod +x install.sh \ 14 | && sh install.sh \ 15 | && rm -rf /tmp/extensions 16 | 17 | ADD extensions/install-php-extensions /usr/local/bin/ 18 | 19 | RUN chmod uga+x /usr/local/bin/install-php-extensions 20 | 21 | RUN apk --no-cache add tzdata \ 22 | && cp "/usr/share/zoneinfo/$TZ" /etc/localtime \ 23 | && echo "$TZ" > /etc/timezone 24 | 25 | 26 | # Fix: https://github.com/docker-library/php/issues/240 27 | RUN apk add gnu-libiconv=1.16-r0 libstdc++ --update-cache --repository http://${CONTAINER_PACKAGE_URL}/alpine/v3.16/community/ --allow-untrusted 28 | 29 | 30 | 31 | ENV LD_PRELOAD /usr/lib/preloadable_libiconv.so php 32 | 33 | 34 | # Install composer and change it's cache home 35 | RUN curl -o /usr/bin/composer https://mirrors.aliyun.com/composer/composer.phar \ 36 | && chmod +x /usr/bin/composer 37 | ENV COMPOSER_HOME=/tmp/composer 38 | 39 | # php image's www-data user uid & gid are 82, change them to 1000 (primary user) 40 | RUN apk --no-cache add shadow && usermod -u 1000 www-data && groupmod -g 1000 www-data 41 | 42 | 43 | WORKDIR /www 44 | -------------------------------------------------------------------------------- /repo/php81/build/php-fpm.conf: -------------------------------------------------------------------------------- 1 | [global] 2 | error_log = /var/log/php/php-fpm.error.log 3 | log_level = notice 4 | 5 | [www] 6 | user = www-data 7 | group = www-data 8 | listen = 127.0.0.1:9000 9 | pm = dynamic 10 | pm.max_children = 580 11 | pm.start_servers = 80 12 | pm.min_spare_servers = 80 13 | pm.max_spare_servers = 580 14 | pm.max_requests = 10240 15 | pm.process_idle_timeout = 10s 16 | request_terminate_timeout = 100 17 | request_slowlog_timeout = 0 18 | slowlog = /var/log/php/fpm.slow.log 19 | ;catch_workers_output = yes 20 | 21 | -------------------------------------------------------------------------------- /repo/php81/compose.yml: -------------------------------------------------------------------------------- 1 | php81: 2 | build: 3 | context: ./env/php81 4 | args: 5 | PHP_VERSION: php:${PHP81_VERSION}-fpm-alpine3.16 6 | CONTAINER_PACKAGE_URL: ${CONTAINER_PACKAGE_URL} 7 | PHP_EXTENSIONS: ${PHP81_EXTENSIONS} 8 | TZ: "$TZ" 9 | container_name: php81 10 | expose: 11 | - 9581 12 | volumes: 13 | - ${SOURCE_DIR}:/www/:rw 14 | - ${PHP81_PHP_CONF_FILE}:/usr/local/etc/php/php.ini:ro 15 | - ${PHP81_FPM_CONF_FILE}:/usr/local/etc/php-fpm.d/www.conf:rw 16 | - ${PHP81_LOG_DIR}:/var/log/php 17 | - ${DATA_DIR}/composer:/tmp/composer 18 | restart: always 19 | labels: 20 | "type": "php" 21 | cap_add: 22 | - SYS_PTRACE 23 | networks: 24 | - default -------------------------------------------------------------------------------- /repo/php81/env.sample: -------------------------------------------------------------------------------- 1 | #php8的参数 2 | PHP81_VERSION=8.1 3 | PHP81_PHP_CONF_FILE=./env/php81/php.ini 4 | PHP81_FPM_CONF_FILE=./env/php81/php-fpm.conf 5 | PHP81_LOG_DIR=./logs/php81 6 | PHP81_EXTENSIONS=pdo_mysql,mysqli,mbstring,gd,curl,opcache,bcmath,exif,gettext,intl,redis,sockets,zip,xsl,imapmimageick,mongodb,event,xlswriter 7 | -------------------------------------------------------------------------------- /repo/php82/build/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG PHP_VERSION 2 | FROM ${PHP_VERSION} 3 | 4 | ARG TZ 5 | ARG PHP_EXTENSIONS 6 | ARG CONTAINER_PACKAGE_URL 7 | 8 | 9 | RUN if [ $CONTAINER_PACKAGE_URL ] ; then sed -i "s/dl-cdn.alpinelinux.org/${CONTAINER_PACKAGE_URL}/g" /etc/apk/repositories ; fi 10 | 11 | COPY extensions /tmp/extensions 12 | WORKDIR /tmp/extensions 13 | RUN chmod +x install.sh \ 14 | && sh install.sh \ 15 | && rm -rf /tmp/extensions 16 | 17 | ADD extensions/install-php-extensions /usr/local/bin/ 18 | 19 | RUN chmod uga+x /usr/local/bin/install-php-extensions 20 | 21 | RUN apk --no-cache add tzdata \ 22 | && cp "/usr/share/zoneinfo/$TZ" /etc/localtime \ 23 | && echo "$TZ" > /etc/timezone 24 | 25 | 26 | # Fix: https://github.com/docker-library/php/issues/240 27 | RUN apk add gnu-libiconv=1.16-r0 libstdc++ --update-cache --repository http://${CONTAINER_PACKAGE_URL}/alpine/v3.16/community/ --allow-untrusted 28 | 29 | 30 | 31 | ENV LD_PRELOAD /usr/lib/preloadable_libiconv.so php 32 | 33 | 34 | # Install composer and change it's cache home 35 | RUN curl -o /usr/bin/composer https://mirrors.aliyun.com/composer/composer.phar \ 36 | && chmod +x /usr/bin/composer 37 | ENV COMPOSER_HOME=/tmp/composer 38 | 39 | # php image's www-data user uid & gid are 82, change them to 1000 (primary user) 40 | RUN apk --no-cache add shadow && usermod -u 1000 www-data && groupmod -g 1000 www-data 41 | 42 | 43 | WORKDIR /www 44 | -------------------------------------------------------------------------------- /repo/php82/build/php-fpm.conf: -------------------------------------------------------------------------------- 1 | [global] 2 | error_log = /var/log/php/php-fpm.error.log 3 | log_level = notice 4 | 5 | [www] 6 | user = www-data 7 | group = www-data 8 | listen = 127.0.0.1:9000 9 | pm = dynamic 10 | pm.max_children = 580 11 | pm.start_servers = 80 12 | pm.min_spare_servers = 80 13 | pm.max_spare_servers = 580 14 | pm.max_requests = 10240 15 | pm.process_idle_timeout = 10s 16 | request_terminate_timeout = 100 17 | request_slowlog_timeout = 0 18 | slowlog = /var/log/php/fpm.slow.log 19 | ;catch_workers_output = yes 20 | 21 | -------------------------------------------------------------------------------- /repo/php82/compose.yml: -------------------------------------------------------------------------------- 1 | php82: 2 | build: 3 | context: ./env/php82 4 | args: 5 | PHP_VERSION: php:${PHP82_VERSION}-fpm-alpine3.16 6 | CONTAINER_PACKAGE_URL: ${CONTAINER_PACKAGE_URL} 7 | PHP_EXTENSIONS: ${PHP82_EXTENSIONS} 8 | TZ: "$TZ" 9 | container_name: php82 10 | expose: 11 | - 9582 12 | volumes: 13 | - ${SOURCE_DIR}:/www/:rw 14 | - ${PHP82_PHP_CONF_FILE}:/usr/local/etc/php/php.ini:ro 15 | - ${PHP82_FPM_CONF_FILE}:/usr/local/etc/php-fpm.d/www.conf:rw 16 | - ${PHP82_LOG_DIR}:/var/log/php 17 | - ${DATA_DIR}/composer:/tmp/composer 18 | restart: always 19 | labels: 20 | "type": "php" 21 | cap_add: 22 | - SYS_PTRACE 23 | networks: 24 | - default -------------------------------------------------------------------------------- /repo/php82/env.sample: -------------------------------------------------------------------------------- 1 | #php8的参数 2 | PHP82_VERSION=8.2.0RC4 3 | PHP82_PHP_CONF_FILE=./env/php82/php.ini 4 | PHP82_FPM_CONF_FILE=./env/php82/php-fpm.conf 5 | PHP82_LOG_DIR=./logs/php82 6 | PHP82_EXTENSIONS=pdo_mysql,mysqli,mbstring,gd,curl,opcache,bcmath,exif,gettext,intl,redis,sockets,zip,xsl,imapmimageick,mongodb,event,xlswriter 7 | -------------------------------------------------------------------------------- /repo/phpmyadmin/build/config.user.inc.php: -------------------------------------------------------------------------------- 1 | /etc/timezone \ 15 | && rm -rf /var/cache/apk/* 16 | 17 | 18 | WORKDIR /www -------------------------------------------------------------------------------- /repo/supervisor/build/conf.d/php-fpm.ini: -------------------------------------------------------------------------------- 1 | [program:php] 2 | command=php -m 3 | ;directory=/www/localhost/ 4 | priority=999 ; the relative start priority (default 999) 5 | autostart=true ; start at supervisord start (default: true) 6 | autorestart=true ; retstart at unexpected quit (default: true) 7 | startsecs=10 ; number of secs prog must stay running (def. 10) 8 | startretries=3 ; max # of serial start failures (default 3) 9 | exitcodes=0,2 ; 'expected' exit codes for process (default 0,2) 10 | stopsignal=QUIT ; signal used to kill process (default TERM) 11 | stopwaitsecs=10 ; max num secs to wait before SIGKILL (default 10) 12 | user=root ; setuid to this UNIX account to run the program 13 | log_stdout=true 14 | log_stderr=true ; if true, log program stderr (def false) 15 | logfile=/var/log/supervisor/php.log 16 | logfile_maxbytes=1MB ; max # logfile bytes b4 rotation (default 50MB) 17 | logfile_backups=10 ; # of logfile backups (default 10) 18 | stdout_logfile_maxbytes=20MB ; stdout 日志文件大小,默认 50MB 19 | stdout_logfile_backups=20 ; stdout 日志文件备份数 20 | stdout_logfile=/var/log/supervisor/php.stdout.log 21 | -------------------------------------------------------------------------------- /repo/supervisor/build/supervisord.conf: -------------------------------------------------------------------------------- 1 | [unix_http_server] 2 | file=/run/supervisord.sock ; (the path to the socket file) 3 | ;chmod=0700 ; socked file mode (default 0700) 4 | ;chown=nobody:nogroup ; socket file uid:gid owner 5 | ;username=user ; (default is no username (open server)) 6 | ;password=123 ; (default is no password (open server)) 7 | 8 | [inet_http_server] ; inet (TCP) server disabled by default 9 | port=0.0.0.0:9001 ; (ip_address:port specifier, *:port for all iface) 10 | username=user ; (default is no username (open server)) 11 | password=123 ; (default is no password (open server)) 12 | 13 | [supervisord] 14 | logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log) 15 | ;logfile_maxbytes=50MB ; (max main logfile bytes b4 rotation;default 50MB) 16 | ;logfile_backups=10 ; (num of main logfile rotation backups;default 10) 17 | loglevel=error ; (log level;default info; others: debug,warn,trace) 18 | pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid) 19 | nodaemon=true ; (start in foreground if true;default false) 20 | ;minfds=1024 ; (min. avail startup file descriptors;default 1024) 21 | ;minprocs=200 ; (min. avail process descriptors;default 200) 22 | ;umask=022 ; (process file creation umask;default 022) 23 | user=root ; (default is current user, required if root) 24 | ;identifier=supervisor ; (supervisord identifier, default is 'supervisor') 25 | ;directory=/tmp ; (default is not to cd during start) 26 | ;nocleanup=true ; (don't clean up tempfiles at start;default false) 27 | ;childlogdir=/var/log/supervisor ; ('AUTO' child log dir, default $TEMP) 28 | ;environment=KEY=value ; (key value pairs to add to environment) 29 | ;strip_ansi=false ; (strip ansi escape codes in logs; def. false) 30 | 31 | ; the below section must remain in the config file for RPC 32 | ; (supervisorctl/web interface) to work, additional interfaces may be 33 | ; added by defining them in separate rpcinterface: sections 34 | [rpcinterface:supervisor] 35 | supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface 36 | 37 | [supervisorctl] 38 | serverurl=unix:///run/supervisord.sock ; use a unix:// URL for a unix socket 39 | ;serverurl=http://127.0.0.1:9001 ; use an http:// url to specify an inet socket 40 | ;username=chris ; should be same as http_username if set 41 | ;password=123 ; should be same as http_password if set 42 | ;prompt=mysupervisor ; cmd line prompt (default "supervisor") 43 | ;history_file=~/.sc_history ; use readline history if available 44 | 45 | ; The below sample program section shows all possible program subsection values, 46 | ; create one or more 'real' program: sections to be able to control them under 47 | ; supervisor. 48 | 49 | ;[program:theprogramname] 50 | ;command=/bin/cat ; the program (relative uses PATH, can take args) 51 | ;process_name=%(program_name)s ; process_name expr (default %(program_name)s) 52 | ;numprocs=1 ; number of processes copies to start (def 1) 53 | ;directory=/tmp ; directory to cwd to before exec (def no cwd) 54 | ;umask=022 ; umask for process (default None) 55 | ;priority=999 ; the relative start priority (default 999) 56 | ;autostart=true ; start at supervisord start (default: true) 57 | ;autorestart=unexpected ; whether/when to restart (default: unexpected) 58 | ;startsecs=1 ; number of secs prog must stay running (def. 1) 59 | ;startretries=3 ; max # of serial start failures (default 3) 60 | ;exitcodes=0,2 ; 'expected' exit codes for process (default 0,2) 61 | ;stopsignal=QUIT ; signal used to kill process (default TERM) 62 | ;stopwaitsecs=10 ; max num secs to wait b4 SIGKILL (default 10) 63 | ;killasgroup=false ; SIGKILL the UNIX process group (def false) 64 | ;user=chrism ; setuid to this UNIX account to run the program 65 | ;redirect_stderr=true ; redirect proc stderr to stdout (default false) 66 | ;stdout_logfile=/a/path ; stdout log path, NONE for none; default AUTO 67 | ;stdout_logfile_maxbytes=1MB ; max # logfile bytes b4 rotation (default 50MB) 68 | ;stdout_logfile_backups=10 ; # of stdout logfile backups (default 10) 69 | ;stdout_capture_maxbytes=1MB ; number of bytes in 'capturemode' (default 0) 70 | ;stdout_events_enabled=false ; emit events on stdout writes (default false) 71 | ;stderr_logfile=/a/path ; stderr log path, NONE for none; default AUTO 72 | ;stderr_logfile_maxbytes=1MB ; max # logfile bytes b4 rotation (default 50MB) 73 | ;stderr_logfile_backups=10 ; # of stderr logfile backups (default 10) 74 | ;stderr_capture_maxbytes=1MB ; number of bytes in 'capturemode' (default 0) 75 | ;stderr_events_enabled=false ; emit events on stderr writes (default false) 76 | ;environment=A=1,B=2 ; process environment additions (def no adds) 77 | ;serverurl=AUTO ; override serverurl computation (childutils) 78 | 79 | ; The below sample eventlistener section shows all possible 80 | ; eventlistener subsection values, create one or more 'real' 81 | ; eventlistener: sections to be able to handle event notifications 82 | ; sent by supervisor. 83 | 84 | ;[eventlistener:theeventlistenername] 85 | ;command=/bin/eventlistener ; the program (relative uses PATH, can take args) 86 | ;process_name=%(program_name)s ; process_name expr (default %(program_name)s) 87 | ;numprocs=1 ; number of processes copies to start (def 1) 88 | ;events=EVENT ; event notif. types to subscribe to (req'd) 89 | ;buffer_size=10 ; event buffer queue size (default 10) 90 | ;directory=/tmp ; directory to cwd to before exec (def no cwd) 91 | ;umask=022 ; umask for process (default None) 92 | ;priority=-1 ; the relative start priority (default -1) 93 | ;autostart=true ; start at supervisord start (default: true) 94 | ;autorestart=unexpected ; whether/when to restart (default: unexpected) 95 | ;startsecs=1 ; number of secs prog must stay running (def. 1) 96 | ;startretries=3 ; max # of serial start failures (default 3) 97 | ;exitcodes=0,2 ; 'expected' exit codes for process (default 0,2) 98 | ;stopsignal=QUIT ; signal used to kill process (default TERM) 99 | ;stopwaitsecs=10 ; max num secs to wait b4 SIGKILL (default 10) 100 | ;killasgroup=false ; SIGKILL the UNIX process group (def false) 101 | ;user=chrism ; setuid to this UNIX account to run the program 102 | ;redirect_stderr=true ; redirect proc stderr to stdout (default false) 103 | ;stdout_logfile=/a/path ; stdout log path, NONE for none; default AUTO 104 | ;stdout_logfile_maxbytes=1MB ; max # logfile bytes b4 rotation (default 50MB) 105 | ;stdout_logfile_backups=10 ; # of stdout logfile backups (default 10) 106 | ;stdout_events_enabled=false ; emit events on stdout writes (default false) 107 | ;stderr_logfile=/a/path ; stderr log path, NONE for none; default AUTO 108 | ;stderr_logfile_maxbytes=1MB ; max # logfile bytes b4 rotation (default 50MB) 109 | ;stderr_logfile_backups ; # of stderr logfile backups (default 10) 110 | ;stderr_events_enabled=false ; emit events on stderr writes (default false) 111 | ;environment=A=1,B=2 ; process environment additions 112 | ;serverurl=AUTO ; override serverurl computation (childutils) 113 | 114 | ; The below sample group section shows all possible group values, 115 | ; create one or more 'real' group: sections to create "heterogeneous" 116 | ; process groups. 117 | 118 | ;[group:thegroupname] 119 | ;programs=progname1,progname2 ; each refers to 'x' in [program:x] definitions 120 | ;priority=999 ; the relative start priority (default 999) 121 | 122 | ; The [include] section can just contain the "files" setting. This 123 | ; setting can list multiple files (separated by whitespace or 124 | ; newlines). It can also contain wildcards. The filenames are 125 | ; interpreted as relative to this file. Included files *cannot* 126 | ; include files themselves. 127 | 128 | [include] 129 | files = /etc/supervisor/conf.d/*.ini 130 | -------------------------------------------------------------------------------- /repo/supervisor/compose.yml: -------------------------------------------------------------------------------- 1 | supervisor: 2 | build: 3 | context: ./env/supervisor 4 | args: 5 | ALPINE_VERSION: alpine:${ALPINE_VERSION} 6 | TZ: "$TZ" 7 | CONTAINER_PACKAGE_URL: ${CONTAINER_PACKAGE_URL} 8 | container_name: supervisor 9 | ports: 10 | - "${SUPERVISOR_HOST_PORT_C}:9001" 11 | volumes: 12 | - ${SOURCE_DIR}:/www/:rw 13 | - ${SUPERVISOR_LOG}:/var/log/supervisor/:rw 14 | - ${SUPERVISOR_CONFIG}:/etc/supervisor/conf.d/:rw 15 | - ${SUPERVISOR_CONF_FILE}:/etc/supervisor/supervisord.conf:ro 16 | command: 17 | - /bin/sh 18 | - -c 19 | - | 20 | supervisord -n -c /etc/supervisor/supervisord.conf 21 | restart: always 22 | labels: 23 | "type": "supervisor" 24 | cap_add: 25 | - SYS_PTRACE 26 | networks: 27 | - default -------------------------------------------------------------------------------- /repo/supervisor/env.sample: -------------------------------------------------------------------------------- 1 | # 2 | # SUPERVISOR 3 | # 目前作用只是用来监控php-fpm,其他的需要自己编写 4 | # 5 | SUPERVISOR_CONFIG=./env/supervisor/conf.d/ 6 | SUPERVISOR_LOG=./logs/supervisor 7 | SUPERVISOR_CONF_FILE=./env/supervisor/supervisord.conf 8 | SUPERVISOR_HOST_PORT_C=9001 9 | -------------------------------------------------------------------------------- /script/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | red() { 4 | echo -e "\033[31m\033[01m$1\033[0m" 5 | } 6 | 7 | green() { 8 | echo -e "\033[32m\033[01m$1\033[0m" 9 | } 10 | 11 | Linfo(){ 12 | green "Checking System..." 13 | CPU=$(uname -a) 14 | if [[ "$CPU" =~ "aarch64" ]]; then 15 | S=_arm64 16 | url=https://github.com/xiiapp/xii/raw/main/release/xii_linux_arm64.zip 17 | elif [[ "$CPU" =~ "arm" ]]; then 18 | S=_arm 19 | url=https://github.com/xiiapp/xii/raw/main/release/xii_linux_arm.zip 20 | elif [[ "$CPU" =~ "x86_64" ]]; then 21 | S= 22 | url=https://github.com/xiiapp/xii/raw/main/release/xii_linux.zip 23 | else 24 | red "脚本不支持此服务器架构,请尝试手动安装" 25 | exit 1 26 | fi 27 | } 28 | 29 | Minfo(){ 30 | CPU=$(uname -a) 31 | if [[ "$CPU" =~ "arm64" ]]; then 32 | S=_arm 33 | url=https://github.com/xiiapp/xii/raw/main/release/xii_mac_arm.zip 34 | elif [[ "$CPU" =~ "x86_64" ]]; then 35 | S= 36 | url=https://github.com/xiiapp/xii/raw/main/release/xii_mac.zip 37 | fi 38 | } 39 | 40 | cncheck(){ 41 | green "Checking Internet" 42 | ipcheck=$(curl -s "ipinfo.io") 43 | cn=$(echo $ipcheck | grep "CN" ) 44 | if [ -n "$cn" ];then 45 | echo "当前为大陆环境,使用镜像源安装" 46 | durl="get.daocloud.io/docker" 47 | curl="dn-dao-github-mirror.daocloud.io" 48 | else 49 | durl="get.docker.com" 50 | curl="github.com" 51 | Location="world" 52 | fi 53 | } 54 | 55 | docker(){ 56 | green "Checking docker" 57 | docker=$(command -v docker) 58 | compose=$(command -v docker-compose) 59 | # [[ -z $(docker -v 2>/dev/null) ]] && docker="False" 60 | # [[ -n $(docker -v 2>/dev/null) ]] && green "docker:Installed" 61 | # [[ -z $(docker-compose -v 2>/dev/null) ]] && docker-compose="False" 62 | # [[ -n $(docker-compose -v 2>/dev/null) ]] && green "docker-compose:Installed" 63 | if [[ -z "$docker" ]]; then 64 | green "Start installing docker" 65 | curl -sSL $durl | sh 66 | systemctl enable docker 67 | systemctl start docker 68 | groupadd docker 69 | if [ "root" != "$USER" ]; then 70 | usermod -aG docker $USER 71 | fi 72 | fi 73 | if [[ -z "$compose" ]]; then 74 | curl -L "${curl}/docker/compose/releases/download/v2.12.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose 75 | chmod +x /usr/local/bin/docker-compose 76 | fi 77 | } 78 | 79 | depend(){ 80 | green "Checking depend" 81 | depends=("curl" "wget" "unzip" "sudo") 82 | depend="" 83 | for i in "${!depends[@]}"; do 84 | now_depend="${depends[$i]}" 85 | if [ ! -x "$(command -v $now_depend 2>/dev/null)" ]; then 86 | echo "$now_depend 未安装" 87 | depend="$now_depend $depend" 88 | fi 89 | done 90 | if [ "$depend" ]; then 91 | if [ -x "$(command -v apk 2>/dev/null)" ]; then 92 | echo "apk包管理器,正在尝试安装依赖:$depend" 93 | apk --no-cache add $depend $proxy >>/dev/null 2>&1 94 | elif [ -x "$(command -v apt-get 2>/dev/null)" ]; then 95 | echo "apt-get包管理器,正在尝试安装依赖:$depend" 96 | apt -y install $depend >>/dev/null 2>&1 97 | elif [ -x "$(command -v yum 2>/dev/null)" ]; then 98 | echo "yum包管理器,正在尝试安装依赖:$depend" 99 | yum -y install $depend >>/dev/null 2>&1 100 | else 101 | red "未找到合适的包管理工具,请手动安装:$depend" 102 | exit 1 103 | fi 104 | for i in "${!depends[@]}"; do 105 | now_depend="${depends[$i]}" 106 | if [ ! -x "$(command -v $now_depend)" ]; then 107 | red "$now_depend 未成功安装,请尝试手动安装!" 108 | exit 1 109 | fi 110 | done 111 | fi 112 | } 113 | 114 | Minstall(){ 115 | green "MacOS:Start installing xii" 116 | cd ~ 117 | 118 | if [ -d "xii" ] ; then 119 | mv xii xii.bakup.$RANDOM 120 | fi 121 | 122 | mkdir xii 123 | cd xii 124 | echo "$url" 125 | wget -c "$url" -O xii.zip 126 | unzip xii.zip -d ./ 127 | mv -f ~/xii/mac"$S"/* ./ 128 | rm -rf ~/xii/release 129 | rm -f ~/xii/xii.zip 130 | if [ "$Location" == "world" ] ; then 131 | sed -i "" 's/CONTAINER_PACKAGE_URL=mirrors.ustc.edu.cn/CONTAINER_PACKAGE_URL=dl-cdn.alpinelinux.org/g' ~/xii/repo/base/env.sample 132 | fi 133 | chmod +x ~/xii/xii 134 | echo "创建软链接需要输入密码授权" 135 | sudo ln -s ~/xii/xii /usr/local/bin/xii 136 | sudo ln -s ~/xii/xii /usr/local/bin/xxi 137 | } 138 | 139 | Linstall(){ 140 | green "Linux:Start installing xii" 141 | cd /home 142 | 143 | if [ -d "xii" ] ; then 144 | mv xii xii.bakup.$RANDOM 145 | fi 146 | mkdir xii 147 | cd xii 148 | wget -c "$url" -O xii.zip 149 | unzip xii.zip -d ./ 150 | mv -f /home/xii/linux"$S"/* ./ 151 | rm -rf /home/xii/release 152 | rm -f /home/xii/xii.zip 153 | if [ "$Location" == "world" ] ; then 154 | sed -i 's/CONTAINER_PACKAGE_URL=mirrors.ustc.edu.cn/CONTAINER_PACKAGE_URL=dl-cdn.alpinelinux.org/g' /home/xii/repo/base/env.sample 155 | fi 156 | chmod +x /home/xii/xii 157 | ln -s /home/xii/xii /usr/local/bin/xii 158 | ln -s /home/xii/xii /usr/local/bin/xxi 159 | } 160 | 161 | sys=$(uname -a) 162 | if [[ "$sys" =~ "Linux" ]]; then 163 | green "System:Linux" 164 | Linfo 165 | depend 166 | cncheck 167 | docker 168 | Linstall 169 | fi 170 | if [[ "$sys" =~ "Darwin" ]]; then 171 | green "System:MacOS" 172 | Minfo 173 | depend 174 | cncheck 175 | docker 176 | Minstall 177 | fi 178 | 179 | echo " " 180 | echo " " 181 | echo " " 182 | echo -e "\033[33m ---Success---\033[0m" 183 | echo -e "\033[33mXII is installed successfully.\033[0m" 184 | if [ "$(uname)" == "Darwin" ] ; then 185 | echo -e "\033[33m Your app location is ~/xii \033[0m" 186 | else 187 | echo -e " Your app location is /home/xii " 188 | 189 | fi 190 | echo -e "\033[33mPlease visit https://xii.app for detail information before use.\033[0m" 191 | echo " " 192 | echo " " 193 | echo " " 194 | echo " " 195 | -------------------------------------------------------------------------------- /script/make.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 编译xii助手 4 | cd ../assistant 5 | gf build -n xii_mac -a amd64,arm64 -s darwin 6 | gf build -n xii_linux -a amd64,arm,arm64 -s linux 7 | 8 | # 迁移xii助手 9 | cd ../ 10 | rm -rf ./release 11 | 12 | mkdir ./release 13 | mkdir ./release/mac 14 | mkdir ./release/mac_arm 15 | mkdir ./release/linux 16 | mkdir ./release/linux_arm 17 | mkdir ./release/linux_arm64 18 | 19 | mv ./assistant/temp/darwin_amd64/xii_mac ./release/mac/xii 20 | mv ./assistant/temp/darwin_arm64/xii_mac ./release/mac_arm/xii 21 | mv ./assistant/temp/linux_amd64/xii_linux ./release/linux/xii 22 | mv ./assistant/temp/linux_arm64/xii_linux ./release/linux_arm64/xii 23 | mv ./assistant/temp/linux_arm/xii_linux ./release/linux_arm/xii 24 | 25 | # 创建目录 26 | mkdir ./release/mac/data 27 | mkdir ./release/mac_arm/data 28 | mkdir ./release/linux_arm64/data 29 | mkdir ./release/linux_arm/data 30 | mkdir ./release/linux/data 31 | 32 | 33 | mkdir ./release/mac/www 34 | mkdir ./release/mac_arm/www 35 | mkdir ./release/linux_arm64/www 36 | mkdir ./release/linux_arm/www 37 | mkdir ./release/linux/www 38 | 39 | 40 | mkdir ./release/mac/logs 41 | mkdir ./release/mac_arm/logs 42 | mkdir ./release/linux_arm64/logs 43 | mkdir ./release/linux_arm/logs 44 | mkdir ./release/linux/logs 45 | 46 | 47 | mkdir ./release/mac/env 48 | mkdir ./release/mac_arm/env 49 | mkdir ./release/linux_arm64/env 50 | mkdir ./release/linux_arm/env 51 | mkdir ./release/linux/env 52 | 53 | 54 | # 复制文件 55 | cp -r ./repo ./release/mac/repo 56 | cp -r ./repo ./release/mac_arm/repo 57 | cp -r ./repo ./release/linux_arm64/repo 58 | cp -r ./repo ./release/linux_arm/repo 59 | cp -r ./repo ./release/linux/repo 60 | 61 | 62 | cp -r ./script/manual.sh ./release/mac/manual.sh 63 | cp -r ./script/manual.sh ./release/mac_arm/manual.sh 64 | cp -r ./script/manual.sh ./release/linux_arm64/manual.sh 65 | cp -r ./script/manual.sh ./release/linux_arm/manual.sh 66 | cp -r ./script/manual.sh ./release/linux/manual.sh 67 | 68 | # 打包 69 | cd ./release 70 | zip -r xii_mac.zip ./mac 71 | zip -r xii_mac_arm.zip ./mac_arm 72 | zip -r xii_linux_arm64.zip ./linux_arm64 73 | zip -r xii_linux_arm.zip ./linux_arm 74 | zip -r xii_linux.zip ./linux 75 | 76 | 77 | # 清理 78 | rm -rf ./mac 79 | rm -rf ./mac_arm 80 | rm -rf ./linux_arm64 81 | rm -rf ./linux_arm 82 | rm -rf ./linux 83 | 84 | -------------------------------------------------------------------------------- /script/manual.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo " 手动安装:将xii_mac.zip或xii_linux.zip压缩包跟本脚本放在一起,然后执行本脚本将自动安装" 4 | 5 | # Create Floder 6 | if [ "$(uname)" == "Darwin" ] ; then 7 | mv xii_m*.zip ~/xii.zip 8 | cd ~ 9 | 10 | if [ -d "xii" ] ; then 11 | mv xii xii.bakup.$RANDOM 12 | fi 13 | 14 | mkdir xii 15 | cd xii 16 | unzip xii.zip -d ./ 17 | mv -f ~/xii/ma*/* ./ 18 | rm -rf ~/xii/release 19 | rm -f ~/xii/xii.zip 20 | cp -f ~/xii/env.config ~/xii/.env 21 | chmod +x ~/xii/xii 22 | echo "创建软链接需要输入密码授权" 23 | sudo ln -s ~/xii/xii /usr/local/bin/xii 24 | sudo ln -s ~/xii/xii /usr/local/bin/xxi 25 | 26 | else 27 | mv xii_l*.zip /home/xii.zip 28 | cd /home 29 | if [ -d "xii" ] ; then 30 | mv xii xii.bakup.$RANDOM 31 | fi 32 | mkdir xii 33 | mv xii.zip xii/ 34 | cd xii 35 | unzip xii.zip -d ./ 36 | mv -f /home/xii/linux/* ./ 37 | rm -rf /home/xii/release 38 | rm -f /home/xii/xii.zip 39 | cp -f /home/xii/env.config /home/xii/.env 40 | chmod +x /home/xii/xii 41 | ln -s /home/xii/xii /usr/local/bin/xii 42 | ln -s /home/xii/xii /usr/local/bin/xxi 43 | fi 44 | 45 | 46 | 47 | 48 | echo " " 49 | echo " " 50 | echo " " 51 | echo -e " ---Success---" 52 | echo -e "XII is installed successfully." 53 | if [ "$(uname)" == "Darwin" ] ; then 54 | echo -e " Your app location is ~/xii " 55 | else 56 | echo -e " Your app location is /home/xii " 57 | 58 | fi 59 | echo -e "Please visit https://xii.app for detail information before use." 60 | echo " " 61 | echo " " 62 | echo " " 63 | echo " " 64 | 65 | # export PATH=$PATH:/home/xii/assistant or ln -s /home/xii/assistant/xii /usr/bin/xii -------------------------------------------------------------------------------- /script/uninstall.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | 4 | 5 | 6 | if [ "$(uname)" == "Darwin" ] ; then 7 | echo "Enter your password to uninstall " 8 | rm -rf ~/xii 9 | sudo rm -f /usr/local/bin/xii 10 | sudo rm -f /usr/local/bin/xxi 11 | else 12 | rm -rf /home/xii 13 | rm -f /usr/local/bin/xii 14 | rm -f /usr/local/bin/xxi 15 | fi 16 | 17 | 18 | 19 | echo "Uninstall success" -------------------------------------------------------------------------------- /script_dev/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Location variables 4 | Location="world" 5 | if [ "$1" == "china" ] ; then 6 | Location=$1 7 | #elif [ "$2" == "china" ] ; then 8 | # Location=$1 9 | fi 10 | 11 | 12 | # Install wget & curl 13 | if command -v wget >/dev/null 2>&1; then 14 | echo 'wget already installed.Exit' 15 | else 16 | yum install -y wget 17 | apt-get install -y wget 18 | apk add wget 19 | fi 20 | 21 | if command -v curl >/dev/null 2>&1; then 22 | echo 'curl already installed.Exit' 23 | else 24 | yum install -y curl 25 | apt-get install -y curl 26 | apk add curl 27 | fi 28 | 29 | if command -v unzip >/dev/null 2>&1; then 30 | echo 'unzip already installed.Exit' 31 | else 32 | yum install -y unzip 33 | apt-get install -y unzip 34 | apk add unzip 35 | fi 36 | 37 | 38 | 39 | # Install docker 40 | if command -v docker >/dev/null 2>&1; then 41 | echo 'Docker already installed.Exit' 42 | else 43 | curl -fsSL get.docker.com -o get-docker.sh 44 | sh get-docker.sh --mirror Aliyun 45 | systemctl enable docker 46 | systemctl start docker 47 | groupadd docker 48 | if [ "root" != "$USER" ]; then 49 | usermod -aG docker $USER 50 | fi 51 | fi 52 | 53 | 54 | # Install the docker-compose 55 | if command -v docker-compose >/dev/null 2>&1; then 56 | echo 'docker-compose already installed.' 57 | else 58 | if [ "$Location" == "china" ] ; then 59 | curl -L https://get.daocloud.io/docker/compose/releases/download/v2.11.2/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose 60 | else 61 | curl -L "https://github.com/docker/compose/releases/download/v2.11.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose 62 | fi 63 | chmod +x /usr/local/bin/docker-compose 64 | ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose 65 | fi 66 | 67 | 68 | 69 | # Create Floder 70 | if [ "$(uname)" == "Darwin" ] ; then 71 | cd ~ 72 | 73 | if [ -d "xii" ] ; then 74 | mv xii xii.bakup.$RANDOM 75 | fi 76 | 77 | mkdir xii 78 | cd xii 79 | wget -c https://github.com/xiiapp/xii/raw/main/release_dev/xii_mac.zip -O xii.zip 80 | unzip xii.zip -d ./ 81 | mv -f ~/xii/mac/* ./ 82 | rm -rf ~/xii/release 83 | rm -f ~/xii/xii.zip 84 | if [ Location == "world" ] ; then 85 | sed -i "" 's/CONTAINER_PACKAGE_URL=mirrors.ustc.edu.cn/CONTAINER_PACKAGE_URL=/g' ~/xii/repo/base/env.sample 86 | fi 87 | chmod +x ~/xii/xii 88 | echo "创建软链接需要输入密码授权" 89 | sudo ln -s ~/xii/xii /usr/local/bin/xii 90 | sudo ln -s ~/xii/xii /usr/local/bin/xxi 91 | 92 | 93 | 94 | 95 | else 96 | cd /home 97 | 98 | if [ -d "xii" ] ; then 99 | mv xii xii.bakup.$RANDOM 100 | fi 101 | mkdir xii 102 | cd xii 103 | wget -c https://github.com/xiiapp/xii/raw/main/release_dev/xii_linux.zip -O xii.zip 104 | unzip xii.zip -d ./ 105 | mv -f /home/xii/linux/* ./ 106 | rm -rf /home/xii/release 107 | rm -f /home/xii/xii.zip 108 | if [ Location == "world" ] ; then 109 | sed -i "" 's/CONTAINER_PACKAGE_URL=mirrors.ustc.edu.cn/CONTAINER_PACKAGE_URL=/g' /home/xii/repo/base/env.sample 110 | fi 111 | chmod +x /home/xii/xii 112 | ln -s /home/xii/xii /usr/local/bin/xii 113 | ln -s /home/xii/xii /usr/local/bin/xxi 114 | 115 | fi 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | echo " " 125 | echo " " 126 | echo " " 127 | echo -e "\033[33m ---Success---\033[0m" 128 | echo -e "\033[33mXII is installed successfully.\033[0m" 129 | if [ "$(uname)" == "Darwin" ] ; then 130 | echo -e "\033[33m Your app location is ~/xii \033[0m" 131 | else 132 | echo -e " Your app location is /home/xii " 133 | 134 | fi 135 | echo -e "\033[33mPlease visit https://xii.app for detail information before use.\033[0m" 136 | echo " " 137 | echo " " 138 | echo " " 139 | echo " " 140 | 141 | # export PATH=$PATH:/home/xii/assistant or ln -s /home/xii/assistant/xii /usr/bin/xii -------------------------------------------------------------------------------- /script_dev/make.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 编译xii助手 4 | cd ../assistant 5 | gf build -n xii_mac -a amd64 -s darwin 6 | gf build -n xii_linux -a amd64 -s linux 7 | 8 | # 迁移xii助手 9 | cd ../ 10 | rm -rf ./release_dev/linux 11 | rm -rf ./release_dev/mac 12 | rm -f ./release_dev/xii_linux.zip 13 | rm -f ./release_dev/xii_mac.zip 14 | 15 | mkdir ./release_dev/linux 16 | mkdir ./release_dev/mac 17 | 18 | mv ./assistant/temp/darwin_amd64/xii_mac ./release_dev/mac/xii 19 | mv ./assistant/temp/linux_amd64/xii_linux ./release_dev/linux/xii 20 | 21 | # 创建目录 22 | mkdir ./release_dev/linux/data 23 | mkdir ./release_dev/mac/data 24 | 25 | mkdir ./release_dev/linux/www 26 | mkdir ./release_dev/mac/www 27 | 28 | mkdir ./release_dev/linux/logs 29 | mkdir ./release_dev/mac/logs 30 | 31 | mkdir ./release_dev/linux/env 32 | mkdir ./release_dev/mac/env 33 | 34 | # 复制文件 35 | cp -r ./repo ./release_dev/linux/repo 36 | cp -r ./repo ./release_dev/mac/repo 37 | cp -r ./script/manual.sh ./release_dev/mac/manual.sh 38 | cp -r ./script/manual.sh ./release_dev/linux/manual.sh 39 | 40 | # 打包 41 | cd ./release_dev 42 | zip -r xii_linux.zip ./linux 43 | zip -r xii_mac.zip ./mac 44 | rm -rf ./linux 45 | rm -rf ./mac 46 | -------------------------------------------------------------------------------- /www/localhost/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | XII Running 6 | 7 | 8 | 安装成功!为安全起见,建议删除localhost网站。

9 | 执行命令:xii vhost del 10 | 11 | --------------------------------------------------------------------------------