Google Kubernetes Engine で Rails5 のアプリケーションを動かすための記事です。
puma + nginx をソケットで繋げて動かします。http から https にリダイレクトしたりするために nginx をリバースプロキシとして置いておくと、なにかと便利です。
Rails アプリケーションと nginx のコンテナをそれぞれ別に作って、同じポッド内で動かします。共有ボリュームにソケットファイルを置くことで、ふたつを繋げます。この記事では、この点について説明します。
puma + nginx の連携に関する詳しいことは、その他の記事などを参考にしてください。この記事の最後に、参考リンク一覧があります。
nginx の設定
まずは、nginx の設定です。server unix:///app/myapp/sockets/puma.sock;
の部分が重要です。
このあと、ソケットファイルを置くための共有ボリュームの作成について説明します。その共有ボリュームを nginx コンテナ上の/app/myapp/sockets
にマウントしています。
なので、マウントするパスを変える場合は、この設定を変える必要があります。
upstream puma {
server unix:///app/myapp/sockets/puma.sock;
}
server {
listen 80;
server_name puma;
location / {
proxy_read_timeout 300;
proxy_connect_timeout 300;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://puma;
}
}
Rails5 の設定
つぎに、Rails の設定です。RAILS_ROOT/config/puma.rb
を修正します。ソケットでの接続のためにRAILS_ROOT/tmp/sockets/puma.sock
を作成するようにする、よくあるやつです。
「Rails5でpuma + nginx連携」を参考にしました。
これも、bind の値を変える場合は、このあとの設定も変える必要があります。
# port ENV.fetch("PORT") { 3000 }
...
bind "unix://#{Rails.root}/tmp/sockets/puma.sock"
Deployment の設定
さいごに、Deployment の設定です。関係ない設定も多いですが、今回は、コメントをつけた、[1]、[2]、[3]の部分が関係あります。
myapp が Rails アプリケーションのコンテナ、myapp-nginx が nginx のコンテナです。
[1] の volumes の設定で、共有ボリュームが作成されるようにます。
[2] の volumeMounts の設定で、nginx コンテナ上の/app/myapp/sockets
に共有ボリュームをマウントしています。name には [1] の name を指定します。この例では sockets です。
[3] も [2] と同じ要領で Rails アプリケーションのコンテナ上の/app/myapp/tmp/sockets
に共有ボリュームをマウントしています。
この設定で、Rails アプリケーションと nginx の、それぞれ別々のコンテナが同じ puma.sock を参照することができ、連携が可能になります。
apiVersion: "extensions/v1beta1"
kind: "Deployment"
metadata:
name: "myapp"
namespace: "default"
labels:
app: "myapp"
spec:
replicas: 1
selector:
matchLabels:
app: "myapp"
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
minReadySeconds: 5
template:
metadata:
labels:
app: "myapp"
spec:
# [1]
volumes:
- name: "sockets"
emptyDir: {}
containers:
- name: "myapp-nginx"
image: "asia.gcr.io/[PROJECT_NAME]/myapp-nginx:latest"
# [2]
volumeMounts:
- name: "sockets"
mountPath: "/app/myapp/sockets"
livenessProbe:
httpGet:
scheme: HTTP
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 10
- name: "myapp"
image: "asia.gcr.io/[PROJECT_NAME]/myapp:latest"
# [3]
volumeMounts:
- name: "sockets"
mountPath: "/app/myapp/tmp/sockets"
envFrom:
- configMapRef:
name: myapp-env-config
- secretRef:
name: myapp-env-secret
おしまい。