Giter VIP home page Giter VIP logo

gunicorn-k8s-operator's Introduction

CharmHub Badge Publish to edge Promote charm Discourse Status

Gunicorn-k8s Operator

A Juju charm deploying docker images using gunicorn as default.

This charm simplifies docker image deployment management, allowing us to inject variables to the environment as we see fit. It allows for deployment on many different Kubernetes platforms, from MicroK8s to Charmed Kubernetes to public cloud Kubernetes offerings.

As such, the charm makes it easy for those looking to take control of their docker images, use them in a juju environment without having to write a charm from scratch and gives them the freedom to deploy on the Kubernetes platform of their choice.

For DevOps or SRE teams this charm will make docker image testing easier and more manageable. It will allow easy deployment into multiple environments for testing of changes, and supports scaling out for enterprise deployments.

Deployment options overview

For overall concepts related to using Juju see the Juju overview page. For easy local testing we recommend this how to on using MicroK8s with Juju.

Please generate src documentation for every commit. See the section below for more details.

Generating src docs for every commit

Run the following command:

echo -e "tox -e src-docs\ngit add src-docs\n" >> .git/hooks/pre-commit
chmod +x .git/hooks/pre-commit

How to deploy this charm (quick guide)

To deploy the charm and relate it to the PostgreSQL K8s charm within a Juju Kubernetes model:

juju deploy postgresql-k8s
juju deploy gunicorn-k8s
juju relate postgresql-k8s:db gunicorn-k8s:pg

The charm also supports the ingress relation, which can be used with nginx-ingress-integrator.

juju deploy nginx-ingress-integrator
juju relate gunicorn-k8s:ingress nginx-ingress-integrator:ingress

Once the deployment has completed and the "gunicorn-k8s" workload state in juju status has changed to "active" you can visit http://gunicorn-k8s in a browser (assuming gunicorn-k8s resolves to the IP(s) of your k8s ingress) or the juju unit's (gunicorn-k8s) assigned IP, and you'll be presented with a screen that details all the environment variables used by the deployed docker image.

Using your own image

You can, of course, supply our own OCI image. To do so, specify --resource gunicorn-image='image-location' at deploy time, or use juju attach-resource if you want to switch images after initial deployment. Gunicorn is expected to listen on port 8080 by default, but you can configure your own port if needed via the juju config external_port option.

For further details, see the charm's detailed documentation.

gunicorn-k8s-operator's People

Contributors

amandahla avatar arturo-seijas avatar axinojolais avatar github-actions[bot] avatar gregory-schiano avatar gtrkiller avatar jdkandersson avatar merkata avatar mthaddon avatar renovate[bot] avatar weiiwang01 avatar

Stargazers

 avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gunicorn-k8s-operator's Issues

Django Specific Enhancements

Enhancement Proposal

Hi,

I've been following the dev of this Gunicorn charm and it is a really cool general charm. What I'm hoping for is the ability to use it with my Django application which I feel has a pretty common workflow (even across non Django applications). Before I can do that however there are 2 things missing. To mold it to my needs, I've lifted a lot of the charm logic and made a specific charm for my application but I'm hoping I can switch over to this charm again when/if it fits my use case (my attempt at that can be seen here).

1. Nginx Sidecar
In order to server static files for my Django app I need Nginx setup as a sidecar container with the static files in the container and a config file for Nginx. Currently I've emulated what's done in the Indico operator charm and I have an image that installs Nginx and populates the static files + config and I deploy that alongside my workload container.

I can think of some options to accomodate this,

  • Create an additional resource in metadata.yaml that would accept an nginx image we could use for serving up static files. The user then needs to create a separate image with the static files and Nginx config and supply that image when deploying the gunicorn charm.
  • Don't create an additional resource but instead add some logic to the charm to automatically fetch an Nginx image and populate it with resources from the workload container using pebble.

An additional setting could also be added to config.yaml like NGINX_ENABLED which could potentially enable/disable the Nginx functionality if an app doesn't require it?

Alternatively, and I'm not sure if this is the right approach,

  • Identify/create an Nginx charm that would relate to the gunicorn charm and request a config and a tar of static files? This wouldn't be a sidecar though and I'm not sure how scaling would work here.

2. Running schema migrations
For my application I require that schema migrations are run when the app is deployed. Currently I set my app not to startup automatically, only once Postgres is related and the schema migration is run does the app start. The flow is,
Deploy app (Blocked waiting for postgres) -> Postgres related -> Schema migration run (set a peer relation value so that we don't run the migration again) -> start Gunicorn server.

The challenge here is that to make it general, every app will have it's own command and set of pre-conditions. In my application/charm, the command resembles the following,

process = container.exec(
                command=[
                    "/usr/bin/python3",
                    "/code/manage.py",
                    "migrate",
                    "--noinput",
                ],
                environment={"DATABASE_URL": db_uri},
            )

where db_uri is obtained from

pg_data = self._stored.reldata.get("pg", {})
db_uri = pg_data.get("db_uri")

and the pre-condition is that the Postgres relation exists (i.e. db_uri is populated).

In a conversation with @mthaddon the idea came up that the entrypoint of the image could be used to define the command and the pre-condition can be verified by checking that the required environment variables are set. I imagine the environment variables would be templatted as is done in the config.yaml, so setting something like the following perhaps inside your dockerfile,
ENTRYPOINT DATABASE_URL={{pg.db_uri}} python3 /code/manage.py migrate --noinput

Those 2 issues are pretty much it. Happy to discuss or elaborate further on anything above. Really cool work going on here, thanks!

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

This repository currently has no open or pending branches.

Detected dependencies

github-actions
.github/actions/build_oci_image/action.yaml
  • docker/setup-buildx-action v3
  • actions/checkout v4
  • docker/build-push-action v5
  • actions/upload-artifact v4
.github/actions/publish_oci_resource/action.yaml
  • actions/download-artifact v4
.github/workflows/auto_update_libs.yaml
.github/workflows/bot_pr_approval.yaml
.github/workflows/comment.yaml
.github/workflows/integration_test.yaml
.github/workflows/promote_charm.yaml
.github/workflows/publish_charm.yaml
.github/workflows/test.yaml
pip_requirements
requirements.txt
  • ops ==2.13.0

  • Check this box to trigger a request for Renovate to run again on this repository

charm should default to an `external_hostname` of `self.app.name`

Enhancement Proposal

This charm should default to an external_hostname of self.app.name.

So in other words, if you just do juju deploy gunicorn-k8s it should configure an external hostname of gunicorn-k8s.

If you do juju deploy gunicorn-k8s gunicorn it should configure an external hostname of gunicorn.

If you do juju deploy gunicorn-k8s --config external_hostname=foo.internal it should configure an external hostname of foo.internal.

We should update the default deploy documentation in the README to reflect that.

Environment output in default image should be alphabetically sorted

Enhancement Proposal

Currently if you spin up the default image and connect to the charm in a browser you get a dump of the environment variables that have been passed in.

It would be more readable if these were sorted alphabetically in case the user is looking for a particular variable.

Add a juju action to show all reldata in StoredState

Enhancement Proposal

When setting the environment variable for a particular workload, it's useful to know what variables are available to you, which are defined in reldata within StoredState.

The charm should have an action to show all the data so someone can more easily determine what to use in the environment variable.

This action should be called show-environment-context. We should also mention this in the description of the environment config option.

Allow for configurable container startup command

Enhancement Proposal

Currently the pebble layer for the charm is hard coded to use /srv/gunicorn/run as the startup command for workloads running in the "gunicorn" container. It would be more flexible if we defaulted to this, but allowed for it to be overrriden via Juju config. This would mean we can deploy more images unmodified.

Update default port to 8080, and expose port as a config option

Enhancement Proposal

Currently the charm expects a docker image that runs a web service on port 80.

We should change this to port 8080 as it's non-privileged and more common.

We should also expose the port as a configuration option to allow other workloads to be run without needing to modify the port they're listening on.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.