This tutorial will show you how to deliver assets from the S3 compatible SysEleven Object Storage with ingress-nginx. As the SysEleven Object Storage does not support CORS headers at this time, this is necessary to avoid CORS errors.
For more detailed information about CORS, check out Mozilla’s great documentation.
You will need:
For this configuration to work, your assets have to be served at one or more distinct paths, e.g. /assets
or /img
as all requests to those paths will be served from the S3 bucket.
To use the S3 bucket as upstream for the ingress-nginx, we need to make it available as a Service:
apiVersion: v1
kind: Service
metadata:
name: assets
spec:
type: ExternalName
externalName: $BUCKET.s3.$REGION.cloud.syseleven.net
Replace
$BUCKET
with the name of your bucket, e.g. assets-test
$REGION
with the region where your bucket is located (e.g. dbl
)Then we only need to add an Ingress resource for the paths that the assets have:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/backend-protocol: HTTPS
nginx.ingress.kubernetes.io/upstream-vhost: $BUCKET.s3.$REGION.cloud.syseleven.net
name: assets-ingress
spec:
# No TLS config needed, only one ingress for a hostname needs to have the TLS config, see https://github.com/kubernetes/ingress-nginx/issues/4106#issuecomment-494305090
rules:
- host: $APPLICATION_HOSTNAME
http:
paths:
- path: /img/
backend:
serviceName: assets
servicePort: 443
- path: /css/
backend:
serviceName: assets
servicePort: 443
Replace
$BUCKET
with the name of your bucket, e.g. assets-test
$REGION
with the region where your bucket is located (e.g. dbl
)$APPLICATION_HOSTNAME
with the host name your application is served atand add as many elements to path
as you need.
Once you’ve applied both resources, all requests to the specified paths for your hostname will be served from the bucket, all other requests will still go to your application.
Please note that for this to work, the asset paths in the Ingress above must always be the most specific paths. If the Ingress resource of your application has e.g. configuration for the path /img/backend
, requests to this path will still go to your application.
To use this in production, you need to consider that this adds the Object Storage bucket as a dependency on the server side. Therefore, faults of the backend should be handled gracefully by tuning timeouts and retry values for the Ingress object.
For assets, allowing them to be cached for a very long time is usually desirable. Consider adding the relevant headers with a nginx.ingress.kubernetes.io/configuration-snippet
annotation.
As resources are served indirectly from the bucket, this will introduce a small latency overhead.