OSS版 Coder (code-server) を Docker、GKE で動かす

# Docker

```bash
$ docker run -p 8443:8443 -v "${PWD}:/root/project" codercom/code-server code-server --allow-http --no-auth
```

ブラウザから `http://localhost:8443/` または `http://<DockerサーバIP>:8443/` にアクセス

# Docker Compose

## docker-compose.yml 作成

```yaml:docker-compose.yml
version: '2'
services:
  server:
    container_name: code-server
    image: codercom/code-server
    command: code-server --allow-http --no-auth
    #command: code-server --allow-http    #認証が必要な場合は `--no-auth` を削除
    volumes:
      - "${PWD}:/root/project"
    ports:
      - "8443:8443"
    restart: always
```

## コンテナ起動

```bash
$ docker-compose up -d
```

ブラウザから `http://localhost:8443/` または `http://<DockerサーバIP>:8443/` にアクセス


#GKE（K8s）

##Dockerイメージのアップロード
次のシェルスクリプト`gcr.sh` を実行し GCR（Google Container Registry）へ Docker イメージをアップロード
※環境変数 `GCR_HOST`、`PROJECT` の値は、環境に合わせて変更してください。

```bash:gcr.sh
#!/bin/bash

GCR_HOST=asia.gcr.io #Container Registryホスト名
PROJECT=my-project   #GCRプロジェクト名

set -eu

docker pull codercom/code-server
docker tag codercom/code-server ${GCR_HOST}/${PROJECT}/code-server
gcloud docker -- push ${GCR_HOST}/${PROJECT}/code-server
docker rmi ${GCR_HOST}/${PROJECT}/code-server
docker rmi codercom/code-server
```

## GKE へデプロイ

次のシェルスクリプト `deployment.sh` を実行し、GKE 上に Coder 環境をデプロイ
※環境変数 `PV_SIZE`、`GCR_HOST`、`PROJECT` の値は、環境に合わせて変更してください。

```bash:deployment.sh
#!/bin/bash

PV_SIZE=10Gi         #永続ディスクサイズ
GCR_HOST=asia.gcr.io #Container Registoryホスト名
PROJECT=my-project   #GCRプロジェクト名

set -eu

cat <<EOS | kubectl apply -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-code-server
  namespace: default
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: ${PV_SIZE}
  storageClassName: regpd
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: "1"
  generation: 1
  labels:
    run: code-server
  name: code-server
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      run: code-server
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
    type: RollingUpdate
  template:
    metadata:
      creationTimestamp: null
      labels:
        run: code-server
    spec:
      containers:
      - image: ${GCR_HOST}/${PROJECT}/code-server
        imagePullPolicy: Always
        name: code-server
        env:
        - name: TZ
          value: "Asia/Tokyo"
        command: ["code-server"]
        args: ["--allow-http", "--no-auth"]
        ports:
        - containerPort: 8443
          protocol: TCP
        volumeMounts:
        - mountPath: /root/project
          name: pvc-code-server
        securityContext:
          privileged: true
        resources:
          requests:
            cpu: 20m
      volumes:
      - name: pvc-code-server
        persistentVolumeClaim:
          claimName: "pvc-code-server"
---
apiVersion: v1
kind: Service
metadata:
  name: code-server
  namespace: default
  annotations:
    cloud.google.com/load-balancer-type: "internal"
  labels:
    run: code-server
spec:
  type: LoadBalancer
  #loadBalancerIP: [IP-ADDRESS]
  ports:
  - port: 80
    protocol: TCP
    targetPort: 8443
  selector:
    run: code-server
EOS
```

デプロイ後、Service に割り当てられた `EXTERNAL-IP` を確認
※今回は `EXTERNAL-IP` にはセキュリティを考慮してプライベートIP が割り当てられる設定にしています。

```bash
$ kubectl get svc hoge-code-server
NAME           TYPE           CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE
code-server    LoadBalancer   10.1.XXX.XXX  10.1.XXX.XXX  80:32304/TCP   3m
```

ブラウザから `http://<EXTERNAL-IP>/` へアクセス