├── data
├── prometheus
│ └── .gitignore
├── mongo
│ └── .gitignore
├── mysql
│ └── .gitignore
├── composer
│ └── .gitignore
└── grafana
│ └── .gitignore
├── .dockerignore
├── config
├── lua
│ ├── waf
│ │ ├── wafconf
│ │ │ ├── whiteurl
│ │ │ ├── white-user-agent
│ │ │ ├── user-agent
│ │ │ ├── url
│ │ │ ├── cookie
│ │ │ ├── post
│ │ │ └── args
│ │ ├── config.lua
│ │ ├── waf.lua
│ │ └── init.lua
│ └── test
│ │ ├── http.lua
│ │ ├── redis.lua
│ │ └── mysql.lua
├── sentry
│ ├── .gitignore
│ └── Dockerfile
├── redis
│ └── Dockerfile
├── mongodb
│ └── Dockerfile
├── nginx
│ ├── conf.d
│ │ ├── .gitignore
│ │ ├── certs
│ │ │ └── localhost
│ │ │ │ ├── server.csr
│ │ │ │ ├── gencert.sh
│ │ │ │ ├── server.crt
│ │ │ │ ├── server.key
│ │ │ │ └── server.origin.key
│ │ ├── lua.conf
│ │ ├── localhost.conf
│ │ └── localhost_https.conf
│ ├── Dockerfile
│ └── nginx.conf
├── golang
│ └── Dockerfile
├── node
│ └── Dockerfile
├── php
│ ├── extensions
│ │ ├── redis-4.3.0.tgz
│ │ ├── xdebug-2.6.1.tgz
│ │ ├── install-composer.sh
│ │ ├── php.sh
│ │ └── install.sh
│ ├── Dockerfile
│ ├── php-fpm.conf
│ └── seccomp.json
├── postgres
│ └── Dockerfile
├── mysql
│ ├── Dockerfile
│ └── mysql.cnf
├── yapi
│ ├── entrypoint.sh
│ ├── config.json
│ ├── Dockerfile
│ └── wait-for-it.sh
├── caddy
│ ├── Dockerfile
│ ├── Caddyfile
│ └── vhosts
│ │ └── localhost
├── grafana
│ ├── prometheus.yml
│ └── grafana.ini
└── ubuntu
│ └── Dockerfile
├── logs
├── caddy
│ └── .gitignore
├── nginx
│ └── .gitignore
├── php
│ └── .gitignore
└── letsencrypt
│ └── .gitignore
├── www
└── localhost
│ ├── .user.ini
│ ├── tools
│ └── adminer.php.bak
│ └── index.php
├── .gitattributes
├── .gitignore
├── zdc.bat
├── LICENSE
├── docker.md
├── .env.example
├── README.md
├── docker-compose.yml.example
└── run.sh
/data/prometheus/.gitignore:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.dockerignore:
--------------------------------------------------------------------------------
1 | log/
2 | mysql/
3 | www/
--------------------------------------------------------------------------------
/data/mongo/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
--------------------------------------------------------------------------------
/data/mysql/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
--------------------------------------------------------------------------------
/config/lua/waf/wafconf/whiteurl:
--------------------------------------------------------------------------------
1 | ^/123/$
2 |
--------------------------------------------------------------------------------
/logs/caddy/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/logs/nginx/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/logs/php/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/config/lua/waf/wafconf/white-user-agent:
--------------------------------------------------------------------------------
1 | (baidu)
2 |
--------------------------------------------------------------------------------
/logs/letsencrypt/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/config/sentry/.gitignore:
--------------------------------------------------------------------------------
1 | .gitignore
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/data/composer/.gitignore:
--------------------------------------------------------------------------------
1 | .gitignore
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/data/grafana/.gitignore:
--------------------------------------------------------------------------------
1 | .gitignore
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/www/localhost/.user.ini:
--------------------------------------------------------------------------------
1 | open_basedir=/var/www/html/localhost:/tmp/:/proc/
2 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text eol=lf
2 |
3 | *.png binary
4 | *.jpg binary
5 | *.tgz binary
--------------------------------------------------------------------------------
/config/redis/Dockerfile:
--------------------------------------------------------------------------------
1 | ARG REDIS_IMAGES
2 |
3 | FROM ${REDIS_IMAGES}
4 |
5 |
--------------------------------------------------------------------------------
/config/mongodb/Dockerfile:
--------------------------------------------------------------------------------
1 | ARG MONGODB_IMAGES
2 | FROM ${MONGODB_IMAGES}
3 |
4 |
5 |
--------------------------------------------------------------------------------
/config/nginx/conf.d/.gitignore:
--------------------------------------------------------------------------------
1 | !.gitignore
2 | !localhost.conf
3 | !localhost_https.conf
4 |
--------------------------------------------------------------------------------
/config/golang/Dockerfile:
--------------------------------------------------------------------------------
1 | ARG GO_IMAGES
2 | FROM ${GO_IMAGES}
3 |
4 | WORKDIR /var/www/html
5 |
--------------------------------------------------------------------------------
/config/node/Dockerfile:
--------------------------------------------------------------------------------
1 | ARG NODE_IMAGES
2 | FROM ${NODE_IMAGES}
3 |
4 | WORKDIR /var/www/html
5 |
--------------------------------------------------------------------------------
/config/nginx/Dockerfile:
--------------------------------------------------------------------------------
1 | ARG NGINX_IMAGES
2 | FROM ${NGINX_IMAGES}
3 |
4 | WORKDIR /var/www/html
5 |
--------------------------------------------------------------------------------
/config/sentry/Dockerfile:
--------------------------------------------------------------------------------
1 | ARG SENTRY_IMAGES
2 | FROM ${SENTRY_IMAGES}
3 |
4 | ARG SENTRY_REDIS_HOST
5 |
--------------------------------------------------------------------------------
/www/localhost/tools/adminer.php.bak:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sohaha/zls-docker/HEAD/www/localhost/tools/adminer.php.bak
--------------------------------------------------------------------------------
/config/php/extensions/redis-4.3.0.tgz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sohaha/zls-docker/HEAD/config/php/extensions/redis-4.3.0.tgz
--------------------------------------------------------------------------------
/config/postgres/Dockerfile:
--------------------------------------------------------------------------------
1 | ARG POSTGRES_IMAGES
2 | FROM ${POSTGRES_IMAGES}
3 |
4 | CMD ["postgres"]
5 |
6 | EXPOSE 5432
7 |
--------------------------------------------------------------------------------
/config/php/extensions/xdebug-2.6.1.tgz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sohaha/zls-docker/HEAD/config/php/extensions/xdebug-2.6.1.tgz
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .env
3 | .idea/
4 | .vscode/
5 | tmp/
6 | !www/localhost/
7 | docker-compose.yml
8 | www/
9 | data/
10 |
--------------------------------------------------------------------------------
/config/lua/waf/wafconf/user-agent:
--------------------------------------------------------------------------------
1 | (HTTrack|harvest|audit|dirbuster|pangolin|nmap|sqln|-scan|hydra|Parser|libwww|BBBike|sqlmap|w3af|owasp|Nikto|fimap|havij|PycURL|zmeu|BabyKrokodil|netsparker|httperf|bench| SF/)
2 |
--------------------------------------------------------------------------------
/config/mysql/Dockerfile:
--------------------------------------------------------------------------------
1 | ARG MYSQL_IMAGES
2 | FROM ${MYSQL_IMAGES}
3 |
4 | # mysql backup scripts using crontab
5 | # COPY ./scripts/ /data/mysql/backup/scripts/
6 | # RUN crontab /data/mysql/backup/scripts/crontabfile
7 | # RUN service cron start
8 |
--------------------------------------------------------------------------------
/config/yapi/entrypoint.sh:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 | cd ${VENDORS}
3 | if [ ! -e "init.lock" ]
4 | then
5 | cd ${VENDORS}
6 | yapi install -v ${YAPI_VERSION}
7 | touch init.lock
8 | fi
9 |
10 | cd ${VENDORS}
11 | # 先判断有没有CMD指定路径
12 | if [ $1 ]
13 | then
14 | node $i
15 | else
16 | node server/app.js
17 | fi
--------------------------------------------------------------------------------
/config/caddy/Dockerfile:
--------------------------------------------------------------------------------
1 | ARG CADDY_IMAGES
2 |
3 | FROM ${CADDY_IMAGES} AS builder
4 |
5 | # RUN go env -w GOPROXY=https://goproxy.cn,direct && xcaddy build --with github.com/caddy-dns/dnspod@latest
6 |
7 |
8 | FROM ${CADDY_IMAGES}
9 |
10 | WORKDIR /var/www/html
11 |
12 | # COPY --from=builder /usr/bin/caddy /usr/bin/caddy
--------------------------------------------------------------------------------
/config/lua/waf/wafconf/url:
--------------------------------------------------------------------------------
1 | \.(svn|git|htaccess|bash_history|DS_Store)
2 | \.(bak|inc|old|mdb|sql|backup|java|class)$
3 | (vhost|bbs|host|wwwroot|www|site|root|hytop|flashfxp).*\.rar
4 | (phpmyadmin|jmx-console|jmxinvokerservlet)
5 | java\.lang
6 | /(attachments|upimg|images|css|uploadfiles|html|uploads|templets|static|template|data|inc|forumdata|upload|includes|cache|avatar)/(\w+).(php|jsp)
7 |
--------------------------------------------------------------------------------
/config/caddy/Caddyfile:
--------------------------------------------------------------------------------
1 |
2 | import ./vhosts/*
3 |
4 | # https://73zls.com {
5 | # tls caddy@caddy.com
6 | # root * /var/www/html/xxx/public
7 | # file_server
8 | # proxy / 127.0.0.1:20000
9 | # }
10 |
11 | # http://73zls.com
12 | # {
13 | # redir https://73zls.com{url}
14 | # }
15 |
16 | # Refer to the Caddy docs for more information:
17 | # https://caddyserver.com/docs/caddyfile
18 |
--------------------------------------------------------------------------------
/config/grafana/prometheus.yml:
--------------------------------------------------------------------------------
1 | global:
2 | scrape_interval: 60s
3 | evaluation_interval: 60s
4 |
5 | scrape_configs:
6 | - job_name: prometheus
7 | static_configs:
8 | - targets: ['localhost:9090']
9 | labels:
10 | instance: prometheus
11 |
12 | - job_name: mysqld
13 | static_configs:
14 | - targets: ['mysqlexporter:9104']
15 |
16 | - job_name: 'node'
17 | static_configs:
18 | - targets: ['nodeexporter:9100']
--------------------------------------------------------------------------------
/config/yapi/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "port": "8005",
3 | "adminAccount": "admin@admin.com",
4 | "db": {
5 | "servername": "mongodb",
6 | "DATABASE": "yapi",
7 | "port": 27017,
8 | "user": "yapi",
9 | "pass": "73zls666"
10 | },
11 | "mail": {
12 | "enable": false,
13 | "host": "smtp.163.com",
14 | "port": 465,
15 | "from": "***@163.com",
16 | "auth": {
17 | "user": "***@163.com",
18 | "pass": "*****"
19 | }
20 | }
21 | }
--------------------------------------------------------------------------------
/config/php/extensions/install-composer.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | echo "---------- Install composer ----------"
4 |
5 | isChina=$(curl --silent "cip.cc" | grep "中国")
6 | isComposerURL="https://github.com/composer/composer/releases/download/${COMPOSER_VERSION}/composer.phar"
7 | if [[ -n $isChina || "" == $COMPOSER_VERSION ]]; then
8 | isComposerURL="https://mirrors.aliyun.com/composer/composer.phar"
9 | fi
10 |
11 | wget ${isComposerURL} \
12 | && chmod a+rwx composer.phar \
13 | && mv composer.phar /usr/local/bin/composer \
14 | && composer config -l -g
--------------------------------------------------------------------------------
/config/caddy/vhosts/localhost:
--------------------------------------------------------------------------------
1 | :80 {
2 | # Set this path to your site's directory.
3 | root * /var/www/html/localhost
4 |
5 | # compress
6 | encode gzip
7 |
8 | # Enable the static file server.
9 | file_server {
10 | precompressed br gzip
11 | hide .git .git/ .git/* .git* .gitignore
12 | }
13 |
14 | # Redirect.
15 | # redir https://www.73zls.com{uri}
16 |
17 | # Another common task is to set up a reverse proxy:
18 | # reverse_proxy localhost:8080
19 |
20 | # Or serve a PHP site through php-fpm:
21 | php_fastcgi php:9000
22 |
23 | file_server
24 | }
25 |
--------------------------------------------------------------------------------
/config/ubuntu/Dockerfile:
--------------------------------------------------------------------------------
1 | ARG UBUNTU_IMAGES
2 | FROM ${UBUNTU_IMAGES}
3 |
4 | WORKDIR /var/www/html
5 |
6 | ENV GOUP_GO_HOST=golang.google.cn
7 | ENV GOUP_UPDATE_ROOT=https://github.com/owenthereal/goup/releases/latest/download
8 | ENV GOPROXY=https://goproxy.cn
9 |
10 | ENV PATH=$PATH:/root/.go/bin:/root/.go/current/bin
11 |
12 | RUN sed -i s@/archive.ubuntu.com/@/mirrors.aliyun.com/@g /etc/apt/sources.list && apt-get clean
13 |
14 | # RUN apt update && apt install curl -y
15 | # curl -sSf https://raw.githubusercontent.com/owenthereal/goup/master/install.sh | sh -s -- '--skip-prompt'
16 |
17 | # apt install -y manpages-dev
18 | # RUN tail -F /dev/null
19 |
20 | # gcc
21 | # apt update && apt install -y gcc build-essential
--------------------------------------------------------------------------------
/config/nginx/conf.d/certs/localhost/server.csr:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE REQUEST-----
2 | MIIBrzCCARgCAQAwbzELMAkGA1UEBhMCVVMxDTALBgNVBAgMBE1hcnMxEzARBgNV
3 | BAcMCmlUcmFuc3dhcnAxEzARBgNVBAoMCmlUcmFuc3dhcnAxEzARBgNVBAsMCmlU
4 | cmFuc3dhcnAxEjAQBgNVBAMMCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOB
5 | jQAwgYkCgYEAuM697WuhKWhxoY7mQHToThWbQZN1kss8omrJzo9TJbQzASpOGDBa
6 | hRZn1HQxZiorN7XNuQopF0He5kVb5ge3smvNVyeFoKzSHgEV9Q6owKaSJPX2LpTw
7 | 6r/uuOA93jnosz5/R5IDrErfKt57n5QJ4PRS9zZ6op1Yq5iTc0jhtlECAwEAAaAA
8 | MA0GCSqGSIb3DQEBCwUAA4GBAGmV0Q7YkEux+0DvpzhAGhi6mGs097vKMtAUUPCk
9 | A7ETj7XWRR+49VMzG0IzE3Y3mKMi63m34mxnmDmJvZX5UWB+ijc33609hGnzNW8P
10 | KgtB1EJBb7lymP59Ja/XFj95m14E3ZDDPFgdES8jT0AjQHHAu9r1GYHT57tx2fOj
11 | AP5x
12 | -----END CERTIFICATE REQUEST-----
13 |
--------------------------------------------------------------------------------
/config/lua/waf/wafconf/cookie:
--------------------------------------------------------------------------------
1 | \.\./
2 | \:\$
3 | \$\{
4 | select.+(from|limit)
5 | (?:(union(.*?)select))
6 | having|rongjitest
7 | sleep\((\s*)(\d*)(\s*)\)
8 | benchmark\((.*)\,(.*)\)
9 | base64_decode\(
10 | (?:from\W+information_schema\W)
11 | (?:(?:current_)user|database|schema|connection_id)\s*\(
12 | (?:etc\/\W*passwd)
13 | into(\s+)+(?:dump|out)file\s*
14 | group\s+by.+\(
15 | xwork.MethodAccessor
16 | (?:define|eval|file_get_contents|include|require|require_once|shell_exec|phpinfo|system|passthru|preg_\w+|execute|echo|print|print_r|var_dump|(fp)open|alert|showmodaldialog)\(
17 | xwork\.MethodAccessor
18 | (gopher|doc|php|glob|file|phar|zlib|ftp|ldap|dict|ogg|data)\:\/
19 | java\.lang
20 | \$_(GET|post|cookie|files|session|env|phplib|GLOBALS|SERVER)\[
21 |
--------------------------------------------------------------------------------
/config/nginx/conf.d/certs/localhost/gencert.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # create self-signed server certificate:
4 |
5 | read -p "Enter your domain [www.example.com]: " DOMAIN
6 |
7 | echo "Create server key..."
8 |
9 | openssl genrsa -des3 -out $DOMAIN.key 1024
10 |
11 | echo "Create server certificate signing request..."
12 |
13 | SUBJECT="/C=US/ST=Mars/L=iTranswarp/O=iTranswarp/OU=iTranswarp/CN=$DOMAIN"
14 |
15 | openssl req -new -subj $SUBJECT -key $DOMAIN.key -out $DOMAIN.csr
16 |
17 | echo "Remove password..."
18 |
19 | mv $DOMAIN.key $DOMAIN.origin.key
20 | openssl rsa -in $DOMAIN.origin.key -out $DOMAIN.key
21 |
22 | echo "Sign SSL certificate..."
23 |
24 | openssl x509 -req -days 3650 -in $DOMAIN.csr -signkey $DOMAIN.key -out $DOMAIN.crt
25 |
26 | echo "Done!"
27 |
--------------------------------------------------------------------------------
/config/lua/waf/wafconf/post:
--------------------------------------------------------------------------------
1 | select.+(from|limit)
2 | (?:(union(.*?)select))
3 | having|rongjitest
4 | sleep\((\s*)(\d*)(\s*)\)
5 | benchmark\((.*)\,(.*)\)
6 | base64_decode\(
7 | (?:from\W+information_schema\W)
8 | (?:(?:current_)user|database|schema|connection_id)\s*\(
9 | (?:etc\/\W*passwd)
10 | into(\s+)+(?:dump|out)file\s*
11 | group\s+by.+\(
12 | xwork.MethodAccessor
13 | (?:define|eval|file_get_contents|include|require|require_once|shell_exec|phpinfo|system|passthru|preg_\w+|execute|echo|print|print_r|var_dump|(fp)open|alert|showmodaldialog)\(
14 | xwork\.MethodAccessor
15 | (gopher|doc|php|glob|file|phar|zlib|ftp|ldap|dict|ogg|data)\:\/
16 | java\.lang
17 | \$_(GET|post|cookie|files|session|env|phplib|GLOBALS|SERVER)\[
18 | \<(iframe|script|body|img|layer|div|meta|style|base|object|input)
19 | (onmouseover|onerror|onload)\=
20 |
--------------------------------------------------------------------------------
/zdc.bat:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 | set mycd=%cd%
3 | cd /d %~dp0
4 | set c=%1
5 | set a=%*
6 | call :CurDIR "%cd%"
7 | goto :eof
8 | :CurDIR
9 | set _dockerDir=%~nx1
10 | set volume=--volume %mycd%:/var/www/html
11 |
12 | if %c% == php (docker run --tty --interactive --rm --cap-add SYS_PTRACE %volume% --workdir /var/www/html "%_dockerDir%_php" %a%)
13 |
14 | if %c% == composer (docker run --tty --interactive --rm --cap-add SYS_PTRACE %volume% --workdir /var/www/html "%_dockerDir%_php" %a%)
15 |
16 | if %c% == node (docker run --tty --interactive --rm --cap-add SYS_PTRACE %volume% --workdir /var/www/html "%_dockerDir%_node" %a%)
17 |
18 | if %c% == npm (docker run --tty --interactive --rm --cap-add SYS_PTRACE %volume% --workdir /var/www/html "%_dockerDir%_node" %a%)
19 |
20 | if %c% == up (docker-compose up -d nginx)
21 |
22 | cd /d %mycd%
--------------------------------------------------------------------------------
/config/php/Dockerfile:
--------------------------------------------------------------------------------
1 | ARG PHP_IMAGES
2 | FROM ${PHP_IMAGES}
3 |
4 | ARG PHP_EXTENSIONS
5 | ARG MORE_EXTENSION_INSTALLER
6 | ARG ALPINE_REPOSITORIES
7 | ARG COMPOSER_VERSION
8 | ARG COMPOSER_PACKAGIST
9 |
10 | COPY ./extensions /tmp/extensions
11 |
12 | WORKDIR /tmp/extensions
13 |
14 | ENV EXTENSIONS=",${PHP_EXTENSIONS},"
15 | ENV MC="-j$(nproc)"
16 | ENV COMPOSER_HOME="/composer"
17 | ENV COMPOSER_ALLOW_SUPERUSER=1
18 | ENV COMPOSER_PACKAGIST="${COMPOSER_PACKAGIST}"
19 |
20 | RUN export MC="-j$(nproc)" \
21 | && chmod +x install.sh \
22 | && chmod +x install-composer.sh \
23 | && chmod +x "${MORE_EXTENSION_INSTALLER}"\
24 | && sh install.sh \
25 | && sh "${MORE_EXTENSION_INSTALLER}" \
26 | && php -v \
27 | && php -m \
28 | && sh install-composer.sh \
29 | && rm -rf /tmp/extensions
30 |
31 | WORKDIR /var/www/html
32 |
--------------------------------------------------------------------------------
/config/lua/waf/wafconf/args:
--------------------------------------------------------------------------------
1 | \.\./
2 | \:\$
3 | \$\{
4 | select.+(from|limit)
5 | (?:(union(.*?)select))
6 | having|rongjitest
7 | sleep\((\s*)(\d*)(\s*)\)
8 | benchmark\((.*)\,(.*)\)
9 | base64_decode\(
10 | (?:from\W+information_schema\W)
11 | (?:(?:current_)user|database|schema|connection_id)\s*\(
12 | (?:etc\/\W*passwd)
13 | into(\s+)+(?:dump|out)file\s*
14 | group\s+by.+\(
15 | xwork.MethodAccessor
16 | (?:define|eval|file_get_contents|include|require|require_once|shell_exec|phpinfo|system|passthru|preg_\w+|execute|echo|print|print_r|var_dump|(fp)open|alert|showmodaldialog)\(
17 | xwork\.MethodAccessor
18 | (gopher|doc|php|glob|file|phar|zlib|ftp|ldap|dict|ogg|data)\:\/
19 | java\.lang
20 | \$_(GET|post|cookie|files|session|env|phplib|GLOBALS|SERVER)\[
21 | \<(iframe|script|body|img|layer|div|meta|style|base|object|input)
22 | (onmouseover|onerror|onload)\=
23 |
--------------------------------------------------------------------------------
/config/nginx/conf.d/certs/localhost/server.crt:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIICVTCCAb4CCQCz53tsf+lJiTANBgkqhkiG9w0BAQsFADBvMQswCQYDVQQGEwJV
3 | UzENMAsGA1UECAwETWFyczETMBEGA1UEBwwKaVRyYW5zd2FycDETMBEGA1UECgwK
4 | aVRyYW5zd2FycDETMBEGA1UECwwKaVRyYW5zd2FycDESMBAGA1UEAwwJbG9jYWxo
5 | b3N0MB4XDTE5MDgwMTAzMzk1M1oXDTI5MDcyOTAzMzk1M1owbzELMAkGA1UEBhMC
6 | VVMxDTALBgNVBAgMBE1hcnMxEzARBgNVBAcMCmlUcmFuc3dhcnAxEzARBgNVBAoM
7 | CmlUcmFuc3dhcnAxEzARBgNVBAsMCmlUcmFuc3dhcnAxEjAQBgNVBAMMCWxvY2Fs
8 | aG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAuM697WuhKWhxoY7mQHTo
9 | ThWbQZN1kss8omrJzo9TJbQzASpOGDBahRZn1HQxZiorN7XNuQopF0He5kVb5ge3
10 | smvNVyeFoKzSHgEV9Q6owKaSJPX2LpTw6r/uuOA93jnosz5/R5IDrErfKt57n5QJ
11 | 4PRS9zZ6op1Yq5iTc0jhtlECAwEAATANBgkqhkiG9w0BAQsFAAOBgQA28kayGliM
12 | 0OBXcKHoPNeGnpOvPjekN6jyistjYjdiYyNiLFIw2Mt2rQWiXYQq9Vz1T0P7EQO5
13 | udFoV9aTgu0jORbTNGgkLE6EzsDX4xDLR0knodLxi/b6svzYlwEmcsBmpa5GEzC6
14 | P1eZQ/VUthEvfxQCmqbUzl3C1vz7fRrXZg==
15 | -----END CERTIFICATE-----
16 |
--------------------------------------------------------------------------------
/config/nginx/conf.d/certs/localhost/server.key:
--------------------------------------------------------------------------------
1 | -----BEGIN RSA PRIVATE KEY-----
2 | MIICXAIBAAKBgQC4zr3ta6EpaHGhjuZAdOhOFZtBk3WSyzyiasnOj1MltDMBKk4Y
3 | MFqFFmfUdDFmKis3tc25CikXQd7mRVvmB7eya81XJ4WgrNIeARX1DqjAppIk9fYu
4 | lPDqv+644D3eOeizPn9HkgOsSt8q3nuflAng9FL3NnqinVirmJNzSOG2UQIDAQAB
5 | AoGAdj8qPRhptQHz+uhhIQrsfNHMVkgQqY1Kza1AVN9V10EWhX9ZGpcNxCwS4Vg7
6 | J2CB6JJ2ABilNBFcmr/0ThnQCc09gGk2z1qeLfqlmMOWY7bjGqCCEv3yCZFddHTy
7 | 98JenFiz6CAxkLcxbDSyUk/IP2reEvc7r43njk6kWMwlBqUCQQDrnz1rHS3021rS
8 | mciVbeSHJjQOgKGx/PHpfrtESjjPG2KiqnLCNDUY9B4/bxy1WqXi9N9TSphYOB4I
9 | xK1ZkUd7AkEAyMpzfKoiWy7uQNVF+qFMrbMBhKVWSJOHUCoaGtERwQnlc8ZrIk2A
10 | 33OHnIY4ULQn/sTPgUWlnRllitvSrEOpowJAZFqxZRLLhRN8TmCTbxmcEPfzig29
11 | ULqkKkgA6KgYJBXM3+1q7U4hI1yuGWRwvMk8CDs1dxs5YbGdESz7jD91SwJAXGjg
12 | cdWTbkfRG0GMrWai9aZW4od9iHVtZzWZQhJKi39UfM4q7GSjFTQEi8MyE+J2LcjC
13 | f4pgSEcx9pBpCyMw5QJBAIUBRFzvSdkMzzssj0ti9BZiXuvcylAQ3fp8yXoJrZr+
14 | dBKaX8JbftMKoidGdKFV/+J+olYMwtMs0c54z/AVxuE=
15 | -----END RSA PRIVATE KEY-----
16 |
--------------------------------------------------------------------------------
/config/nginx/conf.d/certs/localhost/server.origin.key:
--------------------------------------------------------------------------------
1 | -----BEGIN RSA PRIVATE KEY-----
2 | Proc-Type: 4,ENCRYPTED
3 | DEK-Info: DES-EDE3-CBC,7B88CF20C2DD2972
4 |
5 | ztUpEzHGRNQ2xSRyWR/pwOFvXPVbmt+Fiv1ayiJRKaxS8aDtOxv0izk37EOU66Wk
6 | ilD+JjHx5iWcFiNRBKRsfQ983mS35bV6Xo37bLnEYtClxAJChUjnmRGT2KHSo7ye
7 | 9lE5RyDnTqJFR/rz6QfLqrVyWYwJmFpaJqkSd7uFB92Eo8GjIoCccH7uZwCn05ur
8 | /kIUVVg5XZ7O7H+8FI1MAOUmkZipwpRDN7A07A2NW5bUpZ6cp03eBkJEOOfrF9C3
9 | v59n2Ei/eFgFaJsV8hCj3tBzEcokFL+CKhQl8PL3oOULIzC36WtEOlg3dtK3Jorm
10 | 9X9pEurWKOh0DCnNugW0vQGUfD26eUGn2USXhqkFxkV58WLVfmT414KrsGtJfISO
11 | H2DHtj822Z/VYOPaDXMoROhB8RYtdE8s1HbAUMDxknt4JVIR9rNRiaPl9fkXCrA0
12 | LBuRaXF9A821L+W/BZia2ahtAJ4bfQXgYB08n1T/VBp4VBjQY80DkK3Ou0QuOsuF
13 | EJHXR96pM0ACDShhKppxXK0ozZst/XLUJ/6w3UtHRjL9zyx8Fq040EEjEayY8cqM
14 | 2iWd1OHtDI44g+Xb6X0h3Mk1e3gXmc8Wlq80wVqxOaZ8rGIQ+epGYZGBK3sI7wrL
15 | wiDDKrwmQqbsJcg8sFB+THhEtgIZGfWh96CI/27n4mzWNm+Ys2NzjqiM5QhN/du9
16 | rLIaVYHldzkgnkMW+w1EXi82tpbQKI5Kw9jolF8fPSYYJroT7xe/Kuuim2z0AEWD
17 | SLQCB9t4zGdzOFGlZ+EucPaMepFeEb0p9xMKXI0ENZIR+Cno/OQFQA==
18 | -----END RSA PRIVATE KEY-----
19 |
--------------------------------------------------------------------------------
/config/mysql/mysql.cnf:
--------------------------------------------------------------------------------
1 | # [client]
2 | # port = 3306
3 | # default-character-set = utf8mb4
4 | #
5 | #
6 | # [mysqld]
7 | # user = mysql
8 | # port = 3306
9 | # sql_mode = ""
10 | #
11 | # default-storage-engine = InnoDB
12 | # default-authentication-plugin = mysql_native_password
13 | # character-set-server = utf8mb4
14 | # collation-server = utf8mb4_unicode_ci
15 | # init_connect = 'SET NAMES utf8mb4'
16 | #
17 | # disable-log-bin
18 | # skip-character-set-client-handshake
19 | # explicit_defaults_for_timestamp
20 | #
21 | # slow_query_log
22 | # long_query_time = 3
23 | # slow-query-log-file = /var/lib/mysql/mysql.slow.log
24 | # log-error = /var/lib/mysql/mysql.error.log
25 | # # mysql 5.7 Please note the following
26 | # log-bin = /var/lib/mysql/logbin.log
27 | # # close log
28 | # skip-log-bin
29 | # default-time-zone = '+8:00'
30 | # # skip-grant-tables
31 | #
32 | # max_connections = 10000
33 |
34 | [mysql]
35 | default-character-set = utf8mb4
36 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Wallace Gao
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/config/nginx/conf.d/lua.conf:
--------------------------------------------------------------------------------
1 |
2 | # lua 配置
3 | lua_shared_dict limit 20m;
4 | # 设置防火墙包路径
5 | lua_package_path "/usr/local/openresty/nginx/conf/lua/waf/?.lua;;";
6 | init_by_lua_file "/usr/local/openresty/nginx/conf/lua/waf/init.lua";
7 |
8 | server {
9 | listen 80;
10 | server_name lua.localhost;
11 | # 开启防火墙
12 | access_by_lua_file conf/lua/waf/waf.lua;
13 |
14 | resolver 8.8.8.8 114.114.114.114 valid=3600s;
15 | location /http {
16 | default_type text/html;
17 | # lua_code_cache off; # 关闭缓存
18 | rewrite_by_lua_block {
19 | }
20 | header_filter_by_lua_block {
21 | ngx.header.content_type = "text/html;charset=utf8"
22 | }
23 | content_by_lua_file conf/lua/test/http.lua;
24 | }
25 |
26 | location / {
27 | default_type text/html;
28 | content_by_lua_block {
29 | ngx.say("
hello, world
")
30 | }
31 | }
32 |
33 | location /redis {
34 | default_type text/html;
35 | content_by_lua_file conf/lua/test/redis.lua;
36 | }
37 |
38 | location /mysql {
39 | default_type text/html;
40 | content_by_lua_file conf/lua/test/mysql.lua;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/config/yapi/Dockerfile:
--------------------------------------------------------------------------------
1 | ARG NODE_IMAGES
2 | FROM ${NODE_IMAGES}
3 |
4 | ARG YAPI_VERSION
5 | ARG YAPI_HOME
6 | ARG YAPI_HOST_PORT
7 |
8 | ENV VENDORS ${YAPI_HOME}/vendors
9 | ENV GIT_URL https://github.com/YMFE/yapi.git
10 | ENV GIT_MIRROR_URL https://gitee.com/mirrors/YApi.git
11 |
12 | COPY ./wait-for-it.sh /
13 | COPY ./entrypoint.sh /bin
14 |
15 | WORKDIR ${YAPI_HOME}/
16 |
17 | RUN echo "https://mirror.tuna.tsinghua.edu.cn/alpine/v3.4/main/" > /etc/apk/repositories
18 |
19 | RUN apk update \
20 | && apk upgrade \
21 | && apk add --no-cache git curl python make openssl tar gcc bash \
22 | && rm -rf /var/cache/apk/*
23 |
24 | RUN rm -rf node && \
25 | ret=`curl -s https://api.ip.sb/geoip | grep China | wc -l` && \
26 | if [ $ret -ne 0 ]; then \
27 | GIT_URL=${GIT_MIRROR_URL} && npm config set registry https://registry.npm.taobao.org; \
28 | fi; \
29 | echo ${GIT_URL} && \
30 | git clone --depth 1 ${GIT_URL} vendors && \
31 | cd vendors && \
32 | npm install -g node-gyp yapi-cli && \
33 | npm install --production && \
34 | chmod +x /bin/entrypoint.sh && \
35 | chmod +x /wait-for-it.sh
36 |
37 | EXPOSE ${YAPI_HOST_PORT}
38 | ENTRYPOINT ["entrypoint.sh"]
39 |
--------------------------------------------------------------------------------
/config/lua/test/http.lua:
--------------------------------------------------------------------------------
1 | --[[
2 | Author: seekwe
3 | Date: 2020-08-13 16:05:18
4 | Last Modified by:: seekwe
5 | Last Modified time: 2020-08-14 18:31:26
6 | --]]
7 |
8 | -- curl --request POST 'http://nginx:81/http?get=isGet' --form 'post=yesPost'
9 |
10 | local request_method = ngx.var.request_method
11 |
12 | local ua = ngx.var.http_user_agent
13 |
14 | local ip = getClientIp()
15 |
16 | ngx.say(os.date("%Y-%m-%d %H:%M:%S",os.time())," ",os.getenv("TZ"))
17 | ngx.say("
")
18 | ngx.say("IP: ",ip)
19 | ngx.say("method: ",request_method)
20 | ngx.say("
")
21 | ngx.say("user_agent: ",ua)
22 | ngx.say("
")
23 |
24 | if ngx.req.get_uri_args()["jump"] == nil then
25 | ngx.say('没有 Get 参数,手动设置一个')
26 | ngx.say("
")
27 | ngx.req.set_uri_args({help = 'yes'});
28 | end
29 |
30 | if request_method == "POST" then
31 | ngx.req.read_body() -- 解析 body 参数之前一定要先读取 body
32 | local arg = ngx.req.get_post_args()
33 | for k,v in pairs(arg) do
34 | ngx.say("[POST] ", k, ": ", v,"
")
35 | end
36 | end
37 |
38 | local arg = ngx.req.get_uri_args()
39 | for k,v in pairs(arg) do
40 | ngx.say("[GET] ", k, ": ", v,"
")
41 | end
42 |
43 | for k,v in pairs(ngx.req.get_headers()) do
44 | ngx.say("[HEAD] ", k, ": ", v,"
")
45 | end
46 |
47 | ngx.exit(ngx.OK)
--------------------------------------------------------------------------------
/config/lua/waf/config.lua:
--------------------------------------------------------------------------------
1 | --[[
2 | Author: seekwe
3 | Date: 2019-10-27 18:24:58
4 | Last Modified by:: seekwe
5 | Last Modified time: 2020-08-14 20:46:44
6 | --]]
7 |
8 | --规则存放目录
9 | RulePath = "wafconf/"
10 | --是否开启攻击信息记录,需要配置logdir
11 | Attacklog = "off"
12 | --log存储目录,该目录需要用户自己新建,切需要nginx用户的可写权限
13 | Logdir = "/var/log/nginx/"
14 | --是否拦截url访问
15 | UrlDeny="on"
16 | --是否拦截后重定向
17 | Redirect="on"
18 | --是否拦截cookie攻击
19 | CookieMatch="on"
20 | --是否拦截post攻击
21 | PostMatch="off"
22 | --是否开启URL白名单
23 | WhiteModule="off"
24 | --是否开启主机(对应nginx里面的server_name)白名单
25 | WhiteHostModule="off"
26 | --不可可上传文件后缀类型
27 | BlackFileExt={"php","jsp"}
28 | --ip白名单,多个ip用逗号分隔
29 | IpWhitelist={"127.0.0.1","172.16.1.0-172.16.1.255"}
30 | --ip黑名单,多个ip用逗号分隔
31 | IpBlocklist={"1.0.0.1","2.0.0.0-2.0.0.255"}
32 | --server_name白名单,多个用逗号分隔
33 | HostWhiteList = {"blog.73zls.com"}
34 | --是否开启拦截cc攻击(需要nginx.conf的http段增加lua_shared_dict limit 10m;)
35 | CCDeny="on"
36 | --设置cc攻击频率,单位为秒.默认1分钟同一个IP只能请求同一个地址70次
37 | CCrate="70/60"
38 | Html=[[
39 |
40 |
41 |
42 |
43 | 503 Service Temporarily Unavailable
44 |
nginx
45 |
46 |
47 | ]]
48 |
49 |
--------------------------------------------------------------------------------
/config/php/php-fpm.conf:
--------------------------------------------------------------------------------
1 | ;;;;;;;;;;;;;;;;;;;;;
2 | ; FPM Configuration ;
3 | ;;;;;;;;;;;;;;;;;;;;;
4 |
5 | ;;;;;;;;;;;;;;;;;;
6 | ; Global Options ;
7 | ;;;;;;;;;;;;;;;;;;
8 |
9 | [global]
10 | pid = /var/run/php-fpm.pid
11 | error_log = /var/log/php/php-fpm.log
12 | log_level = warning
13 |
14 | emergency_restart_threshold = 30
15 | emergency_restart_interval = 60s
16 | process_control_timeout = 5s
17 | daemonize = yes
18 |
19 | ;;;;;;;;;;;;;;;;;;;;
20 | ; Pool Definitions ;
21 | ;;;;;;;;;;;;;;;;;;;;
22 |
23 | [www]
24 | ;listen = /dev/shm/php-cgi.sock
25 | listen = 127.0.0.1:9000
26 | ;listen.backlog = -1
27 | ;listen.allowed_clients = 127.0.0.1
28 | ;listen.owner = www-data
29 | ;listen.group = www-data
30 | ;listen.mode = 0666
31 | user = www-data
32 | group = www-data
33 |
34 | pm = dynamic
35 | pm.max_children = 100
36 | pm.start_servers = 10
37 | pm.min_spare_servers = 10
38 | pm.max_spare_servers = 40
39 | ;pm.max_requests = 2048
40 | pm.process_idle_timeout = 10s
41 | request_terminate_timeout = 120
42 | request_slowlog_timeout = 0
43 |
44 | ;pm.status_path = /php-fpm_status
45 | slowlog = /var/log/php/slow.log
46 | rlimit_files = 51200
47 | rlimit_core = 0
48 |
49 | catch_workers_output = yes
50 | ;env[HOSTNAME] = ubuntu
51 | env[PATH] = /usr/local/bin:/usr/bin:/bin
52 | env[TMP] = /tmp
53 | env[TMPDIR] = /tmp
54 | env[TEMP] = /tmp
55 |
--------------------------------------------------------------------------------
/config/lua/test/redis.lua:
--------------------------------------------------------------------------------
1 | --[[
2 | Author: seekwe
3 | Date: 2020-08-13 17:45:02
4 | Last Modified by:: seekwe
5 | Last Modified time: 2020-08-13 18:24:22
6 | --]]
7 |
8 | -- curl 'http://nginx:81/redis'
9 |
10 | -- redis config
11 | local redis = require "resty.redis"
12 | local red = redis:new()
13 | local redis_passwd = "73zls666"
14 | local redis_host = "172.0.0.40"
15 |
16 | local ok, err = red:connect(redis_host, 6379)
17 |
18 | if not ok then
19 | ngx.say("failed to connect: ", err)
20 | return
21 | end
22 |
23 | if redis_passwd then
24 | local count
25 | count, err = red:get_reused_times()
26 | if 0 == count then
27 | ok, err = red:auth(redis_passwd)
28 | if not ok then
29 | ngx.say("failed to auth: ", err)
30 | return
31 | end
32 | elseif err then
33 | ngx.say("failed to get reused times: ", err)
34 | return
35 | end
36 | end
37 |
38 | ok, err = red:set("dog", "an animal1")
39 | if not ok then
40 | ngx.say("failed to set dog: ", err)
41 | return
42 | end
43 |
44 | ngx.say("set result: ", ok)
45 |
46 | local res, err = red:get("dog")
47 | if not res then
48 | ngx.say("failed to get dog: ", err)
49 | return
50 | end
51 |
52 | if res == ngx.null then
53 | ngx.say("dog not found.")
54 | return
55 | end
56 |
57 | ngx.say("dog: ", res)
58 |
59 |
--------------------------------------------------------------------------------
/config/lua/test/mysql.lua:
--------------------------------------------------------------------------------
1 | --[[
2 | Author: seekwe
3 | Date: 2020-08-13 18:20:29
4 | Last Modified by:: seekwe
5 | Last Modified time: 2020-08-13 18:24:12
6 | --]]
7 |
8 | -- curl 'http://nginx:81/mysql'
9 |
10 | local cjson = require "cjson"
11 | local mysql = require "resty.mysql"
12 |
13 | local db = mysql:new()
14 | local ok, err, errcode, sqlstate = db:connect({
15 | host = "172.0.0.20",
16 | port = 3306,
17 | database = "mysql",
18 | user = "root",
19 | password = "73zls666"})
20 |
21 | if not ok then
22 | ngx.log(ngx.ERR, "failed to connect: ", err, ": ", errcode, " ", sqlstate)
23 | return ngx.exit(500)
24 | end
25 |
26 | res, err, errcode, sqlstate = db:query("select 1; select 2; select 3;")
27 | if not res then
28 | ngx.log(ngx.ERR, "bad result #1: ", err, ": ", errcode, ": ", sqlstate, ".")
29 | return ngx.exit(500)
30 | end
31 |
32 | ngx.say("result #1: ", cjson.encode(res))
33 |
34 | local i = 2
35 | while err == "again" do
36 | res, err, errcode, sqlstate = db:read_result()
37 | if not res then
38 | ngx.log(ngx.ERR, "bad result #", i, ": ", err, ": ", errcode, ": ", sqlstate, ".")
39 | return ngx.exit(500)
40 | end
41 | ngx.say("result #", i, ": ", cjson.encode(res))
42 | i = i + 1
43 | end
44 |
45 | local ok, err = db:set_keepalive(10000, 50)
46 | if not ok then
47 | ngx.log(ngx.ERR, "failed to set keepalive: ", err)
48 | ngx.exit(500)
49 | end
--------------------------------------------------------------------------------
/config/nginx/conf.d/localhost.conf:
--------------------------------------------------------------------------------
1 | server {
2 | # 使用是需要去掉默认站点设置`default_server`
3 | listen 80 default_server;
4 | charset utf-8;
5 | server_name localhost;
6 | root /var/www/html/localhost;
7 | index index.php index.html index.htm;
8 |
9 | # 开启防火墙
10 | access_by_lua_file conf/lua/waf/waf.lua;
11 |
12 | # jump https
13 | #rewrite ^(.*)$ https://$host$1 permanent;
14 |
15 | #error_page 404 /404.html;
16 |
17 | location ~ /.well-known {
18 | allow all;
19 | }
20 |
21 | # jump https
22 | #location ~ /.well-known {
23 | # rewrite ^(.*)$ https://$host$1 permanent;
24 | #}
25 |
26 | # rewrite
27 | location / {
28 | try_files $uri $uri/ /index.php$is_args$query_string;
29 | }
30 |
31 | location ~ \.php$ {
32 | fastcgi_pass php:9000;
33 | fastcgi_index index.php;
34 | include fastcgi_params;
35 | fastcgi_param PATH_INFO $fastcgi_path_info;
36 | fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
37 | }
38 |
39 | #location / {
40 | # proxy_pass http://172.0.0.1; # or http://host.docker.internal;
41 | # proxy_redirect off;
42 | # proxy_set_header Host $host;
43 | # proxy_set_header X-Real-IP $remote_addr;
44 | # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
45 | # proxy_set_header X-Forwarded-Proto $scheme;
46 | #}
47 |
48 | #location /php-fpm_status {
49 | # include fastcgi_params;
50 | # fastcgi_pass php:9000;
51 | # fastcgi_param SCRIPT_FILENAME $fastcgi_script_name;
52 | #}
53 |
54 | #access_log /var/log/nginx/nginx.localhost.access.log main;
55 | #error_log /var/log/nginx/nginx.localhost.error.log error;
56 | }
57 |
58 |
--------------------------------------------------------------------------------
/docker.md:
--------------------------------------------------------------------------------
1 | # docker 安装文档
2 |
3 | ## CentOS
4 |
5 | 请按顺序执行以下命令
6 |
7 | ```bash
8 | # 安装依赖
9 | sudo yum install -y yum-utils device-mapper-persistent-data lvm2
10 |
11 | # 配置 repositories
12 | sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
13 |
14 | # 安装 docker
15 | sudo yum install docker-ce -y
16 |
17 | # 检查 dokcer 是否安装成功
18 | docker version
19 |
20 | # 启动 docker
21 | systemctl start docker
22 |
23 | # 开机自动启动 docker
24 | systemctl enable docker
25 |
26 | # 安装 docker-compose
27 |
28 | ## 如果安装失败可以使用 py 的 pip 安装,方式自行谷歌
29 | curl -L "https://github.com/docker/compose/releases/download/1.25.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
30 | ## 国内建议使用国内源
31 | curl -L "https://get.daocloud.io/docker/compose/releases/download/1.25.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
32 |
33 |
34 | ## 设置 docker-compose 权限
35 | chmod +x /usr/local/bin/docker-compose
36 |
37 | # 检查 docker-compose 是否安装成功
38 | docker-compose --version
39 | ```
40 |
41 | ## Ubuntu
42 |
43 | ```bash
44 | sudo curl -sSL https://get.docker.com | sh
45 | sudo usermod pi -aG docker
46 | curl -L "https://get.daocloud.io/docker/compose/releases/download/1.25.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
47 | chmod +x /usr/local/bin/docker-compose
48 | ```
49 |
50 | ## 更多问题
51 |
52 | **权限问题**
53 |
54 | 如果不是 root 用户或提示权限问题,可将当前用户加入 docker 用户组
55 |
56 | ```bash
57 | sudo groupadd docker
58 | sudo gpasswd -a ${USER} docker
59 | sudo service docker restart
60 | ```
61 |
62 | **Pull 太慢**
63 |
64 | 如果是国内服务器请尝试更换 docker 源为国内源
65 |
66 | ```bash
67 | vi /etc/docker/daemon.json
68 |
69 | # {"registry-mirrors": ["https://registry.docker-cn.com"]}
70 |
71 | # 腾讯云
72 | # {"registry-mirrors": ["https://mirror.ccs.tencentyun.com"]}
73 |
74 | # 编辑后重启 dokcer
75 | systemctl daemon-reload
76 | systemctl restart docker
77 | ```
78 |
--------------------------------------------------------------------------------
/config/nginx/conf.d/localhost_https.conf:
--------------------------------------------------------------------------------
1 | server {
2 | listen 443 ssl http2;
3 | server_name localhost;
4 | root /var/www/html/localhost;
5 | index index.php index.html index.htm;
6 |
7 | # 开启防火墙
8 | access_by_lua_file conf/lua/waf/waf.lua;
9 |
10 | access_log /dev/null;
11 | #access_log /var/log/nginx/nginx.localhost.https.access.log main;
12 |
13 | #error_log /var/log/nginx/nginx.localhost.https.error.log warn;
14 |
15 | # Please create your own certificate settings
16 | #ssl_certificate /etc/nginx/letsencrypt/localhost/fullchain1.pem;
17 | #ssl_certificate_key /etc/nginx/letsencrypt/localhost/privkey1.pem;
18 | ssl_certificate /etc/nginx/conf.d/certs/localhost/server.crt;
19 | ssl_certificate_key /etc/nginx/conf.d/certs/localhost/server.key;
20 | ssl_prefer_server_ciphers on;
21 | ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
22 | ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4";
23 | add_header Strict-Transport-Security max-age=31536000;
24 |
25 | #error_page 404 /404.html;
26 |
27 | # redirect server error pages to the static page /50x.html
28 | error_page 500 502 503 504 /50x.html;
29 | location = /50x.html {
30 | root /usr/share/nginx/html;
31 | }
32 |
33 | location ~ /.well-known {
34 | allow all;
35 | }
36 |
37 | # proxy the swoole, You need to comment out the following rewrite
38 | # location / {
39 | # proxy_set_header Host $http_host;
40 | # proxy_set_header X-Real-IP $remote_addr;
41 | # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
42 | # proxy_set_header X-Forwarded-Proto $scheme;
43 | # proxy_pass https://172.0.0.30:8081;
44 | # }
45 |
46 | # rewrite
47 | location / {
48 | try_files $uri $uri/ /index.php$is_args$query_string;
49 | }
50 |
51 | # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
52 | location ~ \.php$ {
53 | fastcgi_pass php:9000;
54 | fastcgi_index index.php;
55 | include fastcgi_params;
56 | fastcgi_param PATH_INFO $fastcgi_path_info;
57 | fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/www/localhost/index.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | 程序版本信息
8 |
9 |
10 |
11 | 数据库管理';
13 | echo '程序版本信息
';
14 | echo '';
15 | echo '- Nodejs版本:10.16.0
';
16 | echo '- Nginx版本:', $_SERVER['SERVER_SOFTWARE'], '
';
17 | echo '- MySQL服务器版本:', getMysqlVersion(), '
';
18 | echo '- Redis服务器版本:', getRedisVersion(), '
';
19 | echo '- PHP版本:', PHP_VERSION, '
';
20 | echo '
';
21 |
22 | echo '已安装的php扩展
';
23 | printExtensions();
24 |
25 | /**
26 | * 获取MySQL版本
27 | */
28 | function getMysqlVersion()
29 | {
30 | if (extension_loaded('PDO_MYSQL')) {
31 | try {
32 | $dbh = new PDO('mysql:host=mysql;dbname=mysql', 'root', $_SERVER['MYSQL_ROOT_PASSWORD']??'');
33 | $sth = $dbh->query('SELECT VERSION() as version');
34 | $info = $sth->fetch();
35 | } catch (PDOException $e) {
36 | if(strpos($e->getMessage(), 'getaddrinfo failed: Name ')){
37 | return "Mysql 没有启动";
38 | }
39 | return $e->getMessage();
40 | }
41 | return $info['version'];
42 | } else {
43 | return 'PDO_MYSQL 扩展未安装 ×';
44 | }
45 |
46 | }
47 |
48 | /**
49 | * 获取Redis版本
50 | */
51 | function getRedisVersion()
52 | {
53 | if (extension_loaded('redis')) {
54 | try {
55 | $redis = new Redis();
56 | $redis->connect('redis', 6379);
57 | $redis->auth($_SERVER['REDIS_PASSWORD'] ?? '');
58 | /** @var array $info */
59 | $info = $redis->info();
60 | return $info['redis_version'];
61 | } catch (Exception $e) {
62 | if(strpos($e->getMessage(), 'Name does not resolve')){
63 | return "Redis 没有启动";
64 | }
65 | return $e->getMessage();
66 | }
67 | } else {
68 | return 'Redis 扩展未安装 ×';
69 | }
70 | }
71 |
72 | /**
73 | * 获取已安装扩展列表
74 | */
75 | function printExtensions()
76 | {
77 | echo '';
78 | foreach (get_loaded_extensions() as $i => $name) {
79 | echo "- ", $name, '=', phpversion($name), '
';
80 | }
81 | echo '
';
82 | }
83 | ?>
84 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/config/lua/waf/waf.lua:
--------------------------------------------------------------------------------
1 | --[[
2 | Author: seekwe
3 | Date: 2019-10-27 18:24:58
4 | Last Modified by:: seekwe
5 | Last Modified time: 2020-08-13 19:06:24
6 | --]]
7 |
8 | local content_length=tonumber(ngx.req.get_headers()['content-length'])
9 | local method=ngx.req.get_method()
10 | local ngxmatch=ngx.re.match
11 | if whiteip() then
12 | elseif whitehost() then
13 | elseif whiteua() then
14 | elseif blockip() then
15 | elseif denycc() then
16 | elseif ngx.var.http_Acunetix_Aspect then
17 | ngx.exit(444)
18 | elseif ngx.var.http_X_Scan_Memo then
19 | ngx.exit(444)
20 | elseif whiteurl() then
21 | elseif ua() then
22 | elseif url() then
23 | elseif args() then
24 | elseif cookie() then
25 | elseif PostCheck then
26 | if method=="POST" then
27 | local boundary = get_boundary()
28 | if boundary then
29 | local len = string.len
30 | local sock, err = ngx.req.socket()
31 | if not sock then
32 | return
33 | end
34 | ngx.req.init_body(128 * 1024)
35 | sock:settimeout(0)
36 | local content_length = nil
37 | content_length=tonumber(ngx.req.get_headers()['content-length'])
38 | local chunk_size = 4096
39 | if content_length < chunk_size then
40 | chunk_size = content_length
41 | end
42 | local size = 0
43 | while size < content_length do
44 | local data, err, partial = sock:receive(chunk_size)
45 | data = data or partial
46 | if not data then
47 | return
48 | end
49 | ngx.req.append_body(data)
50 | if body(data) then
51 | return true
52 | end
53 | size = size + len(data)
54 | local m = ngxmatch(data,[[Content-Disposition: form-data;(.+)filename="(.+)\\.(.*)"]],'ijo')
55 | if m then
56 | fileExtCheck(m[3])
57 | filetranslate = true
58 | else
59 | if ngxmatch(data,"Content-Disposition:",'isjo') then
60 | filetranslate = false
61 | end
62 | if filetranslate==false then
63 | if body(data) then
64 | return true
65 | end
66 | end
67 | end
68 | local less = content_length - size
69 | if less < chunk_size then
70 | chunk_size = less
71 | end
72 | end
73 | ngx.req.finish_body()
74 | else
75 | ngx.req.read_body()
76 | local args = ngx.req.get_post_args()
77 | if not args then
78 | return
79 | end
80 | for key, val in pairs(args) do
81 | if type(val) == "table" then
82 | if type(val[1]) == "boolean" then
83 | return
84 | end
85 | data=table.concat(val, ", ")
86 | else
87 | data=val
88 | end
89 | if data and type(data) ~= "boolean" and body(data) then
90 | return true
91 | end
92 | end
93 | end
94 | end
95 | else
96 | return
97 | end
98 |
--------------------------------------------------------------------------------
/config/php/extensions/php.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | echo
4 | echo "============================================"
5 | echo "Install extensions from : ${MORE_EXTENSION_INSTALLER}"
6 | echo "Extra Extensions : ${PHP_EXTENSIONS}"
7 | echo "Multicore Compilation : ${MC}"
8 | echo "Work directory : ${PWD}"
9 | echo "============================================"
10 | echo
11 |
12 |
13 | if [ -z "${EXTENSIONS##*,mcrypt,*}" ]; then
14 | echo "---------- mcrypt was REMOVED from PHP 7.2.0 ----------"
15 | fi
16 |
17 |
18 | if [ -z "${EXTENSIONS##*,mysql,*}" ]; then
19 | echo "---------- mysql was REMOVED from PHP 7.0.0 ----------"
20 | fi
21 |
22 |
23 | if [ -z "${EXTENSIONS##*,sodium,*}" ]; then
24 | echo "---------- Install sodium ----------"
25 | echo "Sodium is bundled with PHP from PHP 7.2.0 "
26 | fi
27 |
28 | if [ -z "${EXTENSIONS##*,swoole,*}" ]; then
29 | echo "---------- Install swoole ----------"
30 | # git clone --depth=1
31 | cd /tmp/extensions
32 | curl -o ./swoole.tar.gz https://github.com/swoole/swoole-src/archive/master.tar.gz -L && \
33 | tar zxvf ./swoole.tar.gz && \
34 | mv swoole-src* swoole-src && \
35 | cd swoole-src && \
36 | phpize && \
37 | ./configure \
38 | --enable-openssl \
39 | --enable-http2 && \
40 | make clean && make && make install
41 | # pecl install swoole \
42 | docker-php-ext-enable swoole
43 | fi
44 |
45 | # if [ -z "${EXTENSIONS##*,swoole_tracker,*}" ]; then
46 | # echo "---------- Install swoole_tracker ----------"
47 | # cd /tmp/extensions
48 | # chmod +x ./swoole-tracker-install.sh && \
49 | # ./swoole-tracker-install.sh && \
50 | # rm ./swoole-tracker-install.sh
51 | # echo -e "\033[32m echo -e 'extension=/usr/local/etc/php/swoole-tracker/swoole_tracker73.so\napm.enable=1\napm.sampling_rate=100' > /usr/local/etc/php/conf.d/swoole-tracker.ini \033[0m"
52 | # cp -r swoole-tracker /usr/local/etc/php/
53 | # fi
54 |
55 | if [ -z "${EXTENSIONS##*,mongodb,*}" ]; then
56 | echo "---------- Install mongodb ----------"
57 | pecl install mongodb
58 | docker-php-ext-enable mongodb
59 | fi
60 |
61 | if [ -z "${EXTENSIONS##*,yaf,*}" ]; then
62 | echo "---------- Install yaf ----------"
63 | pecl install yaf
64 | docker-php-ext-enable yaf
65 | fi
66 |
67 | if [ -z "${EXTENSIONS##*,amqp,*}" ]; then
68 | echo "---------- Install amqp ----------"
69 | apk add --no-cache rabbitmq-c-dev
70 | cd /tmp/extensions
71 | pecl install amqp-1.9.4.tgz
72 | docker-php-ext-enable amqp
73 | fi
74 |
75 | if [ -z "${EXTENSIONS##*,redis,*}" ]; then
76 | echo "---------- Install redis ----------"
77 | mkdir redis \
78 | && tar -xf redis-4.3.0.tgz -C redis --strip-components=1 \
79 | && ( cd redis && phpize && ./configure && make ${MC} && make install ) \
80 | && docker-php-ext-enable redis
81 | fi
82 |
83 | if [ -z "${EXTENSIONS##*,memcached,*}" ]; then
84 | echo "---------- Install memcached ----------"
85 | apk add --no-cache libmemcached-dev zlib-dev
86 | printf "\n" | pecl install memcached-3.1.3
87 | docker-php-ext-enable memcached
88 | fi
89 |
90 | if [ -z "${EXTENSIONS##*,xdebug,*}" ]; then
91 | echo "---------- Install xdebug ----------"
92 | cd /tmp/extensions
93 | tar -xf xdebug-2.6.1.tgz -C xdebug --strip-components=1 \
94 | && ( cd xdebug && phpize && ./configure && make ${MC} && make install ) \
95 | && docker-php-ext-enable xdebug
96 | fi
97 |
98 | if [ -z "${EXTENSIONS##*,pdo_sqlsrv,*}" ]; then
99 | echo "---------- Install pdo_sqlsrv ----------"
100 | apk add --no-cache unixodbc-dev
101 | pecl install pdo_sqlsrv
102 | docker-php-ext-enable pdo_sqlsrv
103 | fi
104 |
105 | if [ -z "${EXTENSIONS##*,sqlsrv,*}" ]; then
106 | echo "---------- Install sqlsrv ----------"
107 | apk add --no-cache unixodbc-dev
108 | printf "\n" | pecl install sqlsrv
109 | docker-php-ext-enable sqlsrv
110 | fi
111 |
--------------------------------------------------------------------------------
/config/nginx/nginx.conf:
--------------------------------------------------------------------------------
1 | # nginx.conf -- docker-openresty
2 | #
3 | # This file is installed to:
4 | # `/usr/local/openresty/nginx/conf/nginx.conf`
5 | # and is the file loaded by nginx at startup,
6 | # unless the user specifies otherwise.
7 | #
8 | # It tracks the upstream OpenResty's `nginx.conf`, but removes the `server`
9 | # section and adds this directive:
10 | # `include /etc/nginx/conf.d/*.conf;`
11 | #
12 | # The `docker-openresty` file `nginx.vh.default.conf` is copied to
13 | # `/etc/nginx/conf.d/default.conf`. It contains the `server section
14 | # of the upstream `nginx.conf`.
15 | #
16 | # See https://github.com/openresty/docker-openresty/blob/master/README.md#nginx-config-files
17 | #
18 |
19 | #user nobody;
20 | #worker_processes 1;
21 |
22 | # Enables the use of JIT for regular expressions to speed-up their processing.
23 | pcre_jit on;
24 |
25 |
26 |
27 | #error_log logs/error.log;
28 | #error_log logs/error.log notice;
29 | #error_log logs/error.log info;
30 |
31 | #pid logs/nginx.pid;
32 |
33 |
34 | events {
35 | worker_connections 1024;
36 | }
37 |
38 |
39 | http {
40 | include mime.types;
41 | default_type application/octet-stream;
42 |
43 | # Enables or disables the use of underscores in client request header fields.
44 | # When the use of underscores is disabled, request header fields whose names contain underscores are marked as invalid and become subject to the ignore_invalid_headers directive.
45 | # underscores_in_headers off;
46 |
47 | #log_format main '$remote_addr - $remote_user [$time_local] "$request" '
48 | # '$status $body_bytes_sent "$http_referer" '
49 | # '"$http_user_agent" "$http_x_forwarded_for"';
50 |
51 | #access_log logs/access.log main;
52 |
53 | # Log in JSON Format
54 | # log_format nginxlog_json escape=json '{ "timestamp": "$time_iso8601", '
55 | # '"remote_addr": "$remote_addr", '
56 | # '"body_bytes_sent": $body_bytes_sent, '
57 | # '"request_time": $request_time, '
58 | # '"response_status": $status, '
59 | # '"request": "$request", '
60 | # '"request_method": "$request_method", '
61 | # '"host": "$host",'
62 | # '"upstream_addr": "$upstream_addr",'
63 | # '"http_x_forwarded_for": "$http_x_forwarded_for",'
64 | # '"http_referrer": "$http_referer", '
65 | # '"http_user_agent": "$http_user_agent", '
66 | # '"http_version": "$server_protocol", '
67 | # '"nginx_access": true }';
68 | # access_log /dev/stdout nginxlog_json;
69 |
70 | # See Move default writable paths to a dedicated directory (#119)
71 | # https://github.com/openresty/docker-openresty/issues/119
72 | client_body_temp_path /var/run/openresty/nginx-client-body;
73 | proxy_temp_path /var/run/openresty/nginx-proxy;
74 | fastcgi_temp_path /var/run/openresty/nginx-fastcgi;
75 | uwsgi_temp_path /var/run/openresty/nginx-uwsgi;
76 | scgi_temp_path /var/run/openresty/nginx-scgi;
77 |
78 | sendfile on;
79 | #tcp_nopush on;
80 |
81 | #keepalive_timeout 0;
82 | keepalive_timeout 65;
83 |
84 | client_max_body_size 20m;
85 |
86 | #Gzip Compression
87 | gzip on;
88 | gzip_buffers 16 8k;
89 | gzip_comp_level 6;
90 | gzip_http_version 1.1;
91 | gzip_min_length 256;
92 | gzip_proxied any;
93 | gzip_vary on;
94 | gzip_types
95 | text/xml application/xml application/atom+xml application/rss+xml application/xhtml+xml image/svg+xml
96 | text/javascript application/javascript application/x-javascript
97 | text/x-json application/json application/x-web-app-manifest+json
98 | text/css text/plain text/x-component
99 | font/opentype application/x-font-ttf application/vnd.ms-fontobject
100 | image/x-icon;
101 | gzip_disable "MSIE [1-6]\.(?!.*SV1)";
102 |
103 | include /etc/nginx/conf.d/*.conf;
104 |
105 | # Don't reveal OpenResty version to clients.
106 | # server_tokens off;
107 | }
--------------------------------------------------------------------------------
/.env.example:
--------------------------------------------------------------------------------
1 | ### environment config file ###############################
2 | SOURCE_DIR=./www
3 |
4 | ### Ubuntu #################################################
5 | UBUNTU_IMAGES=seekwe/ubuntu18:v2
6 |
7 | ### Nginx ##################################################
8 | # 更多版本选择:https://hub.docker.com/r/openresty/openresty/tags
9 | NGINX_IMAGES=openresty/openresty:1.21.4.1-2-bionic
10 | NGINX_HTTP_HOST_PORT=80
11 | NGINX_HTTPS_HOST_PORT=443
12 | NGINX_CONFD_DIR=./config/nginx/conf.d
13 | NGINX_CONF_FILE=./config/nginx/nginx.conf
14 | NGINX_LOG_DIR=./logs/nginx
15 | LUA_DIR=./config/lua
16 |
17 | ### Caddy ###################################################
18 | # 更多版本选择:https://hub.docker.com/_/caddy?tab=tags
19 | CADDY_IMAGES=caddy:2.6.2
20 | CADDY_CONF_DIR=./config/caddy
21 | CADDY_SSL_DIR=./data/caddy
22 | CADDY_LOG_DIR=./logs/caddy
23 | CADDY_HTTP_HOST_PORT=80
24 | CADDY_HTTPS_HOST_PORT=443
25 |
26 | ### PHP #####################################################
27 | # 更多版本选择:https://hub.docker.com/_/php/?tab=tags
28 | PHP_IMAGES=php:7.4.9-fpm-alpine
29 | # PHP 安装源 阿里云:mirrors.aliyun.com 清华:mirrors.tuna.tsinghua.edu.cn
30 | ALPINE_REPOSITORIES=mirrors.tuna.tsinghua.edu.cn
31 | PHP_PHP_CONF_FILE=./config/php/php.ini
32 | PHP_FPM_CONF_FILE=./config/php/php-fpm.conf
33 | PHP_LOG_DIR=./logs/php
34 | # 可用扩展:
35 | # pdo_mysql,odbc,pcntl,mysqli,mbstring,exif,bcmath,calendar,
36 | # sockets,gettext,shmop,sysvmsg,sysvsem,sysvshm,pdo_rebird,
37 | # pdo_dblib,pdo_oci,pdo_odbc,pdo_pgsql,pgsql,oci8,dba,gmp,zip,
38 | # gd,intl,bz2,soap,xsl,xmlrpc,wddx,curl,readline,snmp,pspell,
39 | # recode,tidy,imap,ldap,imagick,sqlsrv,mcrypt,opcache,mongodb,
40 | # redis,memcached,xdebug,swoole,pdo_sqlsrv,sodium,yaf,mysql,
41 | # 如果使用多个主题,请用逗号(,)分隔,注意前后都有(,)
42 | PHP_EXTENSIONS=,pdo_mysql,mysqli,gd,opcache,redis,zip,pcntl,exif,bcmath,sockets,gettext,intl,xmlrpc,mcrypt,
43 |
44 | ### MySQL ###################################################
45 | # 更多版本选择:https://hub.docker.com/_/mariadb/?tab=tags
46 | MYSQL_IMAGES=mariadb:10.9.4
47 | # 安全:不将端口暴露到外部网络
48 | MYSQL_HOST_PORT=127.0.0.1:3306
49 | MYSQL_ROOT_PASSWORD=73zls666
50 | MYSQL_DATABASE=zls
51 | MYSQL_DATA_DIR=./data/mysql
52 | MYSQL_CONF_DIR=./config/mysql
53 | MYSQL_CONF_FILE=./config/mysql/mysql.cnf
54 |
55 | ### Redis ####################################################
56 | REDIS_IMAGES=redis:5.0.9-alpine
57 | # 安全:不将端口暴露到外部网络
58 | REDIS_HOST_PORT=127.0.0.1:6379
59 | REDIS_CONF_FILE=./config/redis/redis.conf
60 | REDIS_PASSWORD=73zls666
61 |
62 |
63 | ### MONGODB ##################################################
64 | MONGODB_IMAGES=mongo:5.0.8
65 | MONGODB_CONF_DIR=./config/mongodb
66 | MONGODB_DATA_DIR=./data/mongo
67 | # 安全:不将端口暴露到外部网络
68 | MONGODB_HOST_PORT=127.0.0.1:27017
69 | MONGODB_INITDB_ROOT_USERNAME=root
70 | MONGODB_INITDB_ROOT_PASSWORD=73zls666
71 |
72 | ### COMPOSER #################################################
73 | COMPOSER_DATA_DIR=./data/composer
74 | COMPOSER_VERSION=1.8.6
75 | COMPOSER_PACKAGIST=https://mirrors.aliyun.com/composer/
76 |
77 | ### POSTGRES #################################################
78 | POSTGRES_IMAGES=postgres:15.0
79 | POSTGRES_DATA_DIR=./data/postgres
80 | # 安全:不将端口暴露到外部网络
81 | POSTGRES_PORT=127.0.0.1:5432
82 | POSTGRES_DB=zls
83 | POSTGRES_USER=root
84 | POSTGRES_PASSWORD=73zls666
85 |
86 | ### SENTRY #################################################
87 | SENTRY_IMAGES=sentry:latest
88 | SENTRY_DATA_DIR=./data/secret
89 | SENTRY_PORT=9000
90 | SENTRY_SECRET_KEY=")=uv7e1glkx9j&&wfesa5ffmz9atu3wh&1xe(mm(yemgbq-1#("
91 |
92 | ### PORTAINER ##############################################
93 | PORTAINER_IMAGES=portainer/portainer
94 | PORTAINER_DATA_DIR=./data/portainer
95 | PORTAINER_HOST_PORT=9001
96 |
97 | ### YAPI ###################################################
98 | YAPI_VERSION=1.8.1
99 | YAPI_HOST_PORT=3000
100 | YAPI_CONFIG_FILE=./config/yapi/config.json
101 | YAPI_HOME=/home
102 | YAPI_LOG_DIR=./logs/yapi
103 |
104 | ### MONITOR ################################################
105 | # https://grafana.com/grafana/dashboards
106 | GRAFANA_IMAGES=grafana/grafana:7.3.6
107 | GRAFANA_PORT=3000
108 | GRAFANA_PASSWORD=admin666
109 | GRAFANA_CONFIG_FILE=./config/grafana/grafana.ini
110 | GRAFANA_DATA_DIR=./data/grafana
111 | GRAFANA_LOG_DIR=./logs/grafana
112 |
113 | PROM_IMAGES=prom/prometheus:v2.23.0
114 | PROM_PORT=127.0.0.1:3001
115 | PROM_CONFIG_FILE=./config/grafana/prometheus.yml
116 | PROM_DATA_DIR=./data/prometheus
117 |
118 | ### Golang #################################################
119 | GO_IMAGES=golang:latest
120 |
121 | ### node ###################################################
122 | NODE_IMAGES=node:10.16.0-alpine
123 |
--------------------------------------------------------------------------------
/config/yapi/wait-for-it.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # Use this script to test if a given TCP host/port are available
3 |
4 | WAITFORIT_cmdname=${0##*/}
5 |
6 | echoerr() { if [[ $WAITFORIT_QUIET -ne 1 ]]; then echo "$@" 1>&2; fi }
7 |
8 | usage()
9 | {
10 | cat << USAGE >&2
11 | Usage:
12 | $WAITFORIT_cmdname host:port [-s] [-t timeout] [-- command args]
13 | -h HOST | --host=HOST Host or IP under test
14 | -p PORT | --port=PORT TCP port under test
15 | Alternatively, you specify the host and port as host:port
16 | -s | --strict Only execute subcommand if the test succeeds
17 | -q | --quiet Don't output any status messages
18 | -t TIMEOUT | --timeout=TIMEOUT
19 | Timeout in seconds, zero for no timeout
20 | -- COMMAND ARGS Execute command with args after the test finishes
21 | USAGE
22 | exit 1
23 | }
24 |
25 | wait_for()
26 | {
27 | if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then
28 | echoerr "$WAITFORIT_cmdname: waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT"
29 | else
30 | echoerr "$WAITFORIT_cmdname: waiting for $WAITFORIT_HOST:$WAITFORIT_PORT without a timeout"
31 | fi
32 | WAITFORIT_start_ts=$(date +%s)
33 | while :
34 | do
35 | if [[ $WAITFORIT_ISBUSY -eq 1 ]]; then
36 | nc -z $WAITFORIT_HOST $WAITFORIT_PORT
37 | WAITFORIT_result=$?
38 | else
39 | (echo > /dev/tcp/$WAITFORIT_HOST/$WAITFORIT_PORT) >/dev/null 2>&1
40 | WAITFORIT_result=$?
41 | fi
42 | if [[ $WAITFORIT_result -eq 0 ]]; then
43 | WAITFORIT_end_ts=$(date +%s)
44 | echoerr "$WAITFORIT_cmdname: $WAITFORIT_HOST:$WAITFORIT_PORT is available after $((WAITFORIT_end_ts - WAITFORIT_start_ts)) seconds"
45 | break
46 | fi
47 | sleep 1
48 | done
49 | return $WAITFORIT_result
50 | }
51 |
52 | wait_for_wrapper()
53 | {
54 | # In order to support SIGINT during timeout: http://unix.stackexchange.com/a/57692
55 | if [[ $WAITFORIT_QUIET -eq 1 ]]; then
56 | timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --quiet --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT &
57 | else
58 | timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT &
59 | fi
60 | WAITFORIT_PID=$!
61 | trap "kill -INT -$WAITFORIT_PID" INT
62 | wait $WAITFORIT_PID
63 | WAITFORIT_RESULT=$?
64 | if [[ $WAITFORIT_RESULT -ne 0 ]]; then
65 | echoerr "$WAITFORIT_cmdname: timeout occurred after waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT"
66 | fi
67 | return $WAITFORIT_RESULT
68 | }
69 |
70 | # process arguments
71 | while [[ $# -gt 0 ]]
72 | do
73 | case "$1" in
74 | *:* )
75 | WAITFORIT_hostport=(${1//:/ })
76 | WAITFORIT_HOST=${WAITFORIT_hostport[0]}
77 | WAITFORIT_PORT=${WAITFORIT_hostport[1]}
78 | shift 1
79 | ;;
80 | --child)
81 | WAITFORIT_CHILD=1
82 | shift 1
83 | ;;
84 | -q | --quiet)
85 | WAITFORIT_QUIET=1
86 | shift 1
87 | ;;
88 | -s | --strict)
89 | WAITFORIT_STRICT=1
90 | shift 1
91 | ;;
92 | -h)
93 | WAITFORIT_HOST="$2"
94 | if [[ $WAITFORIT_HOST == "" ]]; then break; fi
95 | shift 2
96 | ;;
97 | --host=*)
98 | WAITFORIT_HOST="${1#*=}"
99 | shift 1
100 | ;;
101 | -p)
102 | WAITFORIT_PORT="$2"
103 | if [[ $WAITFORIT_PORT == "" ]]; then break; fi
104 | shift 2
105 | ;;
106 | --port=*)
107 | WAITFORIT_PORT="${1#*=}"
108 | shift 1
109 | ;;
110 | -t)
111 | WAITFORIT_TIMEOUT="$2"
112 | if [[ $WAITFORIT_TIMEOUT == "" ]]; then break; fi
113 | shift 2
114 | ;;
115 | --timeout=*)
116 | WAITFORIT_TIMEOUT="${1#*=}"
117 | shift 1
118 | ;;
119 | --)
120 | shift
121 | WAITFORIT_CLI=("$@")
122 | break
123 | ;;
124 | --help)
125 | usage
126 | ;;
127 | *)
128 | echoerr "Unknown argument: $1"
129 | usage
130 | ;;
131 | esac
132 | done
133 |
134 | if [[ "$WAITFORIT_HOST" == "" || "$WAITFORIT_PORT" == "" ]]; then
135 | echoerr "Error: you need to provide a host and port to test."
136 | usage
137 | fi
138 |
139 | WAITFORIT_TIMEOUT=${WAITFORIT_TIMEOUT:-15}
140 | WAITFORIT_STRICT=${WAITFORIT_STRICT:-0}
141 | WAITFORIT_CHILD=${WAITFORIT_CHILD:-0}
142 | WAITFORIT_QUIET=${WAITFORIT_QUIET:-0}
143 |
144 | # check to see if timeout is from busybox?
145 | WAITFORIT_TIMEOUT_PATH=$(type -p timeout)
146 | WAITFORIT_TIMEOUT_PATH=$(realpath $WAITFORIT_TIMEOUT_PATH 2>/dev/null || readlink -f $WAITFORIT_TIMEOUT_PATH)
147 | if [[ $WAITFORIT_TIMEOUT_PATH =~ "busybox" ]]; then
148 | WAITFORIT_ISBUSY=1
149 | WAITFORIT_BUSYTIMEFLAG="-t"
150 |
151 | else
152 | WAITFORIT_ISBUSY=0
153 | WAITFORIT_BUSYTIMEFLAG=""
154 | fi
155 |
156 | if [[ $WAITFORIT_CHILD -gt 0 ]]; then
157 | wait_for
158 | WAITFORIT_RESULT=$?
159 | exit $WAITFORIT_RESULT
160 | else
161 | if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then
162 | wait_for_wrapper
163 | WAITFORIT_RESULT=$?
164 | else
165 | wait_for
166 | WAITFORIT_RESULT=$?
167 | fi
168 | fi
169 |
170 | if [[ $WAITFORIT_CLI != "" ]]; then
171 | if [[ $WAITFORIT_RESULT -ne 0 && $WAITFORIT_STRICT -eq 1 ]]; then
172 | echoerr "$WAITFORIT_cmdname: strict mode, refusing to execute subprocess"
173 | exit $WAITFORIT_RESULT
174 | fi
175 | exec "${WAITFORIT_CLI[@]}"
176 | else
177 | exit $WAITFORIT_RESULT
178 | fi
179 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # zls-docker
2 |
3 | 开箱即用的面向生产和开发环境的 Docker 镜像
4 |
5 | [详细文档](https://docs.73zls.com/zls-docker/#/)
6 |
7 | ## 目录结构
8 |
9 | ```
10 | .
11 | ├── config
12 | │ ├── mysql
13 | │ │ └── mysql.cnf mysql.cnf 配置
14 | │ ├── caddy caddy 配置目录
15 | │ ├── nginx
16 | │ │ ├── conf.d vhost 配置目录
17 | │ │ │ ├── localhost.conf 默认站点配置
18 | │ │ │ └── localhost_https.conf 默认站点HTTPS配置
19 | │ │ └── nginx.conf nginx.conf 配置
20 | │ ├── php
21 | │ │ ├── php-fpm.conf php-fpm.conf 配置
22 | │ │ └── php.ini php.ini 配置
23 | │ ├── redis
24 | │ │ └── redis.conf redis.conf 配置
25 | │ ├── lua lua 脚本
26 | │ │ └── waf
27 | │ │ └── config.lua web 防火墙配置
28 | ├── data 数据目录
29 | ├── logs 日志目录
30 | ├── docker-compose.yml docker-compose 编排文件
31 | ├── run.sh 执行脚本
32 | └── www 站点目录
33 | └── localhost 默认站点
34 | ```
35 |
36 | ## 快速上手
37 |
38 | 1. 安装 git、 docker 和 docker-compose
39 |
40 | docker >=19
41 |
42 | docker-compose >= 3
43 |
44 | 系统自带的 yum、apt 安装版本可能会过低了,
45 |
46 | 如不清楚如果不熟悉怎么安装 docker,
47 |
48 | 执行可以拉取项目后执行 ./run.sh installDocker 查看相关安装命令,
49 |
50 | 或查看 [docker.md](./docker.md) 参考安装步骤。
51 |
52 | 2. 拉取项目
53 |
54 | ```bash
55 | git clone --depth=1 https://github.com/sohaha/zls-docker.git
56 | ```
57 |
58 | 3. 启动
59 |
60 | *默认配置使用 nginx 与 caddy 只能启动其中一个。*
61 |
62 | ```bash
63 | # 更多命令直接执行 run.sh 查看
64 | ./run.sh up
65 |
66 | # Windows 请先复制配置再执行启动命令
67 | copy .env.example .env
68 | copy docker-compose.yml.example docker-compose.yml
69 | docker-compose up -d nginx mysql php
70 | ```
71 |
72 | 5. 访问在浏览器中访问 http://localhost/ 。
73 |
74 | ## 配置设置
75 |
76 | 更多配置请打开 .env 文件查看。
77 |
78 | ### PHP 使用
79 |
80 | **安装扩展**
81 |
82 | ```bash
83 | # 编辑.env文件,
84 | # 从扩展列表 PHP extensions 中选择相应的扩展,
85 | # 添加(移除)到 PHP_EXTENSIONS 中,英文逗号隔开
86 | PHP_EXTENSIONS=swoole,redis
87 |
88 | # 重新编译 PHP 镜像并启动
89 | ./run.sh buildUp php
90 |
91 | # Windows 请执行 docker-compose build php && docker-compose up php -d
92 | ```
93 |
94 | ### 定时任务
95 |
96 | 有些时候需要配置定时任务做一些特定业务处理,但是直接在容器内是不支持的,不过我们可以直接在宿主机上设置。
97 |
98 | !> 请确定 crontab 下 docker-compose 能正常使用,如果不能请尝试执行 `sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose` 再试。
99 |
100 | ```bash
101 | # 假设本脚本放在 /root/zls-docker 目录下
102 | # 需要每分钟执行一次 www/test/task.php
103 |
104 | # crontab -e
105 | # 下面语句就是每分钟进入 php 容器 执行 `php test/task.php`
106 | * * * * * /root/zls-docker/run.sh cron php php test/task.php
107 | ```
108 |
109 | ### 数据库使用
110 |
111 | - 在其它容器需要连接数据库 HOST 直接填容器名,如使用 MySQL: mysql 即可(或 172.0.0.20)。
112 |
113 | - 如需修改默认密码,编辑.env 文件即可,
114 |
115 | MySQL:`MYSQL_ROOT_PASSWORD=73zls666`,
116 |
117 | mongo:`MONGODB_INITDB_ROOT_PASSWORD=73zls666`
118 |
119 | 必须在容器生成之前,如果容器已经生成过,
120 |
121 | 请使用 bash 进入容器内修改,具体方法请谷歌。
122 |
123 | - Msqyl 建立新数据库直接执行: `zdc mysql` 然后选 3( Create Databases )即可。
124 |
125 | ---
126 |
127 | ## 日常使用
128 |
129 | ### 安装脚本
130 |
131 | 建议把脚本命令安装至系统中,方便使用
132 |
133 | ```bash
134 | ./run.sh tools
135 | # 输入1,自动安装至系统,然后就可以全局使用 zdocker
136 |
137 | zdocker help
138 | ```
139 |
140 | ### 命令行
141 |
142 | 如要使用 composer,启动 swoole ,或 npm 安装等等。
143 |
144 | ```bash
145 | ./run.sh composer install zls/wechat
146 | ./run.sh php test.php
147 | ./run.sh npm install zls-ui
148 | ./run.sh go build
149 | ...
150 | ```
151 |
152 | ### 重新加载
153 |
154 | nginx,php-fpm 之类的修改了配置是需要重新加载的,可使用该命令
155 |
156 | ```bash
157 | # 不值得容器默认为nginx,下面命令等同 ./run.sh reload nginx
158 | ./run.sh reload
159 |
160 | ./run.sh reload php
161 | ```
162 |
163 | ### 进入容器
164 |
165 | ```bash
166 | # ./run.sh bash 容器名称,如ph
167 | ./run.sh bash php
168 | ```
169 |
170 | ### 停止容器
171 |
172 | ```bash
173 | # ./run.sh stop 容器名称(空表示停止全部)
174 | ./run.sh stop nginx
175 | ```
176 |
177 | ### 辅助操作
178 |
179 | 一些常用的操作,如 php-fpm 优化,清理没用使用的容器等等
180 |
181 | ```bash
182 | ./run.sh tools
183 | ```
184 |
185 | ### HTTPS 证书
186 |
187 | **首次使用**
188 |
189 | ```bash
190 | # 如果首次执行失败,建议先把签证服务修改为 letsencrypt
191 | ~/.acme.sh/acme.sh --set-default-ca --server letsencrypt
192 | ```
193 |
194 | ```bash
195 | # ./run.sh ssl -d 要签名的域名 -w 服务器里项目访问路径
196 | ./run.sh ssl -d mydomain.com -w /home/zdocker/www/mydomain.com/public
197 |
198 | # 证书生成成功会自动拷贝一份到 /config/nginx/conf.d/certs/mydomain.com/ 目录
199 | # https 的配置可以参考 config/nginx/conf.d/localhost_https.conf
200 | ```
201 |
202 | ### 更多问题
203 |
204 | **数据库安全**
205 |
206 | 默认情况数据库是禁止外部连接的,如果需要开启请修改 .env 中的 MySQL 配置,
207 | 把 `MYSQL_HOST_PORT=127.0.0.1:3306` 改成 `MYSQL_HOST_PORT=3306`
208 |
209 | ```mysql
210 | # 为了安全性建议把 %.root 的密码修改成其他密码(默认密码:73zls666)
211 | ALTER USER `root`@`%` IDENTIFIED BY 'xxx1990hi',`root`@`%` PASSWORD EXPIRE NEVER;
212 | ```
213 |
214 | **数据库备份**
215 | 建议设置定时任务,定时备份数据库,如下:
216 |
217 | ```bash
218 | # 假设本脚本放在 /root/zls-docker 目录下
219 | # crontab -e
220 |
221 | # 每天凌晨三点备份 MySQL 数据库
222 | 00 03 * * * /root/zls-docker/run.sh mysql backup
223 |
224 | # 每天凌晨三点备份 MongoDB 数据库
225 | 00 03 * * * /root/zls-docker/run.sh mongodb backup
226 |
227 | ```
228 |
229 | **MongoDB 启动失败**
230 |
231 | ```
232 | /data/db/WiredTiger.wt: handle-open: open: Operation not permitted
233 | ```
234 |
235 | 原因: Windows 下不支持映射目录
236 |
237 | 解决方案: 注释掉 `docker-compose.yml` 文件内的 `mongodb` 映射配置,
238 |
239 | `# - ${MONGODB_DATA_DIR}:/data/db:rw`
240 |
241 | **Swoole 版本**
242 |
243 | 默认情况安装的是最新版的 Swoole, 如果需要指定版本直接修改安装脚本 `config/php/extensions/php.sh`
244 |
245 | **启动失败**
246 |
247 | 查看 logs 目录,参考日志信息处理。
248 |
249 | **安装 sentry**
250 |
251 | 首次启动之后需要初始化数据库,然后访问 http://127.0.0.1:9000 。
252 |
253 | ```bash
254 | # 首次启动一定一定要修改 SENTRY_SECRET_KEY ,下面这条命令可以动态生成一个 SECRET_KEY
255 | # docker run --rm sentry config generate-secret-key
256 | # 初始化数据库,过程需要填写邮箱与密码
257 | zdc bash sentry sentry upgrade
258 | ```
259 |
260 | **安装 YAPI**
261 |
262 | ```bash
263 | # 先启动 mongodb
264 | ./run.sh up mongodb
265 |
266 | # 进入 mogodb 内 建立 Yapi 账号
267 | ./run.sh bash mongodb
268 | # 进入 mongo 数据库
269 | mongo -u root -p 73zls666
270 | # 进入 Yapi 库
271 | use yapi
272 | # 添加一个用户 然后 Ctrl+c退出数据库 exit 退出容器
273 | db.createUser({user: "yapi",pwd: "73zls666",roles: [{role: "dbOwner",db: "yapi"}]})
274 | # 默认账号密码 admin@admin.com ymfe.org
275 | # 启动 yapi (上面步骤只要执行一次)
276 | ./run.sh up yapi
277 |
278 | ```
279 |
280 | **安装监控服务**
281 |
282 | 默认包含 grafana、prometheus、mysqlexporter。
283 |
284 | 注意: 如果你是 Root 用户启动,首次启动之前需要先给数据目录写入权限
285 |
286 | ```bash
287 | chmod 777 ./data/grafana
288 | chmod 777 ./data/prometheus
289 | ```
290 |
291 | 启动命令: zdc up grafana,
292 |
293 | 然后访问 http://127.0.0.1:3010/ ( 默认账号 admin/admin666 )。
294 |
295 | 配置 MySQL dashboard:
296 |
297 | 首先添加 Data Sources 选 Prometheus ,
298 |
299 | URL填: http://prometheus:9090 ,其他的默认保存即可,
300 |
301 | 然后复制 `config/grafana/mysql-dashboard.json` 内容,贴贴到 ‘Import via panel json’ 创建完成。
302 |
303 | 如需监控服务器性能:
304 |
305 | 需手动启动(需要 docker root 权限) `zdc up nodeexporter`,再 `Import via grafana.com` 编码 8919。
306 |
--------------------------------------------------------------------------------
/config/php/extensions/install.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | echo
4 | echo "============================================"
5 | echo "Install extensions from : install.sh"
6 | echo "Extra Extensions : ${PHP_EXTENSIONS}"
7 | echo "Multicore Compilation : ${MC}"
8 | echo "Work directory : ${PWD}"
9 | echo "============================================"
10 | echo
11 |
12 |
13 | if [ "${ALPINE_REPOSITORIES}" != "" ]; then
14 | sed -i "s/dl-cdn.alpinelinux.org/${ALPINE_REPOSITORIES}/g" /etc/apk/repositories
15 | fi
16 |
17 |
18 | if [ "${PHP_EXTENSIONS}" != "" ]; then
19 | echo "---------- Install general dependencies ----------"
20 | apk add --no-cache autoconf g++ libtool make curl-dev libxml2-dev linux-headers
21 | fi
22 |
23 | if [ -z "${EXTENSIONS##*,pdo_mysql,*}" ]; then
24 | echo "---------- Install pdo_mysql ----------"
25 | docker-php-ext-install ${MC} pdo_mysql
26 | fi
27 |
28 | if [ -z "${EXTENSIONS##*,zip,*}" ]; then
29 | echo "---------- Install zip ----------"
30 | apk add --no-cache libzip-dev
31 | docker-php-ext-install ${MC} zip
32 | fi
33 |
34 | if [ -z "${EXTENSIONS##*,pcntl,*}" ]; then
35 | echo "---------- Install pcntl ----------"
36 | docker-php-ext-install ${MC} pcntl
37 | fi
38 |
39 | if [ -z "${EXTENSIONS##*,mysqli,*}" ]; then
40 | echo "---------- Install mysqli ----------"
41 | docker-php-ext-install ${MC} mysqli
42 | fi
43 |
44 | if [ -z "${EXTENSIONS##*,mbstring,*}" ]; then
45 | echo "---------- Install mbstring ----------"
46 | docker-php-ext-install ${MC} mbstring
47 | fi
48 |
49 | if [ -z "${EXTENSIONS##*,exif,*}" ]; then
50 | echo "---------- Install exif ----------"
51 | docker-php-ext-install ${MC} exif
52 | fi
53 |
54 | if [ -z "${EXTENSIONS##*,bcmath,*}" ]; then
55 | echo "---------- Install bcmath ----------"
56 | docker-php-ext-install ${MC} bcmath
57 | fi
58 |
59 | if [ -z "${EXTENSIONS##*,calendar,*}" ]; then
60 | echo "---------- Install calendar ----------"
61 | docker-php-ext-install ${MC} calendar
62 | fi
63 |
64 | if [ -z "${EXTENSIONS##*,zend_test,*}" ]; then
65 | echo "---------- Install zend_test ----------"
66 | docker-php-ext-install ${MC} zend_test
67 | fi
68 |
69 | if [ -z "${EXTENSIONS##*,opcache,*}" ]; then
70 | echo "---------- Install opcache ----------"
71 | docker-php-ext-install opcache
72 | fi
73 |
74 | if [ -z "${EXTENSIONS##*,sockets,*}" ]; then
75 | echo "---------- Install sockets ----------"
76 | docker-php-ext-install ${MC} sockets
77 | fi
78 |
79 | if [ -z "${EXTENSIONS##*,gettext,*}" ]; then
80 | echo "---------- Install gettext ----------"
81 | docker-php-ext-install ${MC} gettext
82 | fi
83 |
84 | if [ -z "${EXTENSIONS##*,shmop,*}" ]; then
85 | echo "---------- Install shmop ----------"
86 | docker-php-ext-install ${MC} shmop
87 | fi
88 |
89 | if [ -z "${EXTENSIONS##*,sysvmsg,*}" ]; then
90 | echo "---------- Install sysvmsg ----------"
91 | docker-php-ext-install ${MC} sysvmsg
92 | fi
93 |
94 | if [ -z "${EXTENSIONS##*,sysvsem,*}" ]; then
95 | echo "---------- Install sysvsem ----------"
96 | docker-php-ext-install ${MC} sysvsem
97 | fi
98 |
99 | if [ -z "${EXTENSIONS##*,sysvshm,*}" ]; then
100 | echo "---------- Install sysvshm ----------"
101 | docker-php-ext-install ${MC} sysvshm
102 | fi
103 |
104 | if [ -z "${EXTENSIONS##*,pdo_firebird,*}" ]; then
105 | echo "---------- Install pdo_firebird ----------"
106 | docker-php-ext-install ${MC} pdo_firebird
107 | fi
108 |
109 | if [ -z "${EXTENSIONS##*,pdo_dblib,*}" ]; then
110 | echo "---------- Install pdo_dblib ----------"
111 | docker-php-ext-install ${MC} pdo_dblib
112 | fi
113 |
114 | if [ -z "${EXTENSIONS##*,pdo_oci,*}" ]; then
115 | echo "---------- Install pdo_oci ----------"
116 | docker-php-ext-install ${MC} pdo_oci
117 | fi
118 |
119 | if [ -z "${EXTENSIONS##*,pdo_odbc,*}" ]; then
120 | echo "---------- Install pdo_odbc ----------"
121 | docker-php-ext-install ${MC} pdo_odbc
122 | fi
123 |
124 | if [ -z "${EXTENSIONS##*,pdo_pgsql,*}" ]; then
125 | echo "---------- Install pdo_pgsql ----------"
126 | apk --no-cache add postgresql-dev \
127 | && docker-php-ext-install ${MC} pdo_pgsql
128 | fi
129 |
130 | if [ -z "${EXTENSIONS##*,pgsql,*}" ]; then
131 | echo "---------- Install pgsql ----------"
132 | apk --no-cache add postgresql-dev \
133 | && docker-php-ext-install ${MC} pgsql
134 | fi
135 |
136 | if [ -z "${EXTENSIONS##*,oci8,*}" ]; then
137 | echo "---------- Install oci8 ----------"
138 | docker-php-ext-install ${MC} oci8
139 | fi
140 |
141 | if [ -z "${EXTENSIONS##*,odbc,*}" ]; then
142 | echo "---------- Install odbc ----------"
143 | docker-php-ext-install ${MC} odbc
144 | fi
145 |
146 | if [ -z "${EXTENSIONS##*,dba,*}" ]; then
147 | echo "---------- Install dba ----------"
148 | docker-php-ext-install ${MC} dba
149 | fi
150 |
151 | if [ -z "${EXTENSIONS##*,interbase,*}" ]; then
152 | echo "---------- Install interbase ----------"
153 | echo "Alpine linux do not support interbase/firebird!!!"
154 | #docker-php-ext-install ${MC} interbase
155 | fi
156 |
157 | if [ -z "${EXTENSIONS##*,gd,*}" ]; then
158 | echo "---------- Install gd ----------"
159 | apk add --no-cache freetype-dev libjpeg-turbo-dev libpng-dev \
160 | && docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
161 | && docker-php-ext-install ${MC} gd
162 | fi
163 |
164 | if [ -z "${EXTENSIONS##*,intl,*}" ]; then
165 | echo "---------- Install intl ----------"
166 | apk add --no-cache icu-dev
167 | docker-php-ext-install ${MC} intl
168 | fi
169 |
170 | if [ -z "${EXTENSIONS##*,bz2,*}" ]; then
171 | echo "---------- Install bz2 ----------"
172 | apk add --no-cache bzip2-dev
173 | docker-php-ext-install ${MC} bz2
174 | fi
175 |
176 | if [ -z "${EXTENSIONS##*,soap,*}" ]; then
177 | echo "---------- Install soap ----------"
178 | docker-php-ext-install ${MC} soap
179 | fi
180 |
181 | if [ -z "${EXTENSIONS##*,xsl,*}" ]; then
182 | echo "---------- Install xsl ----------"
183 | apk add --no-cache libxslt-dev
184 | docker-php-ext-install ${MC} xsl
185 | fi
186 |
187 | if [ -z "${EXTENSIONS##*,xmlrpc,*}" ]; then
188 | echo "---------- Install xmlrpc ----------"
189 | apk add --no-cache libxslt-dev
190 | docker-php-ext-install ${MC} xmlrpc
191 | fi
192 |
193 | if [ -z "${EXTENSIONS##*,wddx,*}" ]; then
194 | echo "---------- Install wddx ----------"
195 | apk add --no-cache libxslt-dev
196 | docker-php-ext-install ${MC} wddx
197 | fi
198 |
199 | if [ -z "${EXTENSIONS##*,curl,*}" ]; then
200 | echo "---------- Install curl ----------"
201 | docker-php-ext-install ${MC} curl
202 | fi
203 |
204 | if [ -z "${EXTENSIONS##*,readline,*}" ]; then
205 | echo "---------- Install readline ----------"
206 | apk add --no-cache readline-dev
207 | apk add --no-cache libedit-dev
208 | docker-php-ext-install ${MC} readline
209 | fi
210 |
211 | if [ -z "${EXTENSIONS##*,snmp,*}" ]; then
212 | echo "---------- Install snmp ----------"
213 | apk add --no-cache net-snmp-dev
214 | docker-php-ext-install ${MC} snmp
215 | fi
216 |
217 | if [ -z "${EXTENSIONS##*,pspell,*}" ]; then
218 | echo "---------- Install pspell ----------"
219 | apk add --no-cache aspell-dev
220 | apk add --no-cache aspell-en
221 | docker-php-ext-install ${MC} pspell
222 | fi
223 |
224 | if [ -z "${EXTENSIONS##*,recode,*}" ]; then
225 | echo "---------- Install recode ----------"
226 | apk add --no-cache recode-dev
227 | docker-php-ext-install ${MC} recode
228 | fi
229 |
230 | if [ -z "${EXTENSIONS##*,tidy,*}" ]; then
231 | echo "---------- Install tidy ----------"
232 | apk add --no-cache tidyhtml-dev=5.2.0-r1 --repository http://${ALPINE_REPOSITORIES}/alpine/v3.6/community
233 | docker-php-ext-install ${MC} tidy
234 | fi
235 |
236 | if [ -z "${EXTENSIONS##*,gmp,*}" ]; then
237 | echo "---------- Install gmp ----------"
238 | apk add --no-cache gmp-dev
239 | docker-php-ext-install ${MC} gmp
240 | fi
241 |
242 | if [ -z "${EXTENSIONS##*,imap,*}" ]; then
243 | echo "---------- Install imap ----------"
244 | apk add --no-cache imap-dev
245 | docker-php-ext-configure imap --with-imap --with-imap-ssl
246 | docker-php-ext-install ${MC} imap
247 | fi
248 |
249 | if [ -z "${EXTENSIONS##*,ldap,*}" ]; then
250 | echo "---------- Install ldap ----------"
251 | apk add --no-cache ldb-dev
252 | apk add --no-cache openldap-dev
253 | docker-php-ext-install ${MC} ldap
254 | fi
255 |
256 | if [ -z "${EXTENSIONS##*,imagick,*}" ]; then
257 | echo "---------- Install imagick ----------"
258 | apk add --no-cache file-dev
259 | apk add --no-cache imagemagick-dev
260 | printf "\n" | pecl install imagick-3.4.4
261 | docker-php-ext-enable imagick
262 | fi
263 |
264 |
--------------------------------------------------------------------------------
/config/lua/waf/init.lua:
--------------------------------------------------------------------------------
1 | --[[
2 | Author: seekwe
3 | Date: 2019-10-27 18:24:58
4 | Last Modified by:: seekwe
5 | Last Modified time: 2020-08-14 20:47:22
6 | --]]
7 |
8 | require 'config'
9 | local match = string.match
10 | local ngxmatch=ngx.re.match
11 | local unescape=ngx.unescape_uri
12 | local get_headers = ngx.req.get_headers
13 | local optionIsOn = function (options) return options == "on" and true or false end
14 | logpath = Logdir
15 | rulepath = RulePath
16 | UrlDeny = optionIsOn(UrlDeny)
17 | PostCheck = optionIsOn(PostMatch)
18 | CookieCheck = optionIsOn(CookieMatch)
19 | WhiteCheck = optionIsOn(WhiteModule)
20 | WhiteHostCheck = optionIsOn(WhiteHostModule)
21 | PathInfoFix = optionIsOn(PathInfoFix)
22 | Attacklog = optionIsOn(Attacklog)
23 | CCDeny = optionIsOn(CCDeny)
24 | Redirect=optionIsOn(Redirect)
25 | function getClientIp()
26 | IP = ngx.req.get_headers()["X-Real-IP"]
27 | if IP == nil then
28 | IP = ngx.var.remote_addr
29 | end
30 | if IP == nil then
31 | IP = "unknown"
32 | end
33 | return IP
34 | end
35 | function write(logfile,msg)
36 | local fd = io.open(logfile,"ab")
37 | if fd == nil then return end
38 | fd:write(msg)
39 | fd:flush()
40 | fd:close()
41 | end
42 | function log(method,url,data,ruletag)
43 | if Attacklog then
44 | local realIp = getClientIp()
45 | local ua = ngx.var.http_user_agent
46 | local servername=ngx.var.server_name
47 | local time=ngx.localtime()
48 | if ua then
49 | line = realIp.." ["..time.."] \""..method.." "..servername..url.."\" \""..data.."\" \""..ua.."\" \""..ruletag.."\"\n"
50 | else
51 | line = realIp.." ["..time.."] \""..method.." "..servername..url.."\" \""..data.."\" - \""..ruletag.."\"\n"
52 | end
53 | local filename = logpath..'/waf_'..servername.."_"..ngx.today().."_sec.log"
54 | write(filename,line)
55 | end
56 | end
57 |
58 | function ipToDecimal(ckip)
59 | local n = 4
60 | local decimalNum = 0
61 | local pos = 0
62 | for s, e in function() return string.find(ckip, '.', pos, true) end do
63 | n = n - 1
64 | decimalNum = decimalNum + string.sub(ckip, pos, s-1) * (256 ^ n)
65 | pos = e + 1
66 | if n == 1 then decimalNum = decimalNum + string.sub(ckip, pos, string.len(ckip)) end
67 | end
68 | return decimalNum
69 | end
70 | ------------------------------------规则读取函数-------------------------------------------------------------------
71 | function read_rule(var)
72 | file = io.open(rulepath..'/'..var,"r")
73 | if file==nil then
74 | local info = debug.getinfo(1, "S")
75 | local path = info.source
76 | path = string.sub(path, 2, -1)
77 | path = string.match(path, "^.*/")
78 | file = io.open(path..rulepath..'/'..var,"r")
79 | if file==nil then
80 | return
81 | end
82 | end
83 | t = {}
84 | for line in file:lines() do
85 | table.insert(t,line)
86 | end
87 | file:close()
88 | return(t)
89 | end
90 |
91 | urlrules=read_rule('url')
92 | argsrules=read_rule('args')
93 | uarules=read_rule('user-agent')
94 | whiteuarules=read_rule('white-user-agent')
95 | wturlrules=read_rule('whiteurl')
96 | postrules=read_rule('post')
97 | ckrules=read_rule('cookie')
98 |
99 | function say_html()
100 | if Redirect then
101 | ngx.header.content_type = "text/html;charset=utf8"
102 | ngx.say(Html)
103 | ngx.exit(200)
104 | end
105 | end
106 |
107 | function whiteurl()
108 | if WhiteCheck then
109 | if wturlrules ~=nil then
110 | for _,rule in pairs(wturlrules) do
111 | if ngxmatch(ngx.var.request_uri,rule,"isjo") then
112 | return true
113 | end
114 | end
115 | end
116 | end
117 | return false
118 | end
119 |
120 | function whitehost()
121 | if WhiteHostCheck then
122 | local items = Set(HostWhiteList)
123 | for host in pairs(items) do
124 | if ngxmatch(ngx.var.host, host, "isjo") then
125 | log('POST',ngx.var.request_uri,"-","white host".. host)
126 | return true
127 | end
128 | end
129 | end
130 | return false
131 | end
132 |
133 | function args()
134 | for _,rule in pairs(argsrules) do
135 | local args = ngx.req.get_uri_args()
136 | for key, val in pairs(args) do
137 | if type(val)=='table' then
138 | if val == false then
139 | data=table.concat(val, " ")
140 | end
141 | else
142 | data=val
143 | end
144 | if data and type(data) ~= "boolean" and rule ~="" and ngxmatch(unescape(data),rule,"isjo") then
145 | log('GET',ngx.var.request_uri,"-",rule)
146 | say_html()
147 | return true
148 | end
149 | end
150 | end
151 | return false
152 | end
153 |
154 | function url()
155 | if UrlDeny then
156 | for _,rule in pairs(urlrules) do
157 | if rule ~="" and ngxmatch(ngx.var.request_uri,rule,"isjo") then
158 | log('GET',ngx.var.request_uri,"-",rule)
159 | say_html()
160 | return true
161 | end
162 | end
163 | end
164 | return false
165 | end
166 |
167 | function ua()
168 | local ua = ngx.var.http_user_agent
169 | if ua ~= nil then
170 | for _,rule in pairs(uarules) do
171 | if rule ~="" and ngxmatch(ua,rule,"isjo") then
172 | log('UA',ngx.var.request_uri,"-",rule)
173 | say_html()
174 | return true
175 | end
176 | end
177 | end
178 | return false
179 | end
180 |
181 | function body(data)
182 | for _,rule in pairs(postrules) do
183 | if rule ~="" and data~="" and ngxmatch(unescape(data),rule,"isjo") then
184 | log('POST',ngx.var.request_uri,data,rule)
185 | say_html()
186 | return true
187 | end
188 | end
189 | return false
190 | end
191 |
192 | function cookie()
193 | local ck = ngx.var.http_cookie
194 | if CookieCheck and ck then
195 | for _,rule in pairs(ckrules) do
196 | if rule ~="" and ngxmatch(ck,rule,"isjo") then
197 | log('Cookie',ngx.var.request_uri,"-",rule)
198 | say_html()
199 | return true
200 | end
201 | end
202 | end
203 | return false
204 | end
205 |
206 | function denycc()
207 | if CCDeny then
208 | local uri=ngx.var.uri
209 | CCcount=tonumber(string.match(CCrate,'(.*)/'))
210 | CCseconds=tonumber(string.match(CCrate,'/(.*)'))
211 | local token = getClientIp()..uri
212 | local limit = ngx.shared.limit
213 | local req,_=limit:get(token)
214 | if req then
215 | if req >= CCcount then
216 | ngx.exit(503)
217 | return true
218 | else
219 | limit:incr(token,1)
220 | end
221 | else
222 | limit:set(token,1,CCseconds)
223 | end
224 | end
225 | return false
226 | end
227 |
228 | function whiteua()
229 | local ua = ngx.var.http_user_agent
230 | if ua ~= nil then
231 | for _,rule in pairs(whiteuarules) do
232 | if rule ~="" and ngxmatch(ua,rule,"isjo") then
233 | return true
234 | end
235 | end
236 | end
237 | return false
238 | end
239 |
240 | function get_boundary()
241 | local header = get_headers()["content-type"]
242 | if not header then
243 | return nil
244 | end
245 |
246 | if type(header) == "table" then
247 | header = header[1]
248 | end
249 |
250 | local m = match(header, ";%s*boundary=\"([^\"]+)\"")
251 | if m then
252 | return m
253 | end
254 |
255 | return match(header, ";%s*boundary=([^\",;]+)")
256 | end
257 |
258 | function blockip()
259 | if next(IpBlocklist) ~= nil then
260 | local cIP = getClientIp()
261 | local numIP = 0
262 | if cIP ~= "unknown" then numIP = tonumber(ipToDecimal(cIP)) end
263 | for _,ip in pairs(IpBlocklist) do
264 | local s, e = string.find(ip, '-', 0, true)
265 | if s == nil and cIP == ip then
266 | ngx.exit(403)
267 | return true
268 | elseif s ~= nil then
269 | sIP = tonumber(ipToDecimal(string.sub(ip, 0, s - 1)))
270 | eIP = tonumber(ipToDecimal(string.sub(ip, e + 1, string.len(ip))))
271 | if numIP >= sIP and numIP <= eIP then
272 | ngx.exit(403)
273 | return true
274 | end
275 | end
276 | end
277 | end
278 | return false
279 | end
280 |
281 | function fileExtCheck(ext)
282 | local items = Set(BlackFileExt)
283 | ext=string.lower(ext)
284 | if ext then
285 | for rule in pairs(items) do
286 | if ngx.re.match(ext,rule,"isjo") then
287 | log('POST',ngx.var.request_uri,"-","file attack with ext "..ext)
288 | say_html()
289 | end
290 | end
291 | end
292 | return false
293 | end
294 | function Set (list)
295 | local set = {}
296 | for _, l in ipairs(list) do set[l] = true end
297 | return set
298 | end
299 |
300 | function whiteip()
301 | if next(IpWhitelist) ~= nil then
302 | local cIP = getClientIp()
303 | local numIP = 0
304 | if cIP ~= "unknown" then numIP = tonumber(ipToDecimal(cIP)) end
305 | for _,ip in pairs(IpWhitelist) do
306 | local s, e = string.find(ip, '-', 0, true)
307 | if s == nil and cIP == ip then
308 | return true
309 | elseif s ~= nil then
310 | sIP = tonumber(ipToDecimal(string.sub(ip, 0, s - 1)))
311 | eIP = tonumber(ipToDecimal(string.sub(ip, e + 1, string.len(ip))))
312 | if numIP >= sIP and numIP <= eIP then
313 | return true
314 | end
315 | end
316 | end
317 | end
318 | return false
319 | end
320 |
321 |
322 |
323 |
324 |
--------------------------------------------------------------------------------
/docker-compose.yml.example:
--------------------------------------------------------------------------------
1 | version: "3"
2 |
3 | networks:
4 | defNetworks:
5 | driver: bridge
6 | ipam:
7 | config:
8 | - subnet: 172.0.0.0/24
9 |
10 | services:
11 | ### ubuntu ##########
12 | ubuntu:
13 | build:
14 | context: ./config/ubuntu/
15 | args:
16 | UBUNTU_IMAGES: ${UBUNTU_IMAGES}
17 | network_mode: host
18 | command: tail -F /dev/null
19 | volumes:
20 | - ${SOURCE_DIR}:/var/www/html/:rw
21 |
22 | ### node ##########
23 | node:
24 | build:
25 | context: ./config/node/
26 | args:
27 | NODE_IMAGES: ${NODE_IMAGES}
28 | environment:
29 | TZ: Asia/Shanghai
30 | volumes:
31 | - ${SOURCE_DIR}:/var/www/html/:rw
32 | networks:
33 | - defNetworks
34 |
35 | ### go ##########
36 | go:
37 | build:
38 | context: ./config/golang/
39 | args:
40 | GO_IMAGES: ${GO_IMAGES}
41 | volumes:
42 | - ${SOURCE_DIR}:/var/www/html/:rw
43 | environment:
44 | TZ: Asia/Shanghai
45 | networks:
46 | - defNetworks
47 |
48 | ### nginx ##########
49 | nginx:
50 | build:
51 | context: ./config/nginx/
52 | args:
53 | NGINX_IMAGES: ${NGINX_IMAGES}
54 | ports:
55 | - "${NGINX_HTTP_HOST_PORT}:80"
56 | - "${NGINX_HTTPS_HOST_PORT}:443"
57 | volumes:
58 | - ${SOURCE_DIR}:/var/www/html/:rw
59 | - ${NGINX_LOG_DIR}:/var/log/nginx/:rw
60 | - ${NGINX_CONFD_DIR}:/etc/nginx/conf.d/:rw
61 | - ${LUA_DIR}:/usr/local/openresty/nginx/conf/lua:rw
62 | - ${NGINX_CONF_FILE}:/etc/nginx/nginx.conf:ro
63 | - ${NGINX_CONF_FILE}:/usr/local/openresty/nginx/conf/nginx.conf:ro
64 | restart: on-failure
65 | depends_on:
66 | - php
67 | environment:
68 | MYSQL_ROOT_PASSWORD: "${MYSQL_ROOT_PASSWORD}"
69 | REDIS_PASSWORD: "${REDIS_PASSWORD}"
70 | TZ: Asia/Shanghai
71 | networks:
72 | defNetworks:
73 | ipv4_address: 172.0.0.10
74 |
75 | ### caddy ##########
76 | caddy:
77 | build:
78 | context: ./config/caddy/
79 | args:
80 | CADDY_IMAGES: ${CADDY_IMAGES}
81 | ports:
82 | - "${CADDY_HTTP_HOST_PORT}:80"
83 | - "${CADDY_HTTPS_HOST_PORT}:443"
84 | volumes:
85 | - ${SOURCE_DIR}:/var/www/html/:rw
86 | - ${CADDY_CONF_DIR}/Caddyfile:/etc/caddy/Caddyfile:rw
87 | - ${CADDY_CONF_DIR}/vhosts:/etc/caddy/vhosts:rw
88 | - ${CADDY_SSL_DIR}:/data/caddy/certificates/:rw
89 | - ${CADDY_LOG_DIR}:/tmp/caddylog:rw
90 | restart: on-failure
91 | depends_on:
92 | - php
93 | environment:
94 | MYSQL_ROOT_PASSWORD: "${MYSQL_ROOT_PASSWORD}"
95 | REDIS_PASSWORD: "${REDIS_PASSWORD}"
96 | TZ: Asia/Shanghai
97 | DNSPOD_TOKEN: "id,token"
98 | networks:
99 | defNetworks:
100 | ipv4_address: 172.0.0.11
101 |
102 | ### php ##########
103 | php:
104 | build:
105 | context: ./config/php/
106 | args:
107 | PHP_IMAGES: ${PHP_IMAGES}
108 | ALPINE_REPOSITORIES: ${ALPINE_REPOSITORIES}
109 | PHP_EXTENSIONS: ${PHP_EXTENSIONS}
110 | COMPOSER_VERSION: ${COMPOSER_VERSION}
111 | COMPOSER_PACKAGIST: ${COMPOSER_PACKAGIST}
112 | MORE_EXTENSION_INSTALLER: php.sh
113 | volumes:
114 | - ${SOURCE_DIR}:/var/www/html/:rw
115 | - ${PHP_PHP_CONF_FILE}:/usr/local/etc/php/php.ini:ro
116 | - ${PHP_FPM_CONF_FILE}:/usr/local/etc/php-fpm.d/www.conf:rw
117 | - ${PHP_LOG_DIR}:/var/log/php
118 | - ${COMPOSER_DATA_DIR}:/composer:rw
119 | - ${NGINX_CONFD_DIR}:/etc/nginx/conf.d/:rw
120 | restart: on-failure
121 | environment:
122 | MYSQL_ROOT_PASSWORD: "${MYSQL_ROOT_PASSWORD}"
123 | REDIS_PASSWORD: "${REDIS_PASSWORD}"
124 | TZ: Asia/Shanghai
125 | cap_add:
126 | - SYS_PTRACE
127 | networks:
128 | defNetworks:
129 | ipv4_address: 172.0.0.30
130 | extra_hosts:
131 | - "nginx.docker:172.0.0.10"
132 | security_opt:
133 | - "seccomp=./config/php/seccomp.json"
134 |
135 | ### mysql ##########
136 | mysql:
137 | build:
138 | context: ./config/mysql/
139 | args:
140 | MYSQL_IMAGES: ${MYSQL_IMAGES}
141 | ports:
142 | - "${MYSQL_HOST_PORT}:3306"
143 | volumes:
144 | - ${MYSQL_CONF_FILE}:/etc/mysql/conf.d/mysql.cnf:ro
145 | - ${MYSQL_DATA_DIR}:/var/lib/mysql/:rw
146 | - ${MYSQL_CONF_DIR}:/mysql/:rw
147 | restart: on-failure
148 | networks:
149 | defNetworks:
150 | ipv4_address: 172.0.0.20
151 | environment:
152 | MYSQL_ROOT_PASSWORD: "${MYSQL_ROOT_PASSWORD}"
153 | MYSQL_DATABASE: "${MYSQL_DATABASE}"
154 | TZ: Asia/Shanghai
155 |
156 | ### redis ##########
157 | redis:
158 | build:
159 | context: ./config/redis/
160 | args:
161 | REDIS_IMAGES: ${REDIS_IMAGES}
162 | ports:
163 | - "${REDIS_HOST_PORT}:6379"
164 | volumes:
165 | - ${REDIS_CONF_FILE}:/etc/redis.conf:ro
166 | restart: on-failure
167 | environment:
168 | TZ: Asia/Shanghai
169 | entrypoint:
170 | ["redis-server", "/etc/redis.conf", "--requirepass", "${REDIS_PASSWORD}"]
171 | networks:
172 | defNetworks:
173 | ipv4_address: 172.0.0.40
174 |
175 | ### mongodb ##########
176 | mongodb:
177 | build:
178 | context: ./config/mongodb/
179 | args:
180 | MONGODB_IMAGES: ${MONGODB_IMAGES}
181 | environment:
182 | MONGO_INITDB_ROOT_USERNAME: "${MONGODB_INITDB_ROOT_USERNAME}"
183 | MONGO_INITDB_ROOT_PASSWORD: "${MONGODB_INITDB_ROOT_PASSWORD}"
184 | TZ: Asia/Shanghai
185 | volumes:
186 | - ${MONGODB_DATA_DIR}/data:/data/db:rw
187 | - ./config/mongodb/backup:/backup:rw
188 | # 配置集群
189 | # openssl rand -base64 128 > ./data/mongo/keyFile && sudo chmod 600 ./data/mongo/keyFile && sudo chown 999:999 ./data/mongo/keyFile
190 | # mongo -u root -p 73zls666 --authenticationDatabase admin
191 | # rs.initiate({_id:"rs0", members:[{_id:0, host:"x.x.x.x:27017"}]})
192 | # rs.add("x.x.x.x:27017")
193 | # - ${MONGODB_DATA_DIR}/keyFile:/data/mongodb/keyFile:r
194 | # command: --auth --replSet rs0 --keyFile /data/mongodb/keyFile
195 | command: --auth
196 | ports:
197 | - "${MONGODB_HOST_PORT}:27017"
198 | networks:
199 | - defNetworks
200 |
201 | ### sentry ##########
202 | sentry:
203 | image: ${SENTRY_IMAGES}
204 | depends_on:
205 | - redis
206 | - postgres
207 | - sentry_celery_beat
208 | - sentry_celery_worker
209 | ports:
210 | - ${SENTRY_PORT}:9000
211 | environment:
212 | SENTRY_SECRET_KEY: "${SENTRY_SECRET_KEY}"
213 | SENTRY_REDIS_HOST: "redis"
214 | SENTRY_POSTGRES_HOST: "postgres"
215 | SENTRY_DB_USER: "${POSTGRES_USER}"
216 | SENTRY_DB_PASSWORD: "${POSTGRES_PASSWORD}"
217 | TZ: Asia/Shanghai
218 | cap_add:
219 | - SYS_PTRACE
220 | networks:
221 | - defNetworks
222 |
223 | sentry_celery_beat:
224 | image: ${SENTRY_IMAGES}
225 | depends_on:
226 | - redis
227 | - postgres
228 | command: "sentry run cron"
229 | environment:
230 | SENTRY_SECRET_KEY: "${SENTRY_SECRET_KEY}"
231 | SENTRY_REDIS_HOST: "redis"
232 | SENTRY_POSTGRES_HOST: "postgres"
233 | SENTRY_DB_USER: "${POSTGRES_USER}"
234 | SENTRY_DB_PASSWORD: "${POSTGRES_PASSWORD}"
235 | cap_add:
236 | - SYS_PTRACE
237 | networks:
238 | - defNetworks
239 |
240 | sentry_celery_worker:
241 | image: ${SENTRY_IMAGES}
242 | depends_on:
243 | - redis
244 | - postgres
245 | links:
246 | - redis
247 | - postgres
248 | command: "sentry run worker"
249 | environment:
250 | SENTRY_SECRET_KEY: "${SENTRY_SECRET_KEY}"
251 | SENTRY_REDIS_HOST: "redis"
252 | SENTRY_POSTGRES_HOST: "postgres"
253 | SENTRY_DB_USER: "${POSTGRES_USER}"
254 | SENTRY_DB_PASSWORD: "${POSTGRES_PASSWORD}"
255 | cap_add:
256 | - SYS_PTRACE
257 | networks:
258 | - defNetworks
259 |
260 | ### postgres ##########
261 | postgres:
262 | build:
263 | context: ./config/postgres
264 | args:
265 | POSTGRES_IMAGES: ${POSTGRES_IMAGES}
266 | ports:
267 | - "${POSTGRES_PORT}:5432"
268 | volumes:
269 | - ${POSTGRES_DATA_DIR}:/var/lib/postgresql/data:rw
270 | restart: on-failure
271 | environment:
272 | POSTGRES_DB: "${POSTGRES_DB}"
273 | POSTGRES_USER: "${POSTGRES_USER}"
274 | POSTGRES_PASSWORD: "${POSTGRES_PASSWORD}"
275 | #PGDATA: /tmp
276 | TZ: Asia/Shanghai
277 | networks:
278 | - defNetworks
279 |
280 | ### portainer ##########
281 | portainer:
282 | image: ${PORTAINER_IMAGES}
283 | command: -H unix:///var/run/docker.sock
284 | restart: on-failure
285 | ports:
286 | - "${PORTAINER_HOST_PORT}:9000"
287 | environment:
288 | TZ: Asia/Shanghai
289 | volumes:
290 | - /var/run/docker.sock:/var/run/docker.sock
291 | - ${PORTAINER_DATA_DIR}:/data
292 |
293 | ### yapi ##########
294 | yapi:
295 | build:
296 | context: ./config/yapi/
297 | args:
298 | YAPI_VERSION: ${YAPI_VERSION}
299 | YAPI_HOME: ${YAPI_HOME}
300 | YAPI_HOST_PORT: ${YAPI_HOST_PORT}
301 | NODE_IMAGES: ${NODE_IMAGES}
302 | restart: on-failure
303 | environment:
304 | TZ: Asia/Shanghai
305 | ports:
306 | - "${YAPI_HOST_PORT}:8005"
307 | #- "9090:9090"
308 | volumes:
309 | - ${YAPI_CONFIG_FILE}:/home/vendors/config.json:rw
310 | - ${YAPI_CONFIG_FILE}:/home/config.json:rw
311 | - ${YAPI_LOG_DIR}:/home/log
312 | depends_on:
313 | - mongodb
314 | cap_add:
315 | - SYS_PTRACE
316 | networks:
317 | - defNetworks
318 |
319 | ### drone ##########
320 | # 配置文档 https://docs.drone.io/server/overview/
321 | drone:
322 | image: drone/drone:2
323 | volumes:
324 | - ./data/drone:/var/lib/drone/
325 | - /var/run/docker.sock:/var/run/docker.sock
326 | environment:
327 | # 使用 gitlab,应用回调地址 {DRONE_SERVER_HOST}/login
328 | - DRONE_GITLAB=true
329 | - DRONE_GITLAB_CLIENT_ID=xxx
330 | - DRONE_GITLAB_CLIENT_SECRET=xxx
331 | - DRONE_GITLAB_SERVER=http://gitlab.xxx.com
332 | - DRONE_GITLAB_SKIP_VERIFY=true
333 | # 建议设置指定分组或用户,逗号分隔
334 | # - DRONE_USER_FILTER=
335 | # 输出日志
336 | - DRONE_LOGS_DEBUG=true
337 | - DRONE_OPEN=true
338 | # 访问域名或 IP
339 | - DRONE_SERVER_HOST=drone.xxx.com
340 | # https 还是 http
341 | - DRONE_SERVER_PROTO=https
342 | # Drone Server 和 Agent 的通信密钥,一个随机的长字符串
343 | - DRONE_RPC_SECRET=QWASFGTTG767TU4345435
344 | - DRONE_AGENTS_ENABLED=true
345 | networks:
346 | defNetworks:
347 | ipv4_address: 172.0.0.11
348 | depends_on:
349 | - drone-runner
350 |
351 | drone-runner:
352 | image: drone/drone-runner-docker:1.8
353 | volumes:
354 | - /var/run/docker.sock:/var/run/docker.sock
355 | environment:
356 | - DRONE_RPC_PROTO=http
357 | - DRONE_RPC_HOST=drone
358 | - DRONE_RPC_SECRET=QWASFGTTG767TU4345435
359 | - DRONE_RUNNER_CAPACITY=2
360 | - DRONE_RUNNER_NAME=drone-runner
361 | networks:
362 | - defNetworks
363 |
364 | ### monitor ##########
365 | grafana:
366 | image: ${GRAFANA_IMAGES}
367 | restart: on-failure
368 | ports:
369 | - "${GRAFANA_PORT}:3000"
370 | environment:
371 | TZ: Asia/Shanghai
372 | GF_SECURITY_ADMIN_PASSWORD: ${GRAFANA_PASSWORD}
373 | networks:
374 | - defNetworks
375 | depends_on:
376 | - prometheus
377 | - mysqlexporter
378 | volumes:
379 | - ${GRAFANA_CONFIG_FILE}:/etc/grafana/grafana.ini:ro
380 | - ${GRAFANA_LOG_DIR}:/var/log/grafana:rw
381 | - ${GRAFANA_DATA_DIR}:/var/lib/grafana:rw
382 | prometheus:
383 | image: ${PROM_IMAGES}
384 | restart: on-failure
385 | command:
386 | - "--config.file=/etc/prometheus/prometheus.yml"
387 | - "--storage.tsdb.path=/prometheus"
388 | environment:
389 | TZ: Asia/Shanghai
390 | networks:
391 | - defNetworks
392 | ports:
393 | - "${PROM_PORT}:9090"
394 | volumes:
395 | - ${PROM_CONFIG_FILE}:/etc/prometheus/prometheus.yml
396 | - ${PROM_DATA_DIR}:/prometheus
397 | mysqlexporter:
398 | image: prom/mysqld-exporter:v0.12.1
399 | networks:
400 | - defNetworks
401 | environment:
402 | - DATA_SOURCE_NAME=root:${MYSQL_ROOT_PASSWORD}@(mysql:3306)/
403 | nodeexporter:
404 | image: prom/node-exporter:v1.0.1
405 | command:
406 | - "--path.rootfs=/host"
407 | networks:
408 | - defNetworks
409 | volumes:
410 | - "/:/host:ro,rslave"
411 |
--------------------------------------------------------------------------------
/config/php/seccomp.json:
--------------------------------------------------------------------------------
1 | {
2 | "defaultAction": "SCMP_ACT_ERRNO",
3 | "archMap": [
4 | {
5 | "architecture": "SCMP_ARCH_X86_64",
6 | "subArchitectures": [
7 | "SCMP_ARCH_X86",
8 | "SCMP_ARCH_X32"
9 | ]
10 | },
11 | {
12 | "architecture": "SCMP_ARCH_AARCH64",
13 | "subArchitectures": [
14 | "SCMP_ARCH_ARM"
15 | ]
16 | },
17 | {
18 | "architecture": "SCMP_ARCH_MIPS64",
19 | "subArchitectures": [
20 | "SCMP_ARCH_MIPS",
21 | "SCMP_ARCH_MIPS64N32"
22 | ]
23 | },
24 | {
25 | "architecture": "SCMP_ARCH_MIPS64N32",
26 | "subArchitectures": [
27 | "SCMP_ARCH_MIPS",
28 | "SCMP_ARCH_MIPS64"
29 | ]
30 | },
31 | {
32 | "architecture": "SCMP_ARCH_MIPSEL64",
33 | "subArchitectures": [
34 | "SCMP_ARCH_MIPSEL",
35 | "SCMP_ARCH_MIPSEL64N32"
36 | ]
37 | },
38 | {
39 | "architecture": "SCMP_ARCH_MIPSEL64N32",
40 | "subArchitectures": [
41 | "SCMP_ARCH_MIPSEL",
42 | "SCMP_ARCH_MIPSEL64"
43 | ]
44 | },
45 | {
46 | "architecture": "SCMP_ARCH_S390X",
47 | "subArchitectures": [
48 | "SCMP_ARCH_S390"
49 | ]
50 | }
51 | ],
52 | "syscalls": [
53 | {
54 | "names": [
55 | "accept",
56 | "accept4",
57 | "access",
58 | "adjtimex",
59 | "alarm",
60 | "bind",
61 | "brk",
62 | "capget",
63 | "capset",
64 | "chdir",
65 | "chmod",
66 | "chown",
67 | "chown32",
68 | "clock_getres",
69 | "clock_gettime",
70 | "clock_nanosleep",
71 | "close",
72 | "connect",
73 | "copy_file_range",
74 | "creat",
75 | "dup",
76 | "dup2",
77 | "dup3",
78 | "epoll_create",
79 | "epoll_create1",
80 | "epoll_ctl",
81 | "epoll_ctl_old",
82 | "epoll_pwait",
83 | "epoll_wait",
84 | "epoll_wait_old",
85 | "eventfd",
86 | "eventfd2",
87 | "execve",
88 | "execveat",
89 | "exit",
90 | "exit_group",
91 | "faccessat",
92 | "fadvise64",
93 | "fadvise64_64",
94 | "fallocate",
95 | "fanotify_mark",
96 | "fchdir",
97 | "fchmod",
98 | "fchmodat",
99 | "fchown",
100 | "fchown32",
101 | "fchownat",
102 | "fcntl",
103 | "fcntl64",
104 | "fdatasync",
105 | "fgetxattr",
106 | "flistxattr",
107 | "flock",
108 | "fork",
109 | "fremovexattr",
110 | "fsetxattr",
111 | "fstat",
112 | "fstat64",
113 | "fstatat64",
114 | "fstatfs",
115 | "fstatfs64",
116 | "fsync",
117 | "ftruncate",
118 | "ftruncate64",
119 | "futex",
120 | "futimesat",
121 | "getcpu",
122 | "getcwd",
123 | "getdents",
124 | "getdents64",
125 | "getegid",
126 | "getegid32",
127 | "geteuid",
128 | "geteuid32",
129 | "getgid",
130 | "getgid32",
131 | "getgroups",
132 | "getgroups32",
133 | "getitimer",
134 | "getpeername",
135 | "getpgid",
136 | "getpgrp",
137 | "getpid",
138 | "getppid",
139 | "getpriority",
140 | "getrandom",
141 | "getresgid",
142 | "getresgid32",
143 | "getresuid",
144 | "getresuid32",
145 | "getrlimit",
146 | "get_robust_list",
147 | "getrusage",
148 | "getsid",
149 | "getsockname",
150 | "getsockopt",
151 | "get_thread_area",
152 | "gettid",
153 | "gettimeofday",
154 | "getuid",
155 | "getuid32",
156 | "getxattr",
157 | "inotify_add_watch",
158 | "inotify_init",
159 | "inotify_init1",
160 | "inotify_rm_watch",
161 | "io_cancel",
162 | "ioctl",
163 | "io_destroy",
164 | "io_getevents",
165 | "io_pgetevents",
166 | "ioprio_get",
167 | "ioprio_set",
168 | "io_setup",
169 | "io_submit",
170 | "io_uring_enter",
171 | "io_uring_register",
172 | "io_uring_setup",
173 | "ipc",
174 | "kill",
175 | "lchown",
176 | "lchown32",
177 | "lgetxattr",
178 | "link",
179 | "linkat",
180 | "listen",
181 | "listxattr",
182 | "llistxattr",
183 | "_llseek",
184 | "lremovexattr",
185 | "lseek",
186 | "lsetxattr",
187 | "lstat",
188 | "lstat64",
189 | "madvise",
190 | "memfd_create",
191 | "mincore",
192 | "mkdir",
193 | "mkdirat",
194 | "mknod",
195 | "mknodat",
196 | "mlock",
197 | "mlock2",
198 | "mlockall",
199 | "mmap",
200 | "mmap2",
201 | "mprotect",
202 | "mq_getsetattr",
203 | "mq_notify",
204 | "mq_open",
205 | "mq_timedreceive",
206 | "mq_timedsend",
207 | "mq_unlink",
208 | "mremap",
209 | "msgctl",
210 | "msgget",
211 | "msgrcv",
212 | "msgsnd",
213 | "msync",
214 | "munlock",
215 | "munlockall",
216 | "munmap",
217 | "nanosleep",
218 | "newfstatat",
219 | "_newselect",
220 | "open",
221 | "openat",
222 | "pause",
223 | "pipe",
224 | "pipe2",
225 | "poll",
226 | "ppoll",
227 | "prctl",
228 | "pread64",
229 | "preadv",
230 | "preadv2",
231 | "prlimit64",
232 | "pselect6",
233 | "pwrite64",
234 | "pwritev",
235 | "pwritev2",
236 | "read",
237 | "readahead",
238 | "readlink",
239 | "readlinkat",
240 | "readv",
241 | "recv",
242 | "recvfrom",
243 | "recvmmsg",
244 | "recvmsg",
245 | "remap_file_pages",
246 | "removexattr",
247 | "rename",
248 | "renameat",
249 | "renameat2",
250 | "restart_syscall",
251 | "rmdir",
252 | "rt_sigaction",
253 | "rt_sigpending",
254 | "rt_sigprocmask",
255 | "rt_sigqueueinfo",
256 | "rt_sigreturn",
257 | "rt_sigsuspend",
258 | "rt_sigtimedwait",
259 | "rt_tgsigqueueinfo",
260 | "sched_getaffinity",
261 | "sched_getattr",
262 | "sched_getparam",
263 | "sched_get_priority_max",
264 | "sched_get_priority_min",
265 | "sched_getscheduler",
266 | "sched_rr_get_interval",
267 | "sched_setaffinity",
268 | "sched_setattr",
269 | "sched_setparam",
270 | "sched_setscheduler",
271 | "sched_yield",
272 | "seccomp",
273 | "select",
274 | "semctl",
275 | "semget",
276 | "semop",
277 | "semtimedop",
278 | "send",
279 | "sendfile",
280 | "sendfile64",
281 | "sendmmsg",
282 | "sendmsg",
283 | "sendto",
284 | "setfsgid",
285 | "setfsgid32",
286 | "setfsuid",
287 | "setfsuid32",
288 | "setgid",
289 | "setgid32",
290 | "setgroups",
291 | "setgroups32",
292 | "setitimer",
293 | "setpgid",
294 | "setpriority",
295 | "setregid",
296 | "setregid32",
297 | "setresgid",
298 | "setresgid32",
299 | "setresuid",
300 | "setresuid32",
301 | "setreuid",
302 | "setreuid32",
303 | "setrlimit",
304 | "set_robust_list",
305 | "setsid",
306 | "setsockopt",
307 | "set_thread_area",
308 | "set_tid_address",
309 | "setuid",
310 | "setuid32",
311 | "setxattr",
312 | "shmat",
313 | "shmctl",
314 | "shmdt",
315 | "shmget",
316 | "shutdown",
317 | "sigaltstack",
318 | "signalfd",
319 | "signalfd4",
320 | "sigprocmask",
321 | "sigreturn",
322 | "socket",
323 | "socketcall",
324 | "socketpair",
325 | "splice",
326 | "stat",
327 | "stat64",
328 | "statfs",
329 | "statfs64",
330 | "statx",
331 | "symlink",
332 | "symlinkat",
333 | "sync",
334 | "sync_file_range",
335 | "syncfs",
336 | "sysinfo",
337 | "tee",
338 | "tgkill",
339 | "time",
340 | "timer_create",
341 | "timer_delete",
342 | "timerfd_create",
343 | "timerfd_gettime",
344 | "timerfd_settime",
345 | "timer_getoverrun",
346 | "timer_gettime",
347 | "timer_settime",
348 | "times",
349 | "tkill",
350 | "truncate",
351 | "truncate64",
352 | "ugetrlimit",
353 | "umask",
354 | "uname",
355 | "unlink",
356 | "unlinkat",
357 | "utime",
358 | "utimensat",
359 | "utimes",
360 | "vfork",
361 | "vmsplice",
362 | "wait4",
363 | "waitid",
364 | "waitpid",
365 | "write",
366 | "writev",
367 | "ptrace"
368 | ],
369 | "action": "SCMP_ACT_ALLOW",
370 | "args": [],
371 | "comment": "",
372 | "includes": {},
373 | "excludes": {}
374 | },
375 | {
376 | "names": [
377 | "ptrace"
378 | ],
379 | "action": "SCMP_ACT_ALLOW",
380 | "args": null,
381 | "comment": "",
382 | "includes": {
383 | "minKernel": "4.8"
384 | },
385 | "excludes": {}
386 | },
387 | {
388 | "names": [
389 | "personality"
390 | ],
391 | "action": "SCMP_ACT_ALLOW",
392 | "args": [
393 | {
394 | "index": 0,
395 | "value": 0,
396 | "valueTwo": 0,
397 | "op": "SCMP_CMP_EQ"
398 | }
399 | ],
400 | "comment": "",
401 | "includes": {},
402 | "excludes": {}
403 | },
404 | {
405 | "names": [
406 | "personality"
407 | ],
408 | "action": "SCMP_ACT_ALLOW",
409 | "args": [
410 | {
411 | "index": 0,
412 | "value": 8,
413 | "valueTwo": 0,
414 | "op": "SCMP_CMP_EQ"
415 | }
416 | ],
417 | "comment": "",
418 | "includes": {},
419 | "excludes": {}
420 | },
421 | {
422 | "names": [
423 | "personality"
424 | ],
425 | "action": "SCMP_ACT_ALLOW",
426 | "args": [
427 | {
428 | "index": 0,
429 | "value": 131072,
430 | "valueTwo": 0,
431 | "op": "SCMP_CMP_EQ"
432 | }
433 | ],
434 | "comment": "",
435 | "includes": {},
436 | "excludes": {}
437 | },
438 | {
439 | "names": [
440 | "personality"
441 | ],
442 | "action": "SCMP_ACT_ALLOW",
443 | "args": [
444 | {
445 | "index": 0,
446 | "value": 131080,
447 | "valueTwo": 0,
448 | "op": "SCMP_CMP_EQ"
449 | }
450 | ],
451 | "comment": "",
452 | "includes": {},
453 | "excludes": {}
454 | },
455 | {
456 | "names": [
457 | "personality"
458 | ],
459 | "action": "SCMP_ACT_ALLOW",
460 | "args": [
461 | {
462 | "index": 0,
463 | "value": 4294967295,
464 | "valueTwo": 0,
465 | "op": "SCMP_CMP_EQ"
466 | }
467 | ],
468 | "comment": "",
469 | "includes": {},
470 | "excludes": {}
471 | },
472 | {
473 | "names": [
474 | "sync_file_range2"
475 | ],
476 | "action": "SCMP_ACT_ALLOW",
477 | "args": [],
478 | "comment": "",
479 | "includes": {
480 | "arches": [
481 | "ppc64le"
482 | ]
483 | },
484 | "excludes": {}
485 | },
486 | {
487 | "names": [
488 | "arm_fadvise64_64",
489 | "arm_sync_file_range",
490 | "sync_file_range2",
491 | "breakpoint",
492 | "cacheflush",
493 | "set_tls"
494 | ],
495 | "action": "SCMP_ACT_ALLOW",
496 | "args": [],
497 | "comment": "",
498 | "includes": {
499 | "arches": [
500 | "arm",
501 | "arm64"
502 | ]
503 | },
504 | "excludes": {}
505 | },
506 | {
507 | "names": [
508 | "arch_prctl"
509 | ],
510 | "action": "SCMP_ACT_ALLOW",
511 | "args": [],
512 | "comment": "",
513 | "includes": {
514 | "arches": [
515 | "amd64",
516 | "x32"
517 | ]
518 | },
519 | "excludes": {}
520 | },
521 | {
522 | "names": [
523 | "modify_ldt"
524 | ],
525 | "action": "SCMP_ACT_ALLOW",
526 | "args": [],
527 | "comment": "",
528 | "includes": {
529 | "arches": [
530 | "amd64",
531 | "x32",
532 | "x86"
533 | ]
534 | },
535 | "excludes": {}
536 | },
537 | {
538 | "names": [
539 | "s390_pci_mmio_read",
540 | "s390_pci_mmio_write",
541 | "s390_runtime_instr"
542 | ],
543 | "action": "SCMP_ACT_ALLOW",
544 | "args": [],
545 | "comment": "",
546 | "includes": {
547 | "arches": [
548 | "s390",
549 | "s390x"
550 | ]
551 | },
552 | "excludes": {}
553 | },
554 | {
555 | "names": [
556 | "open_by_handle_at"
557 | ],
558 | "action": "SCMP_ACT_ALLOW",
559 | "args": [],
560 | "comment": "",
561 | "includes": {
562 | "caps": [
563 | "CAP_DAC_READ_SEARCH"
564 | ]
565 | },
566 | "excludes": {}
567 | },
568 | {
569 | "names": [
570 | "bpf",
571 | "clone",
572 | "fanotify_init",
573 | "lookup_dcookie",
574 | "mount",
575 | "name_to_handle_at",
576 | "perf_event_open",
577 | "quotactl",
578 | "setdomainname",
579 | "sethostname",
580 | "setns",
581 | "syslog",
582 | "umount",
583 | "umount2",
584 | "unshare"
585 | ],
586 | "action": "SCMP_ACT_ALLOW",
587 | "args": [],
588 | "comment": "",
589 | "includes": {
590 | "caps": [
591 | "CAP_SYS_ADMIN"
592 | ]
593 | },
594 | "excludes": {}
595 | },
596 | {
597 | "names": [
598 | "clone"
599 | ],
600 | "action": "SCMP_ACT_ALLOW",
601 | "args": [
602 | {
603 | "index": 0,
604 | "value": 2114060288,
605 | "valueTwo": 0,
606 | "op": "SCMP_CMP_MASKED_EQ"
607 | }
608 | ],
609 | "comment": "",
610 | "includes": {},
611 | "excludes": {
612 | "caps": [
613 | "CAP_SYS_ADMIN"
614 | ],
615 | "arches": [
616 | "s390",
617 | "s390x"
618 | ]
619 | }
620 | },
621 | {
622 | "names": [
623 | "clone"
624 | ],
625 | "action": "SCMP_ACT_ALLOW",
626 | "args": [
627 | {
628 | "index": 1,
629 | "value": 2114060288,
630 | "valueTwo": 0,
631 | "op": "SCMP_CMP_MASKED_EQ"
632 | }
633 | ],
634 | "comment": "s390 parameter ordering for clone is different",
635 | "includes": {
636 | "arches": [
637 | "s390",
638 | "s390x"
639 | ]
640 | },
641 | "excludes": {
642 | "caps": [
643 | "CAP_SYS_ADMIN"
644 | ]
645 | }
646 | },
647 | {
648 | "names": [
649 | "reboot"
650 | ],
651 | "action": "SCMP_ACT_ALLOW",
652 | "args": [],
653 | "comment": "",
654 | "includes": {
655 | "caps": [
656 | "CAP_SYS_BOOT"
657 | ]
658 | },
659 | "excludes": {}
660 | },
661 | {
662 | "names": [
663 | "chroot"
664 | ],
665 | "action": "SCMP_ACT_ALLOW",
666 | "args": [],
667 | "comment": "",
668 | "includes": {
669 | "caps": [
670 | "CAP_SYS_CHROOT"
671 | ]
672 | },
673 | "excludes": {}
674 | },
675 | {
676 | "names": [
677 | "delete_module",
678 | "init_module",
679 | "finit_module",
680 | "query_module"
681 | ],
682 | "action": "SCMP_ACT_ALLOW",
683 | "args": [],
684 | "comment": "",
685 | "includes": {
686 | "caps": [
687 | "CAP_SYS_MODULE"
688 | ]
689 | },
690 | "excludes": {}
691 | },
692 | {
693 | "names": [
694 | "acct"
695 | ],
696 | "action": "SCMP_ACT_ALLOW",
697 | "args": [],
698 | "comment": "",
699 | "includes": {
700 | "caps": [
701 | "CAP_SYS_PACCT"
702 | ]
703 | },
704 | "excludes": {}
705 | },
706 | {
707 | "names": [
708 | "kcmp",
709 | "process_vm_readv",
710 | "process_vm_writev",
711 | "ptrace"
712 | ],
713 | "action": "SCMP_ACT_ALLOW",
714 | "args": [],
715 | "comment": "",
716 | "includes": {
717 | "caps": [
718 | "CAP_SYS_PTRACE"
719 | ]
720 | },
721 | "excludes": {}
722 | },
723 | {
724 | "names": [
725 | "iopl",
726 | "ioperm"
727 | ],
728 | "action": "SCMP_ACT_ALLOW",
729 | "args": [],
730 | "comment": "",
731 | "includes": {
732 | "caps": [
733 | "CAP_SYS_RAWIO"
734 | ]
735 | },
736 | "excludes": {}
737 | },
738 | {
739 | "names": [
740 | "settimeofday",
741 | "stime",
742 | "clock_settime"
743 | ],
744 | "action": "SCMP_ACT_ALLOW",
745 | "args": [],
746 | "comment": "",
747 | "includes": {
748 | "caps": [
749 | "CAP_SYS_TIME"
750 | ]
751 | },
752 | "excludes": {}
753 | },
754 | {
755 | "names": [
756 | "vhangup"
757 | ],
758 | "action": "SCMP_ACT_ALLOW",
759 | "args": [],
760 | "comment": "",
761 | "includes": {
762 | "caps": [
763 | "CAP_SYS_TTY_CONFIG"
764 | ]
765 | },
766 | "excludes": {}
767 | },
768 | {
769 | "names": [
770 | "get_mempolicy",
771 | "mbind",
772 | "set_mempolicy"
773 | ],
774 | "action": "SCMP_ACT_ALLOW",
775 | "args": [],
776 | "comment": "",
777 | "includes": {
778 | "caps": [
779 | "CAP_SYS_NICE"
780 | ]
781 | },
782 | "excludes": {}
783 | },
784 | {
785 | "names": [
786 | "syslog"
787 | ],
788 | "action": "SCMP_ACT_ALLOW",
789 | "args": [],
790 | "comment": "",
791 | "includes": {
792 | "caps": [
793 | "CAP_SYSLOG"
794 | ]
795 | },
796 | "excludes": {}
797 | }
798 | ]
799 | }
--------------------------------------------------------------------------------
/run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Service List: redis|mysql|mongodb|nginx|php|golang
4 |
5 | # Default Startup Service
6 | defaultContainer="nginx php mysql"
7 | # Default Service
8 | defaultBashContainer="php"
9 |
10 | mydir=$0
11 | _b=$(ls -ld $mydir | awk '{print $NF}')
12 | _c=$(ls -ld $mydir | awk '{print $(NF-2)}')
13 | [[ $_b =~ ^/ ]] && mydir=$_b || mydir=$(dirname $_c)/$_b
14 |
15 | WORK_DIR=$(
16 | cd $(dirname $mydir)
17 | pwd
18 | )
19 | BIN_PATH="/usr/local/bin"
20 | WORK_NAME=${WORK_DIR##*/}
21 | SCRIPT_SOURCE_DIR=$(pwd)
22 | WHOAMI=$(whoami)
23 | TIME=$(date "+%Y-%m-%d %H:%M:%S")
24 | DATE=$(date "+%Y-%m-%d")
25 | cd $WORK_DIR
26 |
27 | [[ ! $PATH =~ $BIN_PATH ]] && export PATH=$PATH:$BIN_PATH
28 |
29 | function main() {
30 | if [[ ! -d $BIN_PATH ]]; then
31 | BIN_PATH="/usr/bin"
32 | fi
33 | local cmd
34 | config
35 | judge
36 | cmd=$1
37 | if [[ "" != $1 ]] && [[ "help" != $1 ]] && [[ "node" != $1 ]] && [[ "npm" != $1 ]] && [[ "sentry" != $1 ]] && [[ "go" != $1 ]] && [[ "composer" != $1 ]]; then
38 | shift
39 | fi
40 | case "$cmd" in
41 | status | s | ps)
42 | _status $@
43 | ;;
44 | stop)
45 | _stop $@
46 | ;;
47 | buildUp | buildup)
48 | _build $@
49 | _start $@
50 | ;;
51 | restart)
52 | _restart $@
53 | ;;
54 | start | up)
55 | _start $@
56 | ;;
57 | reload)
58 | _reload $@
59 | ;;
60 | build)
61 | _build $@
62 | ;;
63 | bash)
64 | _bash $@
65 | ;;
66 | bash2)
67 | _bash2 $@
68 | ;;
69 | cron)
70 | _cron $@
71 | ;;
72 | php | composer)
73 | _php $@
74 | ;;
75 | node | npm)
76 | _node $@
77 | ;;
78 | go)
79 | _go $@
80 | ;;
81 | sentry)
82 | _sentry $@
83 | ;;
84 | stats)
85 | docker stats --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}\t{{.BlockIO}}"
86 | ;;
87 | ssl)
88 | _certbot $@
89 | ;;
90 | ins)
91 | _inspect $@
92 | ;;
93 | stop_all | stopAll | stopall)
94 | docker ps -a -q
95 | ;;
96 | delete_all | deleteAll | deleteall)
97 | docker system prune -a
98 | ;;
99 | tools)
100 | _tools
101 | ;;
102 | mysql)
103 | _mysqlTools $@
104 | ;;
105 | mongodb)
106 | _mongodbTools $@
107 | ;;
108 | installDocker | installdocker)
109 | _installDocker
110 | ;;
111 | help)
112 | _help $@
113 | ;;
114 | logs)
115 | _logs $@
116 | ;;
117 | name)
118 | echo $WORK_NAME
119 | ;;
120 | *)
121 | _help $@
122 | ;;
123 | esac
124 |
125 | }
126 |
127 | function _help() {
128 | local cmd=${BASH_SOURCE[0]}
129 | cmd=$(echo $cmd | sed 's:\/usr\/bin\/::g')
130 | echo ' .__ .___ __ '
131 | echo '________| | ______ __| _/ ____ ____ | | __ ____ _______ '
132 | echo '\___ /| | / ___/ ______ / __ | / _ \ _/ ___\ | |/ /_/ __ \\_ __ \'
133 | echo ' / / | |__ \___ \ /_____/ / /_/ |( <_> )\ \___ | < \ ___/ | | \/'
134 | echo '/_____ \|____//____ > \____ | \____/ \___ >|__|_ \ \___ >|__| '
135 | echo ' \/ \/ \/ \/ \/ \/ '
136 | echo ''
137 | tips " $cmd start Start up service"
138 | tips " $cmd stop Stop of Service"
139 | tips " $cmd reload Reload Services"
140 | tips " $cmd restart Restart Services"
141 | tips " $cmd status View status"
142 | tips " $cmd stats Display resources used"
143 | tips " $cmd bash Exec Services"
144 | tips " $cmd cron Exec Crontab"
145 | tips " $cmd build Build services"
146 | tips " $cmd buildUp Build and start services"
147 | tips " $cmd tools Toolbox"
148 | tips " $cmd mysql Mysql operating"
149 | tips " $cmd ssl Renew the free certificates from Let's Encrypt."
150 | echo ''
151 | echo " Designated Language Directives(php, node, npm, golang, composer)"
152 | echo " $cmd php -v"
153 | echo " $cmd npm install xxx"
154 | echo ' ......'
155 | }
156 |
157 | function command_exists() {
158 | command -v "$1" 2>&1
159 | }
160 |
161 | function start_docker() {
162 | systemctl start docker && systemctl enable docker
163 | }
164 |
165 | function confirm() {
166 | echo -e -n "\033[34m$* \033[1;36m(Y/n)\033[0m"
167 | read -n 1 -s opt
168 |
169 | [[ "$opt" == $'\n' ]] || echo
170 |
171 | case "$opt" in
172 | 'y' | 'Y' ) return 0;;
173 | 'n' | 'N' ) return 1;;
174 | *) confirm "$1";;
175 | esac
176 | }
177 |
178 | function judge() {
179 | if [ -z `command_exists docker` ]; then
180 | tips "Missing Docker environment"
181 | if confirm "Do you need to install Docker automatically?"; then
182 | # askRoot
183 | curl -sSLk https://get.docker.com/ | bash
184 | if [ $? -ne "0" ]; then
185 | error "Docker installation failed"
186 | fi
187 | tips "Docker installation complete"
188 | else
189 | error "Abort installation"
190 | fi
191 | fi
192 |
193 | if [ -z `command_exists docker compose` ]; then
194 | if [ -z `command_exists docker-compose` ]; then
195 | tips "Docker-compose component not found"
196 | if confirm "Whether the Docker Compose Plugin needs to be installed automatically"; then
197 | curl -L https://github.com/docker/compose/releases/download/1.27.4/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
198 | if [ $? -ne "0" ]; then
199 | error "Docker Compose Plugin installation failed"
200 | fi
201 | chmod +x /usr/local/bin/docker-compose
202 | tips "Docker Compose Plugin installation complete"
203 | else
204 | error "Abort installation"
205 | fi
206 | fi
207 | fi
208 |
209 | # type docker >/dev/null 2>&1 || {
210 | # _installDocker
211 | # error "Please install Docker!"
212 | # }
213 |
214 | # type docker-compose >/dev/null 2>&1 || {
215 | # tips "command:"
216 | # tips " sudo curl -L https://github.com/docker/compose/releases/download/1.27.4/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose"
217 | # tips " sudo chmod +x /usr/local/bin/docker-compose"
218 | # error "Please install docker-compose!"
219 | # }
220 | }
221 |
222 | function askRoot() {
223 | if [ $(id -u) != 0 ]; then
224 | error "You must be root to run this script, please use root run"
225 | fi
226 | }
227 |
228 | function config() {
229 | local dockerComposePath="$WORK_DIR/docker-compose.yml"
230 | local configPath="$WORK_DIR/.env"
231 |
232 | if [[ ! -f $configPath ]]; then
233 | cp $configPath".example" $configPath
234 | if [ $? -ne 0 ]; then
235 | error ".env does not exist, initialize Error."
236 | else
237 | tips ".env does not exist, initialize."
238 | fi
239 | fi
240 |
241 | if [[ ! -f $dockerComposePath ]]; then
242 | cp $dockerComposePath".example" $dockerComposePath
243 | if [ $? -ne 0 ]; then
244 | error "docker-compose.yml does not exist, initialize Error."
245 | else
246 | tips "docker-compose.yml does not exist, initialize."
247 | fi
248 | fi
249 | source $configPath
250 | }
251 |
252 | function _installDocker() {
253 | #askRoot
254 |
255 | local info=$(cat /etc/os-release)
256 | if [[ "" != $(echo $info | grep CentOS) ]]; then
257 | tips 'OS is CentOS'
258 | tips 'command:'
259 | tips " sudo curl -sSL https://get.docker.com | sh"
260 | tips " sudo usermod -aG docker $USER"
261 | tips " newgrp docker"
262 | tips " sudo curl -L https://github.com/docker/compose/releases/download/1.27.4/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose"
263 | tips " sudo chmod +x /usr/local/bin/docker-compose"
264 | tips " docker-compose --version"
265 | tips "start: "
266 | tips " sudo systemctl start docker"
267 | tips " sudo systemctl enable docker"
268 | elif [[ "" != $(echo $info | grep Ubuntu) ]]; then
269 | tips 'OS is Ubuntu'
270 | tips 'command:'
271 | tips " sudo curl -sSL https://get.docker.com | sh"
272 | tips " sudo usermod -aG docker $USER"
273 | tips " newgrp docker"
274 | tips " sudo curl -L https://github.com/docker/compose/releases/download/1.27.4/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose"
275 | tips " sudo chmod +x /usr/local/bin/docker-compose"
276 | tips " docker-compose --version"
277 | tips "start: "
278 | tips " sudo service start docker"
279 | else
280 | tips "See: https://docs.docker.com/install/"
281 | fi
282 | }
283 |
284 | function _install() {
285 | local zdc="$BIN_PATH/zdc"
286 | local zdocker="$BIN_PATH/zdocker"
287 | if [ -f "$zdocker" ]; then
288 | sudo mv -f $zdocker $zdocker"-old"
289 | fi
290 |
291 | if [ -f "$zdc" ]; then
292 | tips "old zdc mv zdc-old"
293 | sudo mv -f $zdc $zdc"-old"
294 | fi
295 |
296 | sudo ln -s $WORK_DIR/run.sh $zdocker
297 | sudo ln -s $WORK_DIR/run.sh $zdc
298 | tips "You can now use zdc instead of ./run.sh: "
299 | tips " zdc up"
300 | tips " zdc help"
301 | }
302 |
303 | function _tools() {
304 | tips "********please enter your choise:(1-7)****"
305 | cat <&2
498 | exit 1
499 | }
500 |
501 | function _php() {
502 | local phpv="php"
503 | local cmd
504 | cmd=$1
505 | images $phpv
506 | local composerPath=$(
507 | cd ${COMPOSER_DATA_DIR/.\/$SCRIPT_SOURCE_DIR/}
508 | pwd
509 | )
510 | if [[ "composer" == $cmd ]]; then
511 | docker run --tty --interactive --rm --cap-add SYS_PTRACE --volume $composerPath:/composer:rw --volume $SCRIPT_SOURCE_DIR:/var/www/html --workdir /var/www/html $WORK_NAME"_php" $@
512 |
513 | #docker run --tty --interactive --rm --user $(id -u):$(id -g) --cap-add SYS_PTRACE --volume /etc/passwd:/etc/passwd:ro --volume /etc/group:/etc/group:ro --volume $composerPath:/composer:rw --volume $SCRIPT_SOURCE_DIR:/var/www/html --workdir /var/www/html $WORK_NAME"_php" $@
514 | else
515 | # _bash $phpv php $@
516 | docker run --tty --interactive --rm --cap-add SYS_PTRACE --volume $composerPath:/composer:rw --volume $SCRIPT_SOURCE_DIR:/var/www/html --workdir /var/www/html $WORK_NAME"_php" php $@
517 | fi
518 | }
519 |
520 | function _sentry() {
521 | images sentry
522 | _bash sentry "$@"
523 | }
524 |
525 | function _node() {
526 | images node
527 | docker run --tty --interactive --rm --volume $SCRIPT_SOURCE_DIR:/var/www/html:rw --workdir /var/www/html $WORK_NAME"_node" "$@"
528 | }
529 |
530 | function _go() {
531 | images go
532 | local goproxy=https://goproxy.cn,direct
533 | if [[ -n "${GOPROXY}" ]]; then
534 | goproxy=$GOPROXY
535 | fi
536 | local cmd=$@
537 | if [[ "bash" == $2 ]];then
538 | docker run -it -e GOPROXY="$goproxy" --volume $SCRIPT_SOURCE_DIR:/var/www/html:rw --workdir /var/www/html $WORK_NAME"_go" bash
539 | return
540 | fi
541 | if [[ -n "${GOPROXY}" ]]; then
542 | docker run --tty --interactive -e GOPROXY="$goproxy" --volume $SCRIPT_SOURCE_DIR:/var/www/html:rw --workdir /var/www/html $WORK_NAME"_go" "$cmd"
543 | fi
544 | }
545 |
546 | function images() {
547 | local container=$1
548 | if [[ "" == $(echo $(docker images) | grep $WORK_NAME"_"$container) ]]; then
549 | tips "The $container service is for the first time, please wait ..."
550 | _start --build $container
551 | elif [[ "" == $(echo $(compose images) | grep $WORK_NAME"_"$container) ]]; then
552 | _start $container
553 | fi
554 | }
555 |
556 | function compose() {
557 | if [ -z `command_exists "docker-compose"` ]; then
558 | docker compose $@
559 | elif [ -z `command_exists "docker compose"` ]; then
560 | docker-compose $@
561 | fi
562 | }
563 |
564 | function __path() {
565 | echo $1
566 | }
567 |
568 | function _logs() {
569 | local container=$1
570 | compose logs $container
571 | }
572 |
573 | function _certbot() {
574 | local certsPath="$WORK_DIR"
575 | local ACME=~/.acme.sh/acme.sh
576 | local binCmd=$certsPath/run.sh
577 | local zdc="$BIN_PATH/zdc"
578 | if [ -f "$zdc" ]; then
579 | binCmd=zdc
580 | fi
581 | local help="Usage: $binCmd ssl -d mydomain.com -w $certsPath/www/mydomain.com/public"
582 | local email
583 | local debug
584 | local force
585 | local reloadcmd
586 | if [ ! -f "$ACME" ]; then
587 | tips "$ACME does not exist, installing..."
588 | curl https://get.acme.sh | sh
589 | # 自动更新
590 | $ACME --upgrade --auto-upgrade
591 | #tips "Please set a scheduled task:"
592 | #echo -e " 55 5 * * * $cmd reload"
593 | fi
594 |
595 | if [[ "$1" == "" ]]; then
596 | error $help
597 | fi
598 |
599 | args=()
600 |
601 | while [ "$1" != "" ]; do
602 | case "$1" in
603 | --email ) email="$2"; shift;;
604 | --dns ) dns="$2"; shift;;
605 | -d | --domain ) domain="$2"; shift;;
606 | -B | --broad ) broad="general analysis"; shift;;
607 | -B | --broad ) broad="general analysis"; shift;;
608 | -a | --alias ) alias="$2"; shift;;
609 | -w | --webroot ) webroot="--webroot $2"; shift;;
610 | -h | --help ) tips $help; exit;;
611 | * ) args+=("$1")
612 | esac
613 | shift
614 | done
615 | if [[ -z "${domain}" ]]; then
616 | error "Please enter the domain name"
617 | fi
618 |
619 |
620 | if [[ -z ${webroot} && -n "${dns}" ]]; then
621 | # dns_cf
622 | dns="--dns ${dns}";
623 | fi
624 |
625 | if [[ -n "${broad}" ]]; then
626 | broad="-d *.${domain}";
627 | fi
628 |
629 | if [[ -n "${alias}" ]]; then
630 | alias_str="--challenge-alias ${alias}";
631 | fi
632 |
633 | ## --force --debug --reloadcmd "zdc reload"
634 |
635 | $ACME --issue $dns $alias_str -d $domain $broad $webroot $args
636 |
637 | if [ $? -ne 0 ]; then
638 | exit
639 | fi
640 |
641 | echo "create certs dir: $certsPath/config/nginx/conf.d/certs/$domain"
642 | mkdir -p $certsPath/config/nginx/conf.d/certs/$domain
643 |
644 | $ACME --install-cert -d $domain $broad --reloadcmd "${binCmd} reload" --key-file $certsPath/config/nginx/conf.d/certs/$domain/server.key --fullchain-file $certsPath/config/nginx/conf.d/certs/$domain/server.crt
645 |
646 | tips "reference:"
647 | echo " cp $certsPath/config/nginx/conf.d/localhost_https.conf $certsPath/config/nginx/conf.d/[DOMAIN]_https.conf"
648 | }
649 |
650 | function _mysqlTools() {
651 | local yes=0
652 | local BAK_DIR="$MYSQL_CONF_DIR/backup"
653 | local BAK_FILE="$BAK_DIR/$TIME.sql"
654 | local DAYS=15
655 | mkdir -p $BAK_DIR
656 | if [[ "backup" == $1 ]]; then
657 | cat >$BAK_DIR/.bak_mysql.sh< "/mysql/backup/${TIME}.sql"
661 |
662 | find /mysql/backup/ -mtime +$DAYS -delete
663 | EOF
664 | _bash mysql chmod 777 /mysql/backup/.bak_mysql.sh
665 | _bash mysql /mysql/backup/.bak_mysql.sh
666 | if [ $? -eq 0 ];then
667 | echo "bak database Sucessfully."
668 | echo "export -> $BAK_FILE"
669 | else
670 | echo "bak database failed!"
671 | echo $(pwd)
672 | echo $BAK_DIR
673 | cat $BAK_DIR/.bak_mysql.sh
674 | fi
675 | rm -f $BAK_DIR/.bak_mysql.sh
676 | exit
677 | fi
678 | tips "********Mysql Tools****"
679 | cat < "$BAK_FILE"
692 | echo "export -> $BAK_FILE"
693 | else
694 | echo "Give up Export mysql"
695 | fi
696 | ;;
697 | 2)
698 | tips 'command:'
699 | echo " ${BASH_SOURCE[0]} bash mysql"
700 | echo " mysql -uroot -p$MYSQL_ROOT_PASSWORD"
701 | echo " source /mysql/backup/xxx.sql"
702 | ;;
703 | 3)
704 | __Enter_Database_Name
705 | tips "Please enter password for mysql user ${database_name}: "
706 | read mysql_password
707 | echo "Your password: ${mysql_password} "
708 | cat >$BAK_DIR/.add_mysql.sql<$BAK_DIR/.add_mysql.sh<$BAK_DIR/.bak.sh< $BAK_FILE"
760 | else
761 | echo "bak database failed!"
762 | echo $(pwd)
763 | echo $BAK_DIR
764 | cat $BAK_DIR/.bak.sh
765 | fi
766 | rm -f $BAK_DIR/.bak.sh
767 | exit
768 | fi
769 | }
770 |
771 | function __Enter_Database_Name()
772 | {
773 | while :;do
774 | tips "Enter database name: "
775 | read database_name
776 | if [ "${database_name}" == "" ]; then
777 | error "Database Name can't be empty!"
778 | else
779 | break
780 | fi
781 | done
782 | }
783 |
784 | function __determine() {
785 | echo -e "Please determine if you want to perform \033[32m$1\033[0m operation (yes|NO)"
786 | read -p "Now select the top option to: " input
787 | case $input in
788 | "y" | "Y" | "yes" | "YES")
789 | return 1
790 | ;;
791 | *)
792 | return 0
793 | ;;
794 | esac
795 | }
796 |
797 | function _inspect() {
798 | docker inspect $WORK_NAME"_$@"
799 | }
800 |
801 | function __yapi() {
802 | compose up -d yapi
803 | tips "yapi: http://127.0.0.1:$YAPI_HOST_PORT"
804 | }
805 |
806 | function __sentry() {
807 | local cmd=${BASH_SOURCE[0]}
808 | # shellcheck disable=SC2001
809 | cmd=$(echo $cmd | sed 's:\/usr\/bin\/::g')
810 | compose up -d sentry sentry_celery_beat sentry_celery_worker
811 | tips "For the first time, please execute the following command to initialize sentry:\n"
812 | tips " $cmd sentry upgrade"
813 | tips ""
814 | }
815 |
816 | main "$@"
817 |
--------------------------------------------------------------------------------
/config/grafana/grafana.ini:
--------------------------------------------------------------------------------
1 | ##################### Grafana Configuration Example #####################
2 | #
3 | # Everything has defaults so you only need to uncomment things you want to
4 | # change
5 |
6 | # possible values : production, development
7 | ;app_mode = production
8 |
9 | # instance name, defaults to HOSTNAME environment variable value or hostname if HOSTNAME var is empty
10 | ;instance_name = ${HOSTNAME}
11 |
12 | #################################### Paths ####################################
13 | [paths]
14 | # Path to where grafana can store temp files, sessions, and the sqlite3 db (if that is used)
15 | ;data = /var/lib/grafana
16 |
17 | # Temporary files in `data` directory older than given duration will be removed
18 | ;temp_data_lifetime = 24h
19 |
20 | # Directory where grafana can store logs
21 | ;logs = /var/log/grafana
22 |
23 | # Directory where grafana will automatically scan and look for plugins
24 | ;plugins = /var/lib/grafana/plugins
25 |
26 | # folder that contains provisioning config files that grafana will apply on startup and while running.
27 | ;provisioning = conf/provisioning
28 |
29 | #################################### Server ####################################
30 | [server]
31 | # Protocol (http, https, h2, socket)
32 | ;protocol = http
33 |
34 | # The ip address to bind to, empty will bind to all interfaces
35 | ;http_addr =
36 |
37 | # The http port to use
38 | ;http_port = 3000
39 |
40 | # The public facing domain name used to access grafana from a browser
41 | ;domain = localhost
42 |
43 | # Redirect to correct domain if host header does not match domain
44 | # Prevents DNS rebinding attacks
45 | ;enforce_domain = false
46 |
47 | # The full public facing url you use in browser, used for redirects and emails
48 | # If you use reverse proxy and sub path specify full url (with sub path)
49 | ;root_url = %(protocol)s://%(domain)s:%(http_port)s/
50 |
51 | # Serve Grafana from subpath specified in `root_url` setting. By default it is set to `false` for compatibility reasons.
52 | ;serve_from_sub_path = false
53 |
54 | # Log web requests
55 | ;router_logging = false
56 |
57 | # the path relative working path
58 | ;static_root_path = public
59 |
60 | # enable gzip
61 | ;enable_gzip = false
62 |
63 | # https certs & key file
64 | ;cert_file =
65 | ;cert_key =
66 |
67 | # Unix socket path
68 | ;socket =
69 |
70 | #################################### Database ####################################
71 | [database]
72 | # You can configure the database connection by specifying type, host, name, user and password
73 | # as separate properties or as on string using the url properties.
74 |
75 | # Either "mysql", "postgres" or "sqlite3", it's your choice
76 | ;type = sqlite3
77 | ;host = 127.0.0.1:3306
78 | ;name = grafana
79 | ;user = root
80 | # If the password contains # or ; you have to wrap it with triple quotes. Ex """#password;"""
81 | ;password =
82 |
83 | # Use either URL or the previous fields to configure the database
84 | # Example: mysql://user:secret@host:port/database
85 | ;url =
86 |
87 | # For "postgres" only, either "disable", "require" or "verify-full"
88 | ;ssl_mode = disable
89 |
90 | ;ca_cert_path =
91 | ;client_key_path =
92 | ;client_cert_path =
93 | ;server_cert_name =
94 |
95 | # For "sqlite3" only, path relative to data_path setting
96 | ;path = grafana.db
97 |
98 | # Max idle conn setting default is 2
99 | ;max_idle_conn = 2
100 |
101 | # Max conn setting default is 0 (mean not set)
102 | ;max_open_conn =
103 |
104 | # Connection Max Lifetime default is 14400 (means 14400 seconds or 4 hours)
105 | ;conn_max_lifetime = 14400
106 |
107 | # Set to true to log the sql calls and execution times.
108 | ;log_queries =
109 |
110 | # For "sqlite3" only. cache mode setting used for connecting to the database. (private, shared)
111 | ;cache_mode = private
112 |
113 | #################################### Cache server #############################
114 | [remote_cache]
115 | # Either "redis", "memcached" or "database" default is "database"
116 | ;type = database
117 |
118 | # cache connectionstring options
119 | # database: will use Grafana primary database.
120 | # redis: config like redis server e.g. `addr=127.0.0.1:6379,pool_size=100,db=0,ssl=false`. Only addr is required. ssl may be 'true', 'false', or 'insecure'.
121 | # memcache: 127.0.0.1:11211
122 | ;connstr =
123 |
124 | #################################### Data proxy ###########################
125 | [dataproxy]
126 |
127 | # This enables data proxy logging, default is false
128 | ;logging = false
129 |
130 | # How long the data proxy waits before timing out, default is 30 seconds.
131 | # This setting also applies to core backend HTTP data sources where query requests use an HTTP client with timeout set.
132 | ;timeout = 30
133 |
134 | # How many seconds the data proxy waits before sending a keepalive probe request.
135 | ;keep_alive_seconds = 30
136 |
137 | # How many seconds the data proxy waits for a successful TLS Handshake before timing out.
138 | ;tls_handshake_timeout_seconds = 10
139 |
140 | # How many seconds the data proxy will wait for a server's first response headers after
141 | # fully writing the request headers if the request has an "Expect: 100-continue"
142 | # header. A value of 0 will result in the body being sent immediately, without
143 | # waiting for the server to approve.
144 | ;expect_continue_timeout_seconds = 1
145 |
146 | # The maximum number of idle connections that Grafana will keep alive.
147 | ;max_idle_connections = 100
148 |
149 | # How many seconds the data proxy keeps an idle connection open before timing out.
150 | ;idle_conn_timeout_seconds = 90
151 |
152 | # If enabled and user is not anonymous, data proxy will add X-Grafana-User header with username into the request, default is false.
153 | ;send_user_header = false
154 |
155 | #################################### Analytics ####################################
156 | [analytics]
157 | # Server reporting, sends usage counters to stats.grafana.org every 24 hours.
158 | # No ip addresses are being tracked, only simple counters to track
159 | # running instances, dashboard and error counts. It is very helpful to us.
160 | # Change this option to false to disable reporting.
161 | ;reporting_enabled = true
162 |
163 | # Set to false to disable all checks to https://grafana.net
164 | # for new versions (grafana itself and plugins), check is used
165 | # in some UI views to notify that grafana or plugin update exists
166 | # This option does not cause any auto updates, nor send any information
167 | # only a GET request to http://grafana.com to get latest versions
168 | ;check_for_updates = true
169 |
170 | # Google Analytics universal tracking code, only enabled if you specify an id here
171 | ;google_analytics_ua_id =
172 |
173 | # Google Tag Manager ID, only enabled if you specify an id here
174 | ;google_tag_manager_id =
175 |
176 | #################################### Security ####################################
177 | [security]
178 | # disable creation of admin user on first start of grafana
179 | ;disable_initial_admin_creation = false
180 |
181 | # default admin user, created on startup
182 | ;admin_user = admin
183 |
184 | # default admin password, can be changed before first start of grafana, or in profile settings
185 | ;admin_password = admin
186 |
187 | # used for signing
188 | ;secret_key = SW2YcwTIb9zpOOhoPsMm
189 |
190 | # disable gravatar profile images
191 | ;disable_gravatar = false
192 |
193 | # data source proxy whitelist (ip_or_domain:port separated by spaces)
194 | ;data_source_proxy_whitelist =
195 |
196 | # disable protection against brute force login attempts
197 | ;disable_brute_force_login_protection = false
198 |
199 | # set to true if you host Grafana behind HTTPS. default is false.
200 | ;cookie_secure = false
201 |
202 | # set cookie SameSite attribute. defaults to `lax`. can be set to "lax", "strict", "none" and "disabled"
203 | ;cookie_samesite = lax
204 |
205 | # set to true if you want to allow browsers to render Grafana in a ,