knowledge-kitchen
/
course-notes
class: center, middle # Deployment Making an application live and available to its users. --- # Agenda 1. [Overview](#overview) 1. [Moving on from development servers](#dev-prod-servers) 1. [Production environment](#production-environment) 1. [Cloud deployments](#cloud-deployments) 1. [Virtual machines and containers](#virtualization) 1. [Kubernetes](#kubernetes) 1. [Continuous deployment](#cd) 1. [Conclusions](#conclusions) --- name: overview # Overview -- name: definitions ## Definitions A few terms to disambiguate. --- template: definitions ### Delivery - **Delivery** is placing an app into its target environment and preparing it to be accessed by its end-users, but not actually executing it. -- - **Continuous delivery** is automatically delivering new versions every time a change is made to the underlying code. --- template: definitions ### Deployment - **Deployment** is placing an app into its target environment, executing it, and making it available to its end-users. -- - **Continuous deployment** is automatically deploying new versions every time a change is made to the underlying code. --- template: definitions ![Atlassian's CI/CD diagram](../assets/deployment/ci-cd-disambiguation.png "CI/CD diagram courtesy of Atlassian") --- template: overview ## Caveats New releases of software, of course, must still successfully build and pass unit, integration and system tests before deployment. -- - Thus, Continuous Deployment is a follow-up to [Continuous Integration](../continuous-integration), where tests are automatically run and re-run with every code change. --- template: overview ## Automation Pipeline With [version control](../version-control-systems), [code linters](../software-testing/#code-linting), [large language model-based code assistants](https://github.blog/2022-09-07-research-quantifying-github-copilots-impact-on-developer-productivity-and-happiness/), [automated provisioning of virtual computing environments](../containers), [automated builds](../build-tools), and [automated testing](../continuous-integration), continuous deployment is the natural evolution of a fully automated software development and operations (devops) pipeline. --- name: dev-prod-servers # Moving on from development servers -- ## Overview Many application development frameworks, including [Flask](../flask-pymongo) and [React](/content/courses/agile-development-and-devops/slides/react-intro), come with development servers. -- For example: -- - the `flask run` command launches the [development server for a Flask-based application](https://flask.palletsprojects.com/en/stable/server/) -- - the `npm start` command typically launches the [development server for a React-based application](https://createreactapp.github.io/starting-the-create-react-app-development-server) -- These are simple web servers that can be easily run on a development machine for quick debugging and [testing](../software-testing). However, they are **not intended for use in production environments**. --- template: dev-prod-servers ## Limitations of a development server Development servers are not intended for use in production environments. Typically, development servers are... -- - _single-threaded_ - meaning they handle requests sequentially, one at a time, potentially leading to long wait times for users when the server is under heavy load -- - _insecure_ - they are designed for simplicity for use on personal machines, not with security as a major concern -- - _unreliable_ - they are designed to function well for short periods of time, and not tested in environments where they are used as long-running processes --- template: dev-prod-servers ## Production servers Production servers are intended to be _better optimized_ for heavy loads, _more secure_, and _more reliable_ than development servers. -- - Flask-based applications often use [Gunicorn](https://flask.palletsprojects.com/en/stable/deploying/gunicorn/) as a production server. -- - React-based applications often use [Nginx](https://www.nginx.com/) or [Apache](https://httpd.apache.org/), or both as a production server. --- template: dev-prod-servers ## Product servers (continued) Tutorials are readily available to give guidance to the process of publishing apps to production servers. For example... -- Using Digital Ocean's [Droplets](https://www.digitalocean.com/products/droplets): - [Deploying a Flask app to a Digital Ocean Droplet](https://www.digitalocean.com/community/tutorials/how-to-serve-flask-applications-with-gunicorn-and-nginx-on-ubuntu-22-04) - [Deploying a React app to a Digital Ocean Droplet](https://www.digitalocean.com/community/tutorials/deploy-react-application-with-nginx-on-ubuntu) -- Using Digital Ocean's [App Platform](https://www.digitalocean.com/products/app-platform): - [Deploying a Flask app to Digital Ocean's App Platform](https://www.digitalocean.com/community/tutorials/how-to-deploy-a-flask-app-using-gunicorn-to-app-platform) - [Deploying a React app to Digital Ocean's App Platform](https://www.digitalocean.com/community/tutorials/how-to-deploy-a-react-application-to-digitalocean-app-platform) --- name: production-environment # Production environment -- ## Hosting tiers There are several tiers of hosting available for apps that can be deployed and accessed over the Internet, with many companies and services catering to each type - Shared hosting - Dedicated machines - Virtual Private Servers (VPS) - Cloud services --- template: production-environment ## Hosting tiers (continued) ![Hosting tiers](../assets/deployment/shared-hosting.png) --- template: production-environment ## Shared hosting With shared hosting, a developer receives an account on a web server shared by hundreds, if not thousands, of other developers. - Historically the cheapest form of hosting. - If one developer consumes more resources than expected, other developers may feel the effects... the "_noisy neighbor_" problem. - Has restrictions on what is allowed to be done from a user account... no admin rights. - No choice of hardware... limited choice of software. -- Universities and other large organizations often provide shared hosting for their community members. --- template: production-environment ## Dedicated machine With a dedicated machine, i.e. a [bare metal server](https://knowledge.kitchen/content/courses/software-engineering/slides/containers/#7), developers buy or rent a single physical machine managed by either themselves or the hosting company from whom it is rented. - A dedicated physical machine... no [virtualization](https://knowledge.kitchen/content/courses/software-engineering/slides/containers/#36)... no neighbors. - Admin rights to do whatever you want with it. - Software and hardware management services usually offered at additional cost. - Resources limited by the physical machine. --- template: production-environment ## Virtual Private Servers (VPS) With VPS, a developer receives a virtual machine running on a physical machine shared by hundreds, if not thousands, of other users. - A step up from shared hosting, giving more control and better isolation. - Each virtual machine runs in an isolated, sandboxed environment, so one account is unaffected by resourcee usage of another... no "noisy neighbor" problem. - Developers have discretion to do whatever they want in their virtual machine. - Choice of emulated hardware and software. - Resources limited by the physical machine upon which virtual machine is running. --- template: production-environment ## Cloud deployments Deploying to "the cloud" is a catch-all term for deploying to a remote server that is [managed by a third party](https://www.zdnet.com/article/stop-saying-the-cloud-is-just-someone-elses-computer-because-its-not/). --- template: production-environment ## Cloud deployments (continued) ![Cloud versus VPS](../assets/deployment/vps-versus-cloud.png) --- name: cloud-deployments # Cloud deployments -- ![The cloud is just someone else's computer](../assets/deployment/the-cloud-someone-else.png) --- template: cloud-deployments ## Cloud services "_The cloud_" is usually used to mean a grid of hundreds or thousands of physical computers all inter-networked and sharing resources, but presented to a developer as a single virtual machine. - Any one application may run spread across many different physical machines. --- template: cloud-deployments ## Cloud resources Cloud services providers offer a variety of resources to developers. - **Compute services**, i.e. virtual machines and/or containers running app code. - **Databases**, i.e. SQL and NoSQL data storage - **Storage**, i.e. file system where files are stored - **Networking**, i.e. IP addresses, DNS, and other configurations that multiple services for a single app need to communicate with one-another. In addition to these, there are many accessory services such as load balancing, monitoring, logging, analytics, security, etc. --- template: cloud-deployments ## Big tech The world of cloud deployment is dominated by a few players: - [Amazon Web Services](https://aws.amazon.com/) - [Microsoft Azure](https://azure.microsoft.com/) - [Google Cloud](https://cloud.google.com/) - [IBM Cloud](https://www.ibm.com/cloud) Their offerings are generally industrial-strength hosting solutions with obtuse interfaces and extensive capabilities that may be overkill and intimidating for non-specialists. --- template: cloud-deployments ## X-as-a-Service The cloud is often referred to as a "_service_", with a few common levels of service available to [paying] customers: ![X-as-a-Service](../assets/deployment/x-as-a-service.png) _Image courtesy of Microsoft Azure's "[What is PaaS](https://azure.microsoft.com/en-gb/resources/cloud-computing-dictionary/what-is-paas/)"._ --- template: cloud-deployments ## Infrastructure-as-a-Service (IaaS) Some services handle much of the setup of a cloud infrastructure (compute resources, storage resources, networking interoperability, etc) without requiring the user to configure all details. - [Amazon Lightsail](https://aws.amazon.com/lightsail/) - [Amazon CloudFormation](https://aws.amazon.com/cloudformation/) - [Microsoft Azure](https://azure.microsoft.com/en-gb/resources/cloud-computing-dictionary/what-is-azure/azure-iaas/#products) - [Google Cloud](https://cloud.google.com/solutions/infrastructure-modernization) - [Digital Ocean](https://www.digitalocean.com) - [IBM Cloud Foundry](https://www.cloudfoundry.org/the-foundry/ibm-cloud-foundry/) - [Linode](https://www.linode.com/) From IaaS, developers leverage The Cloud to receive the necessary preconfigured [virtual] hardware and networking abilites upon which to develop. --- template: cloud-deployments ## Platform-as-a-Service (PaaS) Whereas IaaS provides the pre-set hardware and networking of a cloud deployment, PaaS additional provide the pre-set configuration of dependencies and platforms necessary to deploy a specific type of application. - [Amazon AWS Elastic Beanstalk](https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/Welcome.html) - [Microsoft Azure Web Apps](https://azure.microsoft.com/en-us/products/app-service/web/?b=17.09) - [Google App Engine](https://cloud.google.com/appengine/) - [Digital Ocean App Platform](https://www.digitalocean.com/products/app-platform) - [IBM Cloud Foundry](https://www.cloudfoundry.org/the-foundry/ibm-cloud-foundry/) - [Salesforce Platform](https://www.salesforce.com/products/platform/overview/) - [Platform.sh](https://platform.sh/) - [Dokku](https://dokku.com/) From PaaS, developers receive an environment with platform systems already setup on an appropriate cloud compute and storage inrastructure and they can simply get to work on a specific type of project development. --- template: cloud-deployments ## Considerations when choosing IaaS versus PaaS A few considerations when deciding whether to go with IaaS or PaaS: -- - **IaaS** is fully customizable, whereas **PaaS** works best if you closely follow common conventions and patterns. -- - **IaaS** requires more setup and maintenance compared to **PaaS**, since it is more hands-on and configurable. -- - **IaaS** services will cost less than **PaaS** for the same basic resources, since there is less abstraction and less automation included. -- - As a general rule, **IaaS** may be more suitable for large, complex, or custom applications. **PaaS** may be better suited for small, simple, or conventional applications. --- name: virtualization # Virtual machines and containers -- ## Overview Cloud compute services are provided as either virtual machines or [containers](../containers). -- - Containers are a more lightweight, portable variation of a virtual machine, where the operating system is not included in the virtual environment. -- - Cloud-based virtual machines can run containers, if desired. -- - Additionally, some providers offer container services directly, abstracting away the virtual machines so developers don't have to worry about where the container is being run. --- template: virtualization ## Overview (continued) ![Virtual machines versus containers](../assets/containers/comparison-of-server-virtualization-systems.png) - Note that a container contains only the necessary dependencies needed to run an application, and do not contain the full operating system, whereas virtual machines do. --- template: virtualization ## Example For example, Digital Ocean, provides both virtual machines, which they call [Droplets](https://www.digitalocean.com/products/droplets), and container deployments using their [App Platform](https://www.digitalocean.com/products/app-platform) or [Kubernetes](https://www.digitalocean.com/products/kubernetes) services. -- - A simple and cheap setup would be to launch a single **Droplet**, clone all necessary code repositories to it from GitHub, and manually launch the subsystems directly on the Droplet. Multiple sub-systems can be run on different ports of the same virtual machine, as necessary. This is an example of simple Infrastructure-as-a-Service. -- - A simple setup that betrays a more advanced toolset would be to use the **App Platform** service to build and launch containers automatically hosting each subsystem of your application. This is an example of Platform-as-a-Service. -- - If a more custom container setup is desired, the **Kubernetes** service allows developers to configure a cluster of virtual machines to run containers. This is an example of Infrastructure-as-a-Service. --- name: kubernetes # Kubernetes -- ## Overview [Kubernetes](https://kubernetes.io/) (a.k.a. `k8s`) is a container "orchestrator" - it manages the deployment of containers across a cluster of machines. -- - a "_cluster_" is a group of machines in a "cloud" data center that work together to run a single service. -- - a "_node_" is a single machine in a cluster, usually a virtual machine but could be physical. -- - a "_pod_" is a group of one or more containers that run together on a single node, with a single IP address and other shared resources. --- template: kubernetes ## Comparison to Docker Compose [Docker Compose](../containers#docker-compose), which also orchestrates containers, and kubernetes are designed for different use cases. -- - Docker Compose can orchestrate a set of containers _all running on the same machine_. This is usually fine for small deployments with a limited number of containers. -- - For larger deployments, where multiple instances of each container might be needed, or where the containers will not necessarily all be running on the same machine, kubernetes is the orchestrator of choice. -- - Kubernetes implementations usually start with at least 3 nodes for redundancy. --- template: kubernetes ## Components of a Kubernetes cluster ![Kubernetes cluster](../assets/deployment/kubernetes-cluster.png) --- template: kubernetes ## Components of a Kubernetes cluster (continued) Each node in a cluster runs a container using a container runtime engine, like [Docker](https://docker.com) or [containerd](https://containerd.io/). -- - The nodes within a cluster are managed by a "**Control Plane**" that makes sure applications within the cluster are running with the correct configuration in the desired state. -- - Each node in the cluster runs "**Kubelet**" - software that manages the containers running on that node and communicates with the control plane. -- - Developers typically interact with the cluster using the "[kubectl](https://kubernetes.io/docs/tasks/tools/)" command-line tool to deploy, inspect, and manage cluster resources. --- name: cd # Continuous deployment -- ## Overview Continuous Deployment (CD) is the process of automatically deploying new versions of a software application to a production environment with every change to the codebase. -- - Continuous Deployment usually follows Continuous Integration (CI; automated builds and tests), in what is known as the **CI/CD pipeline**. -- - CD would only take place if the CI tests pass. -- - The same tools and processes used for CI can be used for CD. For example, [GitHub Actions](https://github.com/features/actions), [Jenkins](https://jenkins.io/), [Travis CI](https://travis-ci.com/), and [Circle CI](https://circleci.com/) all can be used for both CI and CD. --- template: cd ## Simple pipeline A CI/CD pipeline for a simple application, such as one running on a single virtual machine, might involve the following steps: -- 1. Developer pushes code to a repository (e.g. GitHub, GitLab, Bitbucket, etc.) -- 2. CI server (e.g. GitHub Actions, Jenkins, Travis CI, Circle CI, etc.) builds and runs tests on the code. -- 3. If the tests pass, the CI server _copies the code to the production environment_, e.g. by [using the `rsync` command](https://www.digitalocean.com/community/tutorials/how-to-use-rsync-to-sync-local-and-remote-directories) to copy the code from the build server to the production server. -- 4. The production server deploys the application by stopping and restarting it. -- 5. The updated application is now available to users. --- template: cd ## Simple containerized pipeline A similar CI/CD pipeline that runs the application either directly with Docker or using Docker Compose (but not using Kubernetes) might involve the following: -- 1. Developer pushes code to a repository (e.g. GitHub, GitLab, Bitbucket, etc.) -- 2. CI server (e.g. GitHub Actions, Jenkins, Travis CI, Circle CI, etc.) builds and runs tests on the code. -- 3. If the tests pass, the CI server _uploads the built Docker image to a container registry_ such as DockerHub. -- 4. The CI server _deploys a container using the new image_ to the production environment using [`docker` or `docker-compose` commands](https://faun.pub/full-ci-cd-with-docker-github-actions-digitalocean-droplets-container-registry-db2938db8246). -- 5. The updated application is now available to users. --- template: cd ## Even simpler containerized pipeline An even simpler containerized pipeline does not require the developer to develop a Docker image of their own system in order to use containers. - Digital Ocean's **App Platform** and similar services can automatically create a Docker image from a code repository and then automatically instantiate containers from this image and deploy them. --- template: cd ## Kubernetes pipeline Deploying to a Kubernetes cluster follows similar steps: -- 1. Developer pushes code to a repository (e.g. GitHub, GitLab, Bitbucket, etc.) -- 2. CI server (e.g. Jenkins, Travis CI, Circle CI, GitHub Actions, etc.) builds and runs tests on the code. -- 3. If the tests pass, the CI server _uploads the built Docker image to a container registry_ such as DockerHub,' -- 4. The CI server _deploys a kubernetes cluster using the new image_ [using `kubectl` commands](https://developer.ibm.com/blogs/use-a-github-action-to-deploy-an-app-to-kubernetes/). -- 5. The updated application is now available to users. --- name: conclusions # Conclusions Thank you. Bye.