2020/06 Cola Daily Build

06/01

06/02

nginx brotli

https://hub.docker.com/r/fholzer/nginx-brotli/

upgrade cscolabear/DockerDev

brotli on;
brotli_comp_level 6;
brotli_static on;
brotli_types application/atom+xml application/javascript application/json application/rss+xml application/vnd.ms-fontobject application/x-font-opentype application/x-font-truetype application/x-font-ttf application/x-javascript application/xhtml+xml application/xml font/eot font/opentype font/otf font/truetype image/svg+xml image/vnd.microsoft.icon image/x-icon image/x-win-bitmap text/css text/javascript text/plain text/xml;

如果是動態內容,chrome 不發送 accept-encoding
非 https chrome 也不發送 ( Brotli only works over HTTPS)

accept-encoding: gzip, deflate, br


可以用 curl 重送 header,

e.g.

curl -s -I -H 'Accept-Encoding: br' http://local.cwb-l5/
curl -s -I -H 'Accept-Encoding: gzip' http://local.cwb-l5/


l5-swagger 瀏覽限制

production 環境下停用

create Middleware

app/Http/Middleware/Swagger.php

<?php

namespace App\Http\Middleware;

use Illuminate\Support\Facades\App;
use Closure;

class Swagger
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if (App::environment('production')) {
            abort('is production');
        }
        return $next($request);
    }
}

app/Http/Kernel.php

.
.
protected $middlewareGroups = [
    .
    .

        'swagger' => [
            \App\Http\Middleware\Swagger::class,
        ],
    .
    .
];

config/l5-swagger.php

'routes' => [
.
.
  'middleware' => [
            'api' => [],
            'asset' => [],
            'docs' => ['swagger'],
            'oauth2_callback' => [],
        ],
.
.

.env 設定為 production 時

APP_ENV=production

ref.

該篇試用 middleware 自動建立 json(但新版 swagger 己有 L5_SWAGGER_GENERATE_ALWAYS .env 可啟用)
https://dokaheionnahibio.blogspot.com/2018/04/laravel-with-swagger.html

06/03

swagger doc

https://swagger.io/docs/specification/describing-request-body/


support nextjen

06/04

public webpack dev server

(nginx proxy webpackserver)
讓 webpack server 可以外連,不會被限制於本機或是 docker container 內

webpack.config.js

devServer: {
  .
  host: '0.0.0.0',
  disableHostCheck: true,
},

host 的部份依需求再調整
預設: ‘localhost’,
0.0.0.0 為開放所有 ip, host

因為 webpack server 有 watch 功能
開發時比較方便


webpack change url publicPath

webpack img url path 在 dev server(hot reload/watch) 和 production bundle(dist) 不同的處理方法

sass 或 css loader 需要判斷目前是否為 production;
是則使用不同的 publicPath 規則

const styleLoader = {
  loader: 'style-loader',
};

const productionMiniCssLoader = {
  loader: MiniCssExtractPlugin.loader,
  options: {
    publicPath: '../', // production (dist); different path levels at css image url
  },
}


const sass = {
  test: /\.s[c|a]ss$/,
  use: [
    config.env === 'production' ? productionMiniCssLoader : styleLoader,
    cssLoader,
    postcssLoader,
    sassLoader,
  ],
};

06/05

  • nextjen
  • webpack fixed

06/08

on leave

06/09

drone & nginx & drone authenticate user

個人讓 drone 和 nginx 同一網域內

設定讓 drone 僅 cscolabear 這個使用者可以登入

version: '2.2'

services:
  .
  .

  nginx:
    hostname: docker-nginx
    build:
      context: ./Dockerfiles/nginx
    image: cscolabear/nginx:latest
    ports:
      - 80:80
      - 443:443
    volumes:
      - /var/www:/var/www
      - ./Logs:/var/log/nginx
      - ./Dockerfiles/nginx/sites-enabled:/etc/nginx/sites-enabled
      - ./ssl:/var/ssl
    mem_limit: 32m
    depends_on:
      - fpm
      - drone-server
    restart: on-failure
    networks:
      - app_net

  .
  .

  drone-server:
    image: drone/drone:1
    ports:
      - 8080:80
    volumes:
      - ./Database/drone:/data
    restart: always
    environment:
      - DRONE_SERVER_HOST=${DRONE_SERVER_HOST}
      - DRONE_SERVER_PROTO=${DRONE_SERVER_PROTO}
      - DRONE_RPC_SECRET=${DRONE_RPC_SECRET}
      - DRONE_USER_CREATE=username:cscolabear,admin:true
      - DRONE_USER_FILTER=cscolabear

      # GitHub Config
      - DRONE_GITHUB_SERVER=https://github.com
      - DRONE_GITHUB_CLIENT_ID=${DRONE_GITHUB_CLIENT_ID}
      - DRONE_GITHUB_CLIENT_SECRET=${DRONE_GITHUB_CLIENT_SECRET}

      - DRONE_LOGS_PRETTY=true
      - DRONE_LOGS_COLOR=true
    networks:
      - app_net

  drone-runner:
    image: drone/drone-runner-docker:1
    restart: always
    depends_on:
      - drone-server
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - DRONE_RPC_HOST=${DRONE_RPC_HOST}
      - DRONE_RPC_PROTO=${DRONE_RPC_PROTO}
      - DRONE_RPC_SECRET=${DRONE_RPC_SECRET}
      - DRONE_RUNNER_CAPACITY=1
    networks:
      - app_net

networks:
  app_net:
    driver: "bridge"

for docker compose .env

# drone
DRONE_SERVER_HOST=drone.workxplay.net
DRONE_SERVER_PROTO=https

# openssl rand -hex 16
DRONE_RPC_SECRET=bexxxxxxxxxxee

# use drone server container name
DRONE_RPC_HOST=drone-server
DRONE_RPC_PROTO=http

DRONE_GITHUB_CLIENT_ID=d8xxxxxxxxxxxxxxxx78
DRONE_GITHUB_CLIENT_SECRET=2exxxxxxxxxxxxxxxxxxxxx05


可以在
確認 nginx 有把 server 正常啟動後再加入 drone.workxplay.net.conf

將下列 nginx conf 放到正確位置後重置 nginx

server {
    listen 80; listen [::]:80;
    server_name drone.workxplay.net;

    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    server_name drone.workxplay.net;

    ssl_certificate /var/ssl/drone.workxplay.net.cer;
    ssl_certificate_key /var/ssl/drone.workxplay.net.key;

    access_log /var/log/nginx/drone.workxplay.net.access.log main;
    error_log /var/log/nginx/drone.workxplay.net.error.log;

    location / {
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-NginX-Proxy true;
        proxy_pass http://drone-server;
        proxy_ssl_session_reuse off;
        proxy_set_header Host $http_host;
        proxy_cache_bypass $http_upgrade;
        proxy_redirect off;

    }
}

注意,比較特別的是
雖然 docker drone 的 80 port 有轉 port 曝光
但在 drone 內部 drone server 與 drone runner 溝通時,不需另外設定 port
而, nginx proxy 也不需另外指定 port

06/10

drillster/drone-rsync

  • leju

06/11

.drone.yml example

kind: pipeline
type: docker
name: default

clone:
  depth: 1

steps:
- name: node
  image: node:12.17-slim
  commands:
    - npm install
    - npm run dev
  when:
    branch:
      - master

- name: rsync
  image: drillster/drone-rsync
  settings:
    hosts:
      from_secret: HOST
    user:
      from_secret: SSH_USER_NAME
    key:
      from_secret: USER_KEY
    source: ./dist/
    target:
      from_secret: TARGET_PATH
    recursive: true
    delete: true
    args: "--no-o --no-g -v"
    # script:
    #   - ls -al
  when:
    branch:
      - master

- name: slack
  image: plugins/slack
  settings:
    webhook:
      from_secret: SLACK_WEBHOOK
    channel: drone-workxplay
    link_names: true
    username: "Drone Bot"
    icon_emoji: ":robot_face:"
    when:
      status: [ success, failure ]
    template: >
      {{#success build.status}}
        ✅ build #{{build.number}} succeeded. Good job.
          `{{repo.name}}/{{build.branch}}`
          {{build.link}}
      {{else}}
        ❌ build #{{build.number}} failed. Fix me please.
          `{{repo.name}}/{{build.branch}}`
           {{build.link}}
      {{/success}}

使用 drone plugin e.g. drillster/drone-rsync
傳入參數的方法
使用 settings: 直接指定 hosts 值
或是使用 drone secret 帶入值, e.g. from_secret: HOST

.
.
.

目前錯誤
檔案傳送成功,但有個 rsync 錯誤
但是在遠端機器找不到 /etc/rsync.conf :confused:


以上解決,對像目錄 (dist) owner 也要是 SSH_USER_NAME

問題二
slack notify
沒辦法監聽中途發生的錯誤 :confused:
不曉得是不是我設定有問題

待測,將 slack 寫成兩個 setp

ps:
雷點,drone 1.x 和 0.x 語法有差異
目前網路上混雜出現~

06/12

assist joe eng

06/15

很慢,打不開
publish local server, like ngork

06/17

plain php handler, send to slack

php handle error

php Use curl to send to the webhook

06/18

  • web socket swoole

06/19

  • simpany smetting

06/22

  • onleave
  • vue tutorial

06/23

vue unescaped html and filter

<p v-html="$options.filters.my_filter(my_variable)"></p>


// multiple filter
<p v-html="$options.filters.makeStrong(
  $options.filters.capitalize(cat)
)"></p>

vue nextTick

scenario: ref 對像 auido 要等 modal 顯示後,才會出現在畫面上

所以沒辦法直接操作 this.$refs.audio.play()
必須透過 nextTick 處理,待 dom 物件都繪製、更新完成後再操作

this.showModal = true

   this.$nextTick(function () {
        this.$refs.audio.play()
      });
    },

Spread Operator (…)

淺複製
shallow-copy

const arr = [1,2,3]
const arr2 = [...arr]

arr2.push(4) // 不影響原始 arr,又能將 arr 複制進入 arr2

06/24

06/28

測試一個專案兩個 Git repo

Push your project to multiple Git Repos.

參考影片~

修改專案目錄下的
.git/config

e.g.

在 [remote "origin”] 下多加一個 [email protected]:xxxxxxxxxxxxxxx.git
(也就是有一個以上的 url)

這樣在 git push origin 的時候就會同時 push 到多個 git repo 了
例如同時推到 github, 和 bitbucket

06/29

檢查 remote push, fetch (git pull) 是否正確, 符合需求

打開 .git/config 設定查看設定

url 第一組為 bitucket 時…

$ git remote -v


(上圖不是我期望的結果,因為希望用 github 為主, bitbucket 為備份,因此 fetch 應該為 github url 才對)
.
.
.

*調整後

將 github 調整為第一組

再一次使 git remote -v 查看

fetch url 變更為 github


結論:

當相同 remote name, 下有多個 remote url 時…
git push 可以同時推送到多個 git repo
但是 git fetch 只會抓取第一組 remote url

Ref:

第一次 設定、新增 git remote
第二次比較建議修戶 .gif/config

$ git remote set-url origin [git remote url, https or git]

#
$ git remote add origin [git remote url, https or git]
$ git remote add my-git-server [git remote url, https or git]

設定 git track

06/30

leaflet & OpenStreetMap

需到 mapbox.com 申請 api token(free plan)

example:

<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css"
    integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ=="
    crossorigin=""/>
    <script src="https://unpkg.com/[email protected]/dist/leaflet.js"
   integrity="sha512-gZwIG9x3wUXg2hdXF6+rVkLF/0Vi9U8D2Ntg4Ga5I5BZpVkVxlJWbSQtXPSiUTtC0TjtGOmxa1AJPuV0CPthew=="
   crossorigin=""></script>

   <style>
       #mapid { height: 100vh }
   </style>
</head>
<body>
    <div id="mapid"></div>
    <script>
        const point = [25.031141, 121.515792];
        const point2 = [25.032511, 121.518484]; // 金
        // var mymap = L.map('mapid').setView([51.505, -0.09], 13);
        var mymap = L.map('mapid').setView(point, 16);
        L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}', {
            attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, <a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
            maxZoom: 18,
            id: 'mapbox/streets-v11',
            tileSize: 512,
            zoomOffset: -1,
            accessToken: 'pk.eyJ1IjoiY3Njb2xhYmVhciIsImEiOiJja2MxZnR4OTUwdDN3MzB1cmo0cW5qaWU0In0.JybBtxp_f4BS5wAN5j5iKA'
        }).addTo(mymap);

        var marker = L.marker(point).addTo(mymap);
        marker.bindPopup("<b>學園K書中心</b><br>可能是一個唸書的地方?")
            // .openPopup();
        L.marker(point2).addTo(mymap)
            .bindPopup("<b>金峰魯肉飯</b><br>uber eat!!!")
            // .openPopup();

    </script>

</body>
</html>

preivew:

ref.

https://leafletjs.com/examples/quick-start/


Adobe_XD_v30.0.12__TNT_Torrentmac.net.dmg

https://helpx.adobe.com/creative-cloud/kb/install-creative-cloud-mac-os-sierra.html