k8sでPWAをびるどしてはいしんする。


Angularやvue.jsなどの静的ファイルをホストするときの流れだよ。

js等のビルドされたファイルをnginxのDocumentRootにコピーして、k8sにapplyするだけなので大した話ではないよ。
ALB経由で配信するよ。

# 1. package.json

今回はvuejsで作ったもの

```
{
  "name": "dapps",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint",
    "test:unit": "vue-cli-service test:unit"
  },
  "dependencies": {
    "axios": "^0.18.0",
    "vue": "^2.6.6",
    "vue-class-component": "^6.0.0",
    "vue-property-decorator": "^7.0.0",
    "vue-router": "^3.0.1"
  },
  "devDependencies": {
    "@types/jest": "^23.1.4",
    "@vue/cli-plugin-babel": "^3.4.0",
    "@vue/cli-plugin-typescript": "^3.4.0",
    "@vue/cli-plugin-unit-jest": "^3.4.0",
    "@vue/cli-service": "^3.4.0",
    "@vue/test-utils": "^1.0.0-beta.20",
    "babel-core": "7.0.0-bridge.0",
    "ts-jest": "^23.0.0",
    "typescript": "^3.0.0",
    "vue-template-compiler": "^2.5.21"
  },
  "postcss": {
    "plugins": {
      "autoprefixer": {}
    }
  },
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not ie <= 8"
  ],
  "jest": {
    "moduleFileExtensions": [
      "js",
      "jsx",
      "json",
      "vue",
      "ts",
      "tsx"
    ],
    "transform": {
      "^.+\\.vue$": "vue-jest",
      ".+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$": "jest-transform-stub",
      "^.+\\.tsx?$": "ts-jest"
    },
    "moduleNameMapper": {
      "^@/(.*)$": "<rootDir>/src/$1"
    },
    "snapshotSerializers": [
      "jest-serializer-vue"
    ],
    "testMatch": [
      "**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)"
    ],
    "testURL": "http://localhost/",
    "globals": {
      "ts-jest": {
        "babelConfig": true
      }
    }
  }
}
```

# 2. Dockerfile

ビルドするコンテナとhttpdを分けるとイメージ節約になる。
URLのルーティングにhistory apiを利用している場合には、別途 try_files の設定をしないといけない。
[Docker+nginxでtry_filesを追加したい
](https://qiita.com/murata-tomohide/items/d5f79742790ed621cca4)

```
# Stage 0, "build-stage", based on Node.js, to build and compile the frontend
FROM node:11.3.0 as build-stage
WORKDIR /app
COPY package*.json /app/
RUN npm install --global npm@6.8.0 npx@10.2.0 && npm install
COPY ./ /app/
RUN npm run build

# Stage 1, based on Nginx, to have only the compiled app, ready for production with Nginx
FROM nginx:1.15
COPY --from=build-stage /app/dist /usr/share/nginx/html
```

できたDockerfileはECRにpushしておいた。

# 3. k8s.yaml

`kubectl applay -f k8s.yam` でデプロイする。
シンプルだね！

アプリとそれのServiceのPod

```yaml
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  name: gascenter-web-frontend-dapps
spec:
  replicas: 2
  selector:
    matchLabels:
      app: gascenter-web-frontend-dapps
  template:
    metadata:
      labels:
        app: gascenter-web-frontend-dapps
    spec:
      containers:
      - args:
        image: 026695289470.dkr.ecr.ap-northeast-1.amazonaws.com/gascenter-web-frontend-dapps:latest
        imagePullPolicy: Always
        name: gascenter-web-frontend-dapps
        ports:
        - containerPort: 80
          protocol: TCP
      imagePullSecrets:
        - name: awsecs
---
kind: Service
apiVersion: v1
metadata:
  name: gascenter-web-frontend-dapps-svc
spec:
  # externalTrafficPolicy: Local
  type: NodePort
  ports:
  - name: "http-port"
    protocol: TCP
    port: 80
    targetPort: 80
  selector:
    app: gascenter-web-frontend-dapps
```

ここからはIngress(ALB)の設定
今回はEKSを使ったので、ALBの設定もk8sから行った。こいつを食わせるとALBをよしなにいじってくれます。

alb.ingress.kubernetes.ioのアノテーションについてはこちら
https://kubernetes-sigs.github.io/aws-alb-ingress-controller/guide/ingress/annotation/

```yaml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: gascenter-web-frontend-app
  annotations:
    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/scheme: internet-facing
    # alb.ingress.kubernetes.io/subnets: subnet-000000,subnet-111111,subnet-22222
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS": 443}]'
    alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:ap-northeast-1:026695289470:certificate/65a878de-ed52-4415-a69e-c0fcf9aeca7a
    alb.ingress.kubernetes.io/actions.ssl-redirect: '{"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}'
spec:
  rules:
    - host: xxxx.takamattekita.cc
      http:
        paths:
          - path: /*
            backend:
              serviceName: ssl-redirect
              servicePort: use-annotation
          - path: /*
            backend:
              serviceName: gascenter-web-frontend-dapps-svc
              servicePort: 80
```