diff --git a/Dashboard/Traefik 2.2 Copy-1615284143326.json b/Dashboard/Traefik 2.2 Copy-1615284143326.json new file mode 100644 index 0000000..cbecbb7 --- /dev/null +++ b/Dashboard/Traefik 2.2 Copy-1615284143326.json @@ -0,0 +1,842 @@ +{ + "__inputs": [ + { + "name": "DS_PROMETHEUS", + "label": "Prometheus", + "description": "", + "type": "datasource", + "pluginId": "prometheus", + "pluginName": "Prometheus" + } + ], + "__requires": [ + { + "type": "grafana", + "id": "grafana", + "name": "Grafana", + "version": "7.3.7" + }, + { + "type": "panel", + "id": "grafana-piechart-panel", + "name": "Pie Chart", + "version": "1.6.1" + }, + { + "type": "panel", + "id": "graph", + "name": "Graph", + "version": "" + }, + { + "type": "datasource", + "id": "prometheus", + "name": "Prometheus", + "version": "1.0.0" + }, + { + "type": "panel", + "id": "singlestat", + "name": "Singlestat", + "version": "" + } + ], + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "${DS_PROMETHEUS}", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "limit": 100, + "name": "Annotations & Alerts", + "showIn": 0, + "type": "dashboard" + } + ] + }, + "description": "Traefik dashboard (data from prometheus on k8s) (based on Traefik by Thomas Cheronneau https://grafana.com/grafana/dashboards/4475)", + "editable": true, + "gnetId": 12541, + "graphTooltip": 0, + "id": null, + "iteration": 1615284134010, + "links": [], + "panels": [ + { + "collapsed": false, + "datasource": "${DS_PROMETHEUS}", + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 16, + "panels": [], + "title": "Global stats", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PROMETHEUS}", + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 1 + }, + "hiddenSeries": false, + "id": 14, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.3.7", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "label_replace(sum(traefik_service_request_duration_seconds_sum{}) by (exported_service) / sum(traefik_service_request_duration_seconds_count{}) by (exported_service), \"short_label\", \"$1\", \"exported_service\", \"(.*)-.*\")", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": " {{ short_label }}", + "refId": "A", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Average response time by service", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:2737", + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:2738", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "breakPoint": "50%", + "cacheTimeout": null, + "combine": { + "label": "Others", + "threshold": 0 + }, + "datasource": "${DS_PROMETHEUS}", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fontSize": "80%", + "format": "short", + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 8 + }, + "id": 8, + "interval": null, + "legend": { + "show": true, + "values": true + }, + "legendType": "Right side", + "links": [], + "maxDataPoints": 3, + "nullPointMode": "connected", + "pieType": "pie", + "strokeWidth": 1, + "targets": [ + { + "expr": "sum(rate(traefik_entrypoint_requests_total{entrypoint =~ \"$entrypoint\"}[5m])) by (entrypoint)", + "format": "time_series", + "instant": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{ entrypoint }}", + "refId": "A" + } + ], + "title": "Requests by protocol for 5 min", + "type": "grafana-piechart-panel", + "valueName": "total" + }, + { + "aliasColors": {}, + "breakPoint": "50%", + "cacheTimeout": null, + "combine": { + "label": "Others", + "threshold": 0 + }, + "datasource": "${DS_PROMETHEUS}", + "description": "", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fontSize": "80%", + "format": "short", + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 8 + }, + "id": 7, + "interval": null, + "legend": { + "show": true, + "sort": "total", + "sortDesc": false, + "values": true + }, + "legendType": "Right side", + "links": [], + "maxDataPoints": 3, + "nullPointMode": "connected", + "pieType": "pie", + "strokeWidth": 1, + "targets": [ + { + "expr": "label_replace(sum(rate(traefik_service_requests_total[5m])) by (service), \"short_label\", \"$1\", \"service\", \"(.*)-.*\")", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{ short_label }}", + "refId": "A" + } + ], + "title": "Request rate by service for 5min", + "type": "grafana-piechart-panel", + "valueName": "total" + }, + { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PROMETHEUS}", + "description": "", + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 15 + }, + "hiddenSeries": false, + "id": 5, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": false, + "values": true + }, + "lines": false, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.3.7", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(traefik_entrypoint_requests_total{entrypoint=~\"$entrypoint\",code=\"200\"}[1m])) by (method) ", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{method}} : {{code}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Status code 200", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:2885", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:2886", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PROMETHEUS}", + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 15 + }, + "hiddenSeries": false, + "id": 6, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": false, + "values": true + }, + "lines": false, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.3.7", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "rate(traefik_entrypoint_requests_total{entrypoint!=\"metrics\",code!=\"200\"}[1m])", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{entrypoint}} : {{ method }} : {{code}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Others status code", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:2979", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:2980", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "collapsed": false, + "datasource": "${DS_PROMETHEUS}", + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 22 + }, + "id": 10, + "panels": [], + "repeat": "service", + "title": "$service stats", + "type": "row" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "datasource": "${DS_PROMETHEUS}", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "format": "ms", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 23 + }, + "id": 4, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum(traefik_service_request_duration_seconds_sum{service=\"$service\"} ) / sum(traefik_service_requests_total{service=\"$service\"} ) * 1000", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "", + "refId": "A" + } + ], + "thresholds": "", + "title": "$service response time", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + }, + { + "aliasColors": {}, + "breakPoint": "50%", + "cacheTimeout": null, + "combine": { + "label": "Others", + "threshold": 0 + }, + "datasource": "${DS_PROMETHEUS}", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fontSize": "80%", + "format": "short", + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 23 + }, + "id": 2, + "interval": null, + "legend": { + "percentage": true, + "show": true, + "values": true + }, + "legendType": "Right side", + "links": [], + "maxDataPoints": 3, + "nullPointMode": "connected", + "pieType": "pie", + "strokeWidth": 1, + "targets": [ + { + "expr": "traefik_service_requests_total{service=\"$service\"}", + "format": "time_series", + "instant": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{method}} : {{code}}", + "refId": "A" + } + ], + "title": "$service return code", + "type": "grafana-piechart-panel", + "valueName": "current" + }, + { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PROMETHEUS}", + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 23 + }, + "hiddenSeries": false, + "id": 3, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": false, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.3.7", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(traefik_service_requests_total{service=\"$service\"}[5m]))", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "Total requests $service", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Total requests over 5min $service", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:1361", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:1362", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "refresh": "10s", + "schemaVersion": 26, + "style": "dark", + "tags": [ + "prometheus", + "traefik", + "kubernetes" + ], + "templating": { + "list": [ + { + "allValue": null, + "current": {}, + "datasource": "${DS_PROMETHEUS}", + "definition": "label_values(traefik_service_request_duration_seconds_sum, service)", + "error": null, + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "service", + "options": [], + "query": "label_values(traefik_service_request_duration_seconds_sum, service)", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 1, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": {}, + "datasource": "${DS_PROMETHEUS}", + "definition": "label_values(traefik_entrypoint_requests_total,entrypoint)", + "error": null, + "hide": 0, + "includeAll": true, + "label": null, + "multi": true, + "name": "entrypoint", + "options": [], + "query": "label_values(traefik_entrypoint_requests_total,entrypoint)", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-30m", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "", + "title": "Traefik 2.2 Copy", + "uid": "duDvV2LMz", + "version": 9 +} \ No newline at end of file diff --git a/README.md b/README.md index 076e92e..3dd7c5c 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ ### 服务器部署 -默认 bolo 的访问域名为 expoli.tech,请根据需要同步修改 `bolo-env.env` 与 `letsencrypt.env` 中的网址与邮件地址, **强烈建议将数据库密码修改为强密码!同时别忘对所有密码项进行同步更改!** 修改完成后根据 [本地快速部署测试](#本地快速部署测试),进行后续步骤即可。 +默认 bolo 的访问域名为 expoli.tech,请根据需要同步修改 `bolo-env.env` 中的各环境变量, **强烈建议将数据库密码修改为强密码!同时别忘对所有密码项进行同步更改!** 修改完成后根据 [本地快速部署测试](#本地快速部署测试),进行后续步骤即可。 ``` # mysql env @@ -51,17 +51,6 @@ JDBC_PASSWORD=bolo123456 JDBC_DRIVER=com.mysql.cj.jdbc.Driver JDBC_URL=jdbc:mysql://db:3306/bolo?useUnicode=yes&characterEncoding=UTF-8&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC - -# -# 需要修改为你的博客域名 -# -SERVER_HOST=expoli.tech - -# 你一般不需要修改 -SERVER_PORT= -SERVER_SCHEME=https -LISTEN_PORT=8080 - ``` **启动参数说明:** @@ -77,13 +66,15 @@ LISTEN_PORT=8080 **注意:启用HTTPS时需保证你的主机拥有公网IP且、80 443 端口可以被正常访问,否则有可能自动颁发证书失败** -修改相应的字段值为自己所需,各环境变量所代表含义请参阅 https://github.com/nginx-proxy/docker-letsencrypt-nginx-proxy-companion +修改相应的字段值为自己所需,可对 `docker-compose.yaml` 中的 `blog.example.org` 进行批量替换 -``` -VIRTUAL_HOST=expoli.tech -LETSENCRYPT_HOST=expoli.tech -LETSENCRYPT_EMAIL=me@expoli.tech +```bash +# 请修改为自己的邮箱地址 +- "--certificatesresolvers.myresolver.acme.email=me@example.org" +# 请将 blog.example.org 修改为你自己的博客域名 +command: --listen_port=8080 --server_scheme=https --server_host=blog.example.org --server_port=443 --lute_http=http://lute:8249 +- traefik.http.routers.bolo.rule=Host(`blog.example.org`) ``` ### 快速部署 @@ -100,40 +91,34 @@ git clone https://github.com/expoli/start-bolo-with-docker-compose.git cd start-bolo-with-docker-compose ``` -- **加载修改后的环境变量** - -```shell -export $(cat ./bolo-env.env ) -``` - - **使用 docker-compose 启动 bolo** ```shell # 后台启动 -export $(cat ./bolo-env.env ) && docker-compose up -d +docker-compose up -d # 前台方式启动可以看到日志输出、方便进行排错 -export $(cat ./bolo-env.env ) && docker-compose up +docker-compose up ``` - **更新容器** ```shell -export $(cat ./bolo-env.env ) && docker-compose pull && docker-compose up -d +docker-compose pull && docker-compose up -d ``` - **删除容器与 docker 网络(但保留关键数据)** ```shell -export $(cat ./bolo-env.env ) && docker-compose down +docker-compose down ``` -- **完全删除 危险!!!** +- **完全删除** -如果你想完全卸载 bolo 只需要运行以下命令,此命令会删除 MySQL 数据卷 **危险**、**因为mysql数据库文件放在了docker volume里面** +如果你想完全卸载 bolo 只需要运行以下命令 ```shell -export $(cat ./bolo-env.env ) && docker-compose down --volume +rm start-bolo-with-docker-compose -rf ``` ### 迁移 @@ -142,12 +127,18 @@ export $(cat ./bolo-env.env ) && docker-compose down --volume ```shell # Backup -docker exec CONTAINER /usr/bin/mysqldump -u root --password=root DATABASE > backup.sql +zip -r start-bolo-with-docker-compose.zip start-bolo-with-docker-compose # Restore -cat backup.sql | docker exec -i CONTAINER /usr/bin/mysql -u root --password=root DATABASE +unzip start-bolo-with-docker-compose.zip ``` +### 性能监控 + +默认 traefik 已经开启了 `prometheus` 性能监控功能、可配合 `Grafana` 进行使用,最终效果如图 + +![Traefik](image/Traefik-2-2-Copy-Grafana.png) + ### 启用定时更新
@@ -158,7 +149,7 @@ cat backup.sql | docker exec -i CONTAINER /usr/bin/mysql -u root --password=root 1. 手动运行定时命令进行测试 ```bash -cd /path/to/your/docker-compose && export $(cat ./bolo-env.env ) && docker-compose pull && docker-compose down && docker-compose up -d +cd /path/to/your/docker-compose && docker-compose pull && docker-compose down && docker-compose up -d ``` 2. 确认运行无误之后将其添加至定时任务中 @@ -195,98 +186,87 @@ cd /path/to/your/docker-compose && export $(cat ./bolo-env.env ) && docker-compo version: '3' services: - db: - image: mariadb - command: --max_allowed_packet=32505856 --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci --transaction-isolation=READ-COMMITTED --binlog-format=ROW - restart: always - volumes: - - db:/var/lib/mysql - # environment: - # - MYSQL_ROOT_PASSWORD= - # - MYSQL_PASSWORD= - # - MYSQL_DATABASE= - # - MYSQL_USER= - env_file: - - bolo-env.env - web: - build: ./web + traefik: + image: "traefik" + container_name: "traefik" restart: always + command: +# - "--log.level=DEBUG" +# - "--api.insecure=true" + - "--providers.docker=true" + - "--providers.docker.exposedbydefault=false" + - "--entrypoints.web.address=:80" + - "--entrypoints.websecure.address=:443" + - "--certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web" + - "--certificatesResolvers.myresolver.acme.dnsChallenge.resolvers=1.1.1.1:53,8.8.8.8:53" +# - "--certificatesresolvers.myresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory" + ############ + # 修改为自己的邮箱地址 + ############ + - "--certificatesresolvers.myresolver.acme.email=me@example.org" + - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json" + # prometheus 数据监控、如不需要可注释掉 + - "--metrics.prometheus=true" + - "--entryPoints.metrics.address=:9090" + - "--metrics.prometheus.entryPoint=metrics" + # http 跳转至 https + - "--entrypoints.web.http.redirections.entryPoint.to=websecure" + - "--entrypoints.web.http.redirections.entryPoint.scheme=https" + network_mode: host volumes: - - bolo:/var/www/html:ro - # environment: - # - VIRTUAL_HOST= - # - LETSENCRYPT_HOST= - # - LETSENCRYPT_EMAIL= - depends_on: - - bolo - env_file: - - letsencrypt.env - networks: - - proxy-tier - - default - - proxy: - build: ./proxy - restart: always - ports: - - 80:80 - - 443:443 - labels: - com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy: "true" - volumes: - - certs:/etc/nginx/certs:ro - - vhost.d:/etc/nginx/vhost.d - - html:/usr/share/nginx/html - - /var/run/docker.sock:/tmp/docker.sock:ro - # environment: - # - ENABLE_IPV6=true - networks: - - proxy-tier + - "./letsencrypt:/letsencrypt" + - "/var/run/docker.sock:/var/run/docker.sock:ro" - letsencrypt-companion: - image: jrcs/letsencrypt-nginx-proxy-companion + db: + image: mysql:5.7 + command: --max_allowed_packet=32505856 --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci --transaction-isolation=READ-COMMITTED --binlog-format=ROW restart: always volumes: - - certs:/etc/nginx/certs - - vhost.d:/etc/nginx/vhost.d - - html:/usr/share/nginx/html - - /var/run/docker.sock:/var/run/docker.sock:ro - # environment: - # - DEFAULT_EMAIL= + - ./mysql/data:/var/lib/mysql env_file: - - letsencrypt.env - networks: - - proxy-tier - depends_on: - - proxy + - bolo-env.env + networks: + - default bolo: image: tangcuyu/bolo-solo:latest restart: always + container_name: "bolo" expose: - "8080" + # 主题与文章挂载目录 + volumes: + - /etc/localtime:/etc/localtime:ro + # - ./web/markdowns:/opt/solo/markdowns:rw + # - ./theme/solo-nexmoe:/opt/solo/skins/nexmoe env_file: - bolo-env.env - command: --listen_port=${LISTEN_PORT} --server_scheme=${SERVER_SCHEME} --server_host=${SERVER_HOST} --server_port=${SERVER_PORT} --lute_http=http://lute:8249 + command: --listen_port=8080 --server_scheme=https --server_host=blog.example.org --server_port=443 --lute_http=http://lute:8249 + dns: 8.8.8.8 + labels: + - traefik.enable=true + - traefik.port=8080 + - traefik.http.routers.bolo.rule=Host(`blog.example.org`) + - traefik.http.routers.bolo.tls=true + - "traefik.http.routers.cloudreve.entrypoints=websecure" + - traefik.http.routers.bolo.tls.certresolver=myresolver depends_on: - db + networks: + - default lute: image: b3log/lute-http restart: always expose: - "8249" - -volumes: - db: - bolo: - certs: - vhost.d: - html: + networks: + - default networks: - proxy-tier: + default: + ```
diff --git a/bolo-env.env b/bolo-env.env index 381edfd..36cc2ea 100644 --- a/bolo-env.env +++ b/bolo-env.env @@ -8,9 +8,3 @@ JDBC_USERNAME=bolo JDBC_PASSWORD=bolo123456 JDBC_DRIVER=com.mysql.cj.jdbc.Driver JDBC_URL=jdbc:mysql://db:3306/bolo?useUnicode=yes&characterEncoding=UTF-8&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC - -SERVER_HOST=expoli.tech - -SERVER_PORT= -SERVER_SCHEME=https -LISTEN_PORT=8080 \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml index 118c200..91ed021 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,98 +1,83 @@ version: '3' services: - db: - image: mariadb - command: --max_allowed_packet=32505856 --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci --transaction-isolation=READ-COMMITTED --binlog-format=ROW + + traefik: + image: "traefik" + container_name: "traefik" restart: always + command: +# - "--log.level=DEBUG" +# - "--api.insecure=true" + - "--providers.docker=true" + - "--providers.docker.exposedbydefault=false" + - "--entrypoints.web.address=:80" + - "--entrypoints.websecure.address=:443" + - "--certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web" + - "--certificatesResolvers.myresolver.acme.dnsChallenge.resolvers=1.1.1.1:53,8.8.8.8:53" +# - "--certificatesresolvers.myresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory" + ############ + # 修改为自己的邮箱地址 + ############ + - "--certificatesresolvers.myresolver.acme.email=me@example.org" + - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json" + # prometheus 数据监控、如不需要可注释掉 + - "--metrics.prometheus=true" + - "--entryPoints.metrics.address=:9090" + - "--metrics.prometheus.entryPoint=metrics" + # http 跳转至 https + - "--entrypoints.web.http.redirections.entryPoint.to=websecure" + - "--entrypoints.web.http.redirections.entryPoint.scheme=https" + network_mode: host volumes: - - db:/var/lib/mysql - # environment: - # - MYSQL_ROOT_PASSWORD= - # - MYSQL_PASSWORD= - # - MYSQL_DATABASE= - # - MYSQL_USER= - env_file: - - bolo-env.env + - "./letsencrypt:/letsencrypt" + - "/var/run/docker.sock:/var/run/docker.sock:ro" - web: - build: ./web + db: + image: mysql:5.7 + command: --max_allowed_packet=32505856 --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci --transaction-isolation=READ-COMMITTED --binlog-format=ROW restart: always volumes: - - bolo:/var/www/html:ro - # environment: - # - VIRTUAL_HOST= - # - LETSENCRYPT_HOST= - # - LETSENCRYPT_EMAIL= - depends_on: - - bolo + - ./mysql/data:/var/lib/mysql env_file: - - letsencrypt.env - networks: - - proxy-tier + - bolo-env.env + networks: - default - proxy: - build: ./proxy - restart: always - container_name: bolo_nginx_proxy - ports: - - 80:80 - - 443:443 - labels: - com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy: "true" - com.github.jrcs.letsencrypt_nginx_proxy_companion.docker_gen: "true" - volumes: - - certs:/etc/nginx/certs:ro - - vhost.d:/etc/nginx/vhost.d - - html:/usr/share/nginx/html - - /var/run/docker.sock:/tmp/docker.sock:ro - # environment: - # - ENABLE_IPV6=true - networks: - - proxy-tier - - letsencrypt-companion: - image: jrcs/letsencrypt-nginx-proxy-companion - restart: always - volumes: - - certs:/etc/nginx/certs - - vhost.d:/etc/nginx/vhost.d - - html:/usr/share/nginx/html - - /var/run/docker.sock:/var/run/docker.sock:ro - dns: 8.8.8.8 - environment: - - NGINX_DOCKER_GEN_CONTAINER=bolo_nginx_proxy # nginx 容器名称 - # - DEFAULT_EMAIL= - networks: - - proxy-tier - depends_on: - - proxy - bolo: image: tangcuyu/bolo-solo:latest restart: always + container_name: "bolo" expose: - "8080" + # 主题与文章挂载目录 + volumes: + - /etc/localtime:/etc/localtime:ro + # - ./web/markdowns:/opt/solo/markdowns:rw + # - ./theme/solo-nexmoe:/opt/solo/skins/nexmoe env_file: - bolo-env.env + command: --listen_port=8080 --server_scheme=https --server_host=blog.example.org --server_port=443 --lute_http=http://lute:8249 dns: 8.8.8.8 - command: --listen_port=${LISTEN_PORT} --server_scheme=${SERVER_SCHEME} --server_host=${SERVER_HOST} --server_port=${SERVER_PORT} --lute_http=http://lute:8249 + labels: + - traefik.enable=true + - traefik.port=8080 + - traefik.http.routers.bolo.rule=Host(`blog.example.org`) + - traefik.http.routers.bolo.tls=true + - "traefik.http.routers.cloudreve.entrypoints=websecure" + - traefik.http.routers.bolo.tls.certresolver=myresolver depends_on: - db + networks: + - default lute: image: b3log/lute-http restart: always expose: - "8249" - -volumes: - db: - bolo: - certs: - vhost.d: - html: + networks: + - default networks: - proxy-tier: + default: diff --git a/image/Traefik-2-2-Copy-Grafana.png b/image/Traefik-2-2-Copy-Grafana.png new file mode 100644 index 0000000..a1c908d Binary files /dev/null and b/image/Traefik-2-2-Copy-Grafana.png differ diff --git a/letsencrypt.env b/letsencrypt.env deleted file mode 100644 index 7fcf27a..0000000 --- a/letsencrypt.env +++ /dev/null @@ -1,5 +0,0 @@ -VIRTUAL_HOST=expoli.tech -LETSENCRYPT_HOST=expoli.tech -LETSENCRYPT_EMAIL=me@expoli.tech - -DEFAULT_EMAIL=me@expoli.tech \ No newline at end of file diff --git a/proxy/Dockerfile b/proxy/Dockerfile deleted file mode 100644 index 0c066d0..0000000 --- a/proxy/Dockerfile +++ /dev/null @@ -1,3 +0,0 @@ -FROM jwilder/nginx-proxy:alpine - -COPY uploadsize.conf /etc/nginx/conf.d/uploadsize.conf \ No newline at end of file diff --git a/proxy/uploadsize.conf b/proxy/uploadsize.conf deleted file mode 100644 index 70a739d..0000000 --- a/proxy/uploadsize.conf +++ /dev/null @@ -1,2 +0,0 @@ -client_max_body_size 10G; -proxy_request_buffering off; \ No newline at end of file diff --git a/web/Dockerfile b/web/Dockerfile deleted file mode 100644 index 9ded20d..0000000 --- a/web/Dockerfile +++ /dev/null @@ -1,3 +0,0 @@ -FROM nginx:alpine - -COPY nginx.conf /etc/nginx/nginx.conf \ No newline at end of file diff --git a/web/nginx.conf b/web/nginx.conf deleted file mode 100644 index f1d419e..0000000 --- a/web/nginx.conf +++ /dev/null @@ -1,64 +0,0 @@ -worker_processes auto; - -error_log /var/log/nginx/error.log warn; -pid /var/run/nginx.pid; - - -events { - worker_connections 1024; -} - - -http { - include /etc/nginx/mime.types; - default_type application/octet-stream; - - log_format main '$remote_addr - $remote_user [$time_local] "$request" ' - '$status $body_bytes_sent "$http_referer" ' - '"$http_user_agent" "$http_x_forwarded_for"'; - - access_log /var/log/nginx/access.log main; - - sendfile on; - #tcp_nopush on; - - keepalive_timeout 65; - - set_real_ip_from 10.0.0.0/8; - set_real_ip_from 172.16.0.0/12; - set_real_ip_from 192.168.0.0/16; - real_ip_header X-Real-IP; - - #gzip on; - - client_max_body_size 200m; - - upstream backend { - server bolo:8080; - } - - server { - listen 80; - - location / { - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Real-Port $remote_port; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - # 在多级代理的情况下,记录每次代理之前的客户端真实ip - proxy_set_header HTTP_X_FORWARDED_FOR $remote_addr; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header Host $host; - proxy_set_header X-NginX-Proxy true; - - proxy_set_header Early-Data $ssl_early_data; - - proxy_pass http://backend; - proxy_redirect default; - - # Socket.IO Support - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - } - } -} \ No newline at end of file