Library for deploying Elixir web apps to Kubernetes. Used in combination with docker_build
library.
It will build a docker image of your app, push it and then deploy it to K8S by creating a K8S Deployment
, Service
and Ingress
for your app. It will also request a SSL cert for your app using Cert manager. This typically is used to obtain Letsencrypt certificates but can be used with other providers.
- A K8S cluster with K8S >= v1.19
- The K8S cluster installed with Cert manager and a
ClusterIssuer
orIssuer
configured. kubectl
installed and configured to access your K8S server- A Docker registry available for your image. Gitlab currently provides a limited free private registry.
- Pull secrets configured on in your cluster namespace to access the image on the Docker registry
Add to mix.exs
:
def deps do
[
{:k8s_deploy, "~> 0.5.0", runtime: false, only: :dev}
]
end
Install and configure docker_build
to build your docker image for you.
Add the following entry in mix.exs
:
# mix.exs
def project do
[
...
k8s_deploy: k8s_deploy(),
...
]
end
defp k8s_deploy do
[
context: "my-k8s-cluster.com", # The kubectl context name in kubectl
image_pull_secrets: ["my-pull-secret"], # Unless a public docker image is used this must be set up before
cert_manager_cluster_issuer: "letsencrypt-cluster-prod", # This needs to be set up before.
host: "www.mysite.com" # HTTPS host
]
end
To build a docker image and deploy:
mix k8s.deploy
For additional options run:
mix help k8s.deploy
The following additional config values are available:
-
:namespace
- the K8S namespace to use. Must be set up before. Defaults todefault
. -
:cert_manager_issuer
- can be used instead of:cert_manager_cluster_issuer
for a namespaced issuer. -
:from_to_www_redirect?
- if your want theIngress
to perform an automatic redirection from the non-www
version of your site to thewww
version or vice versa. Defaults totrue
if the host starts withwww
. Specify the canonical version in:host
. -
:env_vars
- Map of environment variables that will be set in the K8SDeployment
. e.g.%{"FOO" => "BAR"}
. The following environment variables are automatically injected:PORT
- set to4000
URL_HOST
- set to the:host
value in the config (if set)
-
:migrator
- Module name or mfa tuple for running migrations. See "Running Migrations" below. -
:probe_path
- URL path (without host or port) to be used for a K8S containerreadinessProbe
andlivenessProbe
. Specify a URL that returns a 200 without a login. In most cases"/"
should be suitable. If not set, no probes are created. -
:probe_initial_delay_seconds
- Used forreadinessProbe
andlivenessProbe
if a:probe_path
is set. Defaults to 10. -
:resources
- Specify memory and CPU request and limit values. e.g.resources: [ requests: [ cpu: "100m", memory: "128Mi" ], limits: [ cpu: "200m", memory: "256Mi" ] ]
All the keys are optional, although if you specify
resources
you must specify at least one value.
Instead of providing environment variables via the :env_vars
key, you can provide a K8S ConfigMap
in the
deploy/k8s
folder with the name configmap-prod.yaml
. (If using a different environment change prod
to match).
The name of the ConfigMap
must match the :app_name
key specified in the docker_build
config, with the suffix -configmap
.
This will be referenced using envFrom
in the Deployment
.
For example:
---
apiVersion: v1
kind: ConfigMap
metadata:
name: myapp-configmap
data:
FOO: BAR
FOO2: BAR2
To run migrations set the :migrator
config key to either a module name, e.g MyApp.Release
which contains a migrate/0
function,
or a mfa, e.g. {MyApp.Release, :migrate, []}
. You can create the necessary code by following the recommendation
in Phoenix.
A K8S Job
will be created using the same docker image. It will execute the migrate function and run to completion before the deploy continutes. Any ConfigMap
or vars in :env_vars
will be available in to the Pod
container that the job creates.
If you omit the host
field, no ingress will be deployed (unless you have a custom template - see below). You might use this if another app deploys the ingress
rules for this app.
You can also specify :context
as a list. All K8S resources will then be deployed to each context in turn.
If you need to customise the templates beyond what the configuration options provide, you can place your
own template in your project in the location deploy/k8s/{resource}-{environment}.yaml
. For example
deployment-prod.yaml
for a custom Deployment
template.
These files can include EEx
templating and accept the same variables as the default templates (see priv/templates
),
e.g. <%= @deployment_id>
or <%= @docker_image %>
in the Deployment
template. N.B. The @deployment_id
variable is an integer so it must be quoted in your template.
- Run
git push origin master:production
after deploy - Have option to ask for key press before deploying
- Support different environments e.g.
mix k8s.deploy staging
with an environment setting and overrides in config - Block until deploy complete
- Check that cert issuers exist before continuing