Deploy
Create a simple app
To create a new Phoenix project, open your terminal and run the following command:
mix phx.new ping_pong_app --no-html --no-ecto --no-dashboard
Navigate into your new project directory:
cd ping_pong_app
~/pg/cloud/ping_pong_app/lib/ping_pong_app_web/controllers/page_controller.ex
defmodule PingPongAppWeb.Controllers.PageController do
use PingPongAppWeb, :controller
def index(conn, _params) do
data = %{
message: "Hello, world!"
}
json(conn, data)
end
end
~/pg/cloud/ping_pong_app/lib/ping_pong_app_web/router.ex
scope "/api", PingPongAppWeb do
pipe_through :api
get "/ping", Controllers.PageController, :index
end
Prepare a Dockerfile
~/pg/cloud/ping_pong_app/Dockerfile
FROM elixir:1.16.0-alpine as builder
RUN apk add --no-cache build-base git openssl-dev ca-certificates
WORKDIR /app
COPY mix.exs mix.lock ./
COPY config config/
COPY lib lib/
COPY priv priv/
COPY assets assets/
RUN mix deps.get --only prod
RUN mix deps.compile
ENV MIX_ENV=prod
RUN mix compile
RUN mix release
FROM alpine:3.18
RUN apk add --no-cache openssl ncurses-libs libstdc++
WORKDIR /app
COPY --from=builder /app/_build/prod/rel/ping_pong_app ./
ENV PORT=8080
EXPOSE 8080
CMD ["/app/bin/ping_pong_app", "start"]
google cloud
gcloud auth login
gcloud projects list
echo 'export GCLOUD_PROJECT_ID=<your project id>'
direnv allow
gcloud config set project $GCLOUD_PROJECT_ID
Build and Push Image
docker buildx create --name mybuilder --use
docker buildx inspect --bootstrap
brew install docker-credential-helper
gcloud auth configure-docker
docker buildx build \
--platform linux/amd64 \
-t gcr.io/$GCLOUD_PROJECT_ID/ping-pong-app:v1 \
--push .
docker push gcr.io/$GCLOUD_PROJECT_ID/ping-pong-app:v1
Create a GKE cluster
gcloud container clusters create ping-pong-cluster \
--zone us-central1-c \
--num-nodes 1 \
--machine-type e2-micro \
--enable-ip-alias
Authenticates your local kubectl CLI with the GKE cluster:
gcloud components install gke-gcloud-auth-plugin
gcloud container clusters get-credentials ping-pong-cluster --zone us-central1-c
kubectl get node
Prepare k8s configuration
~/pg/cloud/ping_pong_app/k8s/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: ping-pong-deployment
labels:
app: ping-pong-app
spec:
replicas: 1
selector:
matchLabels:
app: ping-pong-app
template:
metadata:
labels:
app: ping-pong-app
spec:
containers:
- name: ping-pong-app
image: gcr.io/YOUR_PROJECT_ID/ping-pong-app:v1 # Replace with your project ID
ports:
- containerPort: 8080
env:
- name: HOST
value: "0.0.0.0"
- name: PORT
value: "8080"
~/pg/cloud/ping_pong_app/k8s/service.yaml
apiVersion: v1
kind: Service
metadata:
name: ping-pong-service
spec:
selector:
app: ping-pong-app # Selects pods with this label
ports:
- protocol: TCP
port: 80 # The port the service exposes
targetPort: 8080 # The port on the pod to forward traffic to
type: LoadBalancer # Creates an external IP address
Deploy
kubectl apply -f k8s/
deployment.apps/ping-pong-deployment created
service/ping-pong-service created
kubectl get pods -l app=ping-pong-app
kubectl get pods -l app=ping-pong-app -o jsonpath='{.items[0].metadata.name}'
kubectl logs YOUR_POD_NAME
Visit your app
kubectl get service ping-pong-service
Clean up
kubectl delete -f k8s/
gcloud container clusters delete ping-pong-cluster --zone us-central1-c
gcloud container images list
gcloud container images list-tags gcr.io/$GCLOUD_PROJECT_ID/ping-pong-app
gcloud container images delete gcr.io/$GCLOUD_PROJECT_ID/ping-pong-app:v1