Deploying a web application can be a challenging task, especially if you want to ensure that your application can handle high traffic, provide high availability, and comply with security and regulatory standards. Fortunately, there are tools and platforms that can help you achieve these goals, such as and Aptible Kubernetes . is a platform that simplifies the deployment and management of secure and compliant web applications. Aptible provides features such as automated provisioning, encryption, backups, logging, monitoring, and auditing for your web applications. Aptible also helps you comply with various such as HIPAA, SOC 2, ISO 27001, and GDPR. Aptible standards and regulations, Learn More Learn why Aptible's Engineering-Led Support and Production-Ready SLAs makes them a great choice for you. Read here is an open-source system that automates the deployment, scaling, and management of containerized applications. Kubernetes allows you to run your web application in a cluster of servers, called , that can be distributed across different regions and providers. Kubernetes also provides features such as , service discovery, self-healing, , rolling updates, and more. Kubernetes nodes load balancing horizontal scaling In this article, you will learn how to deploy a with Aptible and Kubernetes. You will use Aptible to create a secure and compliant environment for your web application and Kubernetes to orchestrate the deployment and scaling of your web application across multiple nodes. You will also learn how to use some of the key concepts and components of Aptible and Kubernetes, such as: scalable web application : The smallest unit of deployment in Kubernetes. A pod is a group of one or more containers that share the same network and storage resources. Pods : An abstraction that defines a logical set of pods and a policy to access them. A service provides a stable endpoint for your pods, regardless of their location or state. Services : An abstraction that manages the creation and update of pods. A deployment allows you to specify the desired state of your pods, such as the number of replicas, the image version, the update strategy, etc. Kubernetes will ensure that your pods match the desired state. Deployments : A logical grouping of resources in Aptible. An environment consists of one or more , which are the web applications that you deploy with Aptible; one or more , which are the data stores that you provision with Aptible; and one or more endpoints, which are the entry points for accessing your apps and databases. Aptible Environments apps databases Content Overview Prerequisites Step 1: Create an Aptible app and configure your environment variables Step 2: Build and push your web application image to a container registry Step 3: Create a Kubernetes deployment and service for your web application Step 4: Expose your web application service to the internet with Aptible endpoints Step 5: Test and verify your web application deployment Conclusion Prerequisites To follow this article, you will need: An . You can sign up for a Aptible account free trial here. A . You can use any provider that supports Kubernetes, such as Google Cloud Platform (GCP), Amazon Web Services (AWS), Microsoft Azure, etc. You can also use a local cluster for testing purposes, such as Minikube or Docker Desktop. Kubernetes cluster A . You can use any programming language or framework that supports web development, such as Ruby on Rails, Django, Node.js, etc. You can also use an existing web application or clone one from GitHub. web application codebase A . A file that defines how to build a Docker image for your web application. You can Dockerfile learn how to write a Dockerfile here. A A tool that allows you to interact with your Kubernetes cluster. You can . kubectl command-line tool. install kubectl here A . A tool that allows you to manage your code versioning and deployment with Aptible. Git command-line tool By the end of this article, you will have deployed a scalable web application with Aptible and Kubernetes and learned how to use some of the best practices and tools for web development. Let's get started! Step 1: Create an Aptible app and configure your environment variables Before you can deploy your web application with Aptible, you need to create an app and configure your environment variables. An app is a logical unit of deployment in Aptible that represents your web application. Environment variables are key-value pairs that store configuration settings for your app, such as database credentials, API keys, etc. You can use either the or the to create an app and configure your environment variables. In this article, we will use the Aptible CLI, which is a command-line tool that allows you to interact with Aptible. Aptible CLI Aptible dashboard To create an app with the Aptible CLI, you need to: Log in to your Aptible account using the command. You will be prompted to enter your email and password, and then a verification code sent to your email. aptible login Choose an environment for your app using the command. An environment is a logical grouping of resources in Aptible, such as apps, databases, and endpoints. You can have multiple environments for different purposes, such as development, staging, or production. In this article, we will use the environment, which is created by default when you sign up for Aptible. aptible switch production Create an app using the command. You need to provide a name for your app, which must be unique within your environment. In this article, we will name our app . aptible apps:create web-app Please you can use any name other than “web-app" Here is an example of the commands to create an app with the Aptible CLI: $ aptible login Email: user@example.com Password: ******** Verification code: 123456 Logged in as user@example.com $ aptible switch production Switched to production $ aptible apps:create web-app App web-app created! To configure your environment variables with the Aptible CLI, you need to: - List the existing environment variables for your app using the command. You will see some default environment variables that are set by Aptible, such as , , etc. aptible config APTIBLE_APP_ID APTIBLE_APP_HANDLE - Add new environment variables for your app using the command. You need to provide the key and value for each environment variable, separated by a space. You can add multiple environment variables at once by separating them with a space as well. In this article, we will add some environment variables that are required by our web application, such as , , , etc. aptible config:set DATABASE_URL SECRET_KEY_BASE RAILS_ENV - Verify that your environment variables are set correctly using the command again. aptible config Here is an example of the commands to configure your environment variables with the Aptible CLI: $ aptible config --app web-app APTIBLE_APP_ID=123 APTIBLE_APP_HANDLE=web-app ... $ aptible config:set --app web-app DATABASE_URL=postgres://user:password@host:port/db SECRET_KEY_BASE=abcdefg RAILS_ENV=production DATABASE_URL=postgres://user:password@host:port/db SECRET_KEY_BASE=abcdefg RAILS_ENV=production $ aptible config --app web-app APTIBLE_APP_ID=123 APTIBLE_APP_HANDLE=web-app DATABASE_URL=postgres://user:password@host:port/db SECRET_KEY_BASE=abcdefg RAILS_ENV=production ... You have now created an app and configured your environment variables with Aptible. Step 2: Build and push your web application image to a container registry Next, you need to build and push your web application image to a container registry. A web application image is a file that contains all the code, dependencies, and configuration of your web application. A container registry is a service that stores and distributes your web application images. You can use or any other similar tool to build your web application image and tag it with a version number. Docker is a software that allows you to create, run, and share containers. A container is an isolated environment that runs your web application image. You can install Docker here. Docker To build your web application image with Docker, you need to: - Navigate to the directory where your web application codebase and Dockerfile are located using the command. cd - Build your web application image using the command. You need to provide a name and a tag for your image, which must be unique within your container registry. The name and tag are separated by a colon ( ). In this article, we will name our image and tag it with . docker build : web-app v1 - Verify that your web application image is built correctly using the command. You will see your image listed along with its name, tag, size, and creation date. docker images Here is an example of the commands to build your web application image with Docker: $ cd web-app $ docker build -t web-app:v1 . Sending build context to Docker daemon 2.048kB Step 1/8 : FROM ruby:2.7 ... Successfully built 123456789abc Successfully tagged web-app:v1 $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE web-app v1 123456789abc 10 seconds ago 1.23GB To push your web application image to a container registry, you need to: - Log in to your container registry account using the command. You will be prompted to enter your username and password, and then a verification code if required. docker login - Push your web application image using the command. You need to provide the name and tag of your image, as well as the name of your container registry. The name of your container registry is usually prefixed to the name of your image, separated by a slash ( ). In this article, we will use as our container registry, which is a public service that hosts and distributes Docker images. We will prefix our image name with our Docker Hub username, which is . docker push / Docker Hub user - Verify that your web application image is pushed correctly using the command again. You will see a message indicating that your image was pushed successfully. docker images Here is an example of the commands to push your web application image to Docker Hub: $ docker login Username: user Password: ******** Verification code: 123456 Login Succeeded $ docker push user/web-app:v1 The push refers to repository [docker.io/user/web-app] ... 123456789abc: Pushed v1: digest: sha256:abcdefg size: 1234 $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE user/web-app v1 123456789abc 10 seconds ago 1.23GB Alternatively, you can use another container registry of your choice, such as , etc. Each container registry may have different requirements and steps for logging in, pushing, and pulling images. You can refer to their respective documentation for more details. Google Container Registry (GCR) Amazon Elastic Container Registry (ECR), Microsoft Azure Container Registry (ACR), You have now built and pushed your web application image to a container registry. Step 3: Create a Kubernetes deployment and service for your web application After you have pushed your web application image to a container registry, you need to create a Kubernetes deployment and service for your web application. A deployment is an object that manages the creation and update of your pods, which are the smallest unit of deployment in Kubernetes. A service is an object that defines a logical set of pods and a policy to access them, such as load balancing, service discovery, etc. You can use to define your Kubernetes deployment and service objects for your web application. YAML is a human-readable data format that allows you to specify the configuration and properties of your Kubernetes objects. You can use any text editor to create and edit YAML files. YAML files To define your Kubernetes deployment object with a YAML file, you need to: - Create a file with a or extension, such as . .yaml .yml deployment.yaml - Specify the , , , and fields for your deployment object. apiVersion kind metadata spec These fields are required for any Kubernetes object: The field indicates the version of the Kubernetes API that you are using. In this article, we will use , which is the latest stable version for deployments. apiVersion apps/v1 The field indicates the type of the Kubernetes object. In this case, it is . kind Deployment The field contains information about the name, labels, annotations, etc. of your deployment object. Labels are key-value pairs that can be used to identify and group your Kubernetes objects. Annotations are key-value pairs that can be used to store additional information or metadata about your Kubernetes objects. metadata The field contains the desired state and behavior of your deployment object, such as the number of replicas, the pod template, the update strategy, etc. spec Specify the , , and fields within the field for your deployment object. These fields are required for any deployment object. selector template eplicas spec The field defines how to select the pods that belong to your deployment object. You need to provide a field that contains one or more labels that match the labels of your pods. selector matchLabels The field defines the pod template that will be used to create new pods for your deployment object. You need to provide a field that contains the labels of your pods, and a field that contains the configuration and properties of your pods, such as the containers, volumes, environment variables, etc. emplate metadata spec The field defines the number of pods that you want to run for your deployment object. You can specify any positive integer value. In this article, we will use 3 replicas for our deployment object. replicas - Specify the , , and fields within the field of the pod template for your deployment object. containers image ports spec These fields are required for any pod that runs a containerized application. The field defines one or more containers that will run in your pod. You need to provide a name and an image for each container. The name can be any string that identifies your container within your pod. The image is the name and tag of your web application image that you pushed to your container registry in the previous step. You need to prefix the image name with the name of your container registry, separated by a slash ( ). In this article, we will prefix our image name with our Docker Hub username, which is . containers / user The field defines the name and tag of your web application image that you pushed to your container registry in the previous step. You need to prefix the image name with the name of your container registry, separated by a slash ( ). image / - The field defines one or more ports that will be exposed by your container. You need to provide a name and a containerPort for each port. The name can be any string that identifies your port within your container. The containerPort is the port number that your web application listens on within your container. In this article, we will use 3000 as our containerPort for our web application. ports Here is an example of a YAML file that defines a Kubernetes deployment object for our web application: apiVersion: apps/v1 kind: Deployment metadata: name: web-app-deployment labels: app: web-app spec: selector: matchLabels: app: web-app template: metadata: labels: app: web-app spec: containers: - name: web-app-container image: user/web-app:v1 ports: - name: http containerPort: 3000 replicas:3 To define your Kubernetes service object with a YAML file, you need to: - Create a file with a . or extension, such as . yaml .yml service.yaml - Specify the , , , and fields for your service object. These fields are required for any Kubernetes object. apiVersion kind metadata spec • The field indicates the version of the Kubernetes API that you are using. In this article, we will use , which is the latest stable version for services. mapiVersion v1 • The field indicates the type of the Kubernetes object. In this case, it is . kind Service • The field contains information about the name, labels, annotations, etc. of your service object. Labels are key-value pairs that can be used to identify and group your Kubernetes objects. Annotations are key-value pairs that can be used to store additional information or metadata about your Kubernetes objects. metadata • The field contains the desired state and behavior of your service object, such as the type, ports, selector, etc. spec - Specify the , , and fields within the field for your service object. These fields are required for any service object. type ports selector spec • The field defines the type of your service object, which determines how your service will be exposed to the outside world. There are four types of services: ClusterIP, NodePort, LoadBalancer, and ExternalName. In this article, we will use ClusterIP as our service type, which is the default type that creates a virtual IP address within the cluster that can be used to access your pods. type • The field defines one or more ports that will be exposed by your service. You need to provide a name, a port, and a targetPort for each port. The name can be any string that identifies your port within your service. The port is the port number that your service will expose to the outside world. The targetPort is the port number that your service will forward the traffic to within your pod. In this article, we will use 80 as our port and 3000 as our targetPort for our web application. ports • The field defines how to select the pods that belong to your service object. You need to provide one or more labels that match the labels of your pods. selector Here is an example of a YAML file that defines a Kubernetes service object for our web application: apiVersion: v1 kind: Service metadata: name: web-app-service labels: app: web-app spec: type: ClusterIP ports: - name: http port: 80 targetPort: 3000 selector: app: web-app To apply your YAML files to your Kubernetes cluster, you need to use . kubectl To apply your YAML files with kubectl, you need to: - Navigate to the directory where your YAML files are located using the command. cd - Apply your YAML files using the command. You need to provide the name of your YAML file or a directory that contains multiple YAML files as an argument. You can also use the flag to specify the file or directory name. In this article, we will use a directory named that contains our YAML files for our deployment and service objects. kubectl apply -f k8s - Verify that your deployment and service objects are created correctly using the command. You can provide the name of your object or a type of object as an argument. You can also use the flag to get more details about your objects. kubectl get -o wide Here is an example of the commands to apply and verify our YAML files with kubectl: $ cd k8s $ kubectl apply -f . deployment.apps/web-app-deployment created $ kubectl get deployment web-app-deployment -o wide NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR web-app-deployment 3/3 3 3 10s web-app-container user/web-app:v1 app=web-app $ kubectl get service web-app-service -o wide NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR web-app-service ClusterIP 10.100.200.300 <none> 80/TCP 10s app=web-app You have now created a Kubernetes deployment and service for your web application. Step 4: Expose your web application service to the internet with Aptible endpoints After you have created a Kubernetes service for your web application, you need to expose your web application service to the internet with Aptible endpoints. An endpoint is an object that defines an entry point for accessing your web application service from the outside world. Aptible provides features such as SSL encryption, custom domains, path routing, etc. for your endpoints. You can use the to create an endpoint for your web application service. Aptible CLI To create an endpoint with the Aptible CLI, you need to: - Create an endpoint using the command. You need to provide a name for your endpoint, which must be unique within your environment. You also need to provide some options for your endpoint, such as the protocol, port, hostname, path, etc. aptible endpoints:create • The option defines the type of your endpoint, which determines how your endpoint will be exposed to the outside world. There are two types of endpoints: TCP and HTTPS. In this article, we will use HTTPS as our endpoint type, which is the default type that creates a secure and encrypted connection between your web application service and your clients. --type • The option defines whether your endpoint will be internal or external. An internal endpoint can only be accessed from within your Aptible environment, while an external endpoint can be accessed from anywhere on the internet. In this article, we will use an external endpoint, which is the default option. --internal • The option defines the port number that your endpoint will listen on. You need to provide a port number that matches the port number that your web application service exposes. In this article, we will use 80 as our port number for our web application service. --port • The option defines the hostname that your endpoint will use. You can provide a custom domain name that you own and have configured with DNS records, or use a default domain name that is provided by Aptible. In this article, we will use a custom domain name that we own and have configured with DNS records, which is . --hostname web-app.example.com If you don't want to buy a custom domain name, please note that Aptible will give you a free subdomain that you can use for your application and you can change it later to a custom domain anytime you want. • The option defines the path that your endpoint will use. You can provide a specific path that you want to route to your web application service, or use a wildcard path that matches any path. In this article, we will use a wildcard path that matches any path, which is . --path / - Verify that your endpoint is created correctly using the command. You will see your endpoint listed along with its name, type, internal flag, port, hostname, path, etc. aptible endpoints:list Here is an example of the commands to create an endpoint with the Aptible CLI: $ aptible switch production Switched to production $ aptible endpoints:create --type https --internal false --port 80 --hostname web-app.example.com --path / web-app Endpoint web-app created! $ aptible endpoints:list --app web-app NAME TYPE INTERNAL PORT HOSTNAME PATH web-app HTTPS false 80 web-app.example.com / Aptible will automatically provide and manage SSL certificates for your endpoint using , which is a free and open certificate authority that provides domain validation certificates. You do not need to do anything to enable SSL encryption for your endpoint. However, you need to make sure that your custom domain name is configured with DNS records that point to your Aptible environment. You can find the DNS records for your environment on the Aptible dashboard under the tab. Let's Encrypt Domains You have now exposed your web application service to the internet with Aptible endpoints. Step 5: Test and verify your web application deployment After you have exposed your web application service to the internet with Aptible endpoints, you need to test and verify your web application deployment. You can use to send requests to your web application endpoint and check the responses. You can also use to monitor the status and logs of your web application pods and service. curl kubectl You can use curl to send requests to your web application endpoint and check the responses. Curl is a command-line tool that allows you to transfer data from or to a server using various protocols, such as HTTP, HTTPS, FTP, etc. To send requests to your web application endpoint with curl, you need to: - Use the command with the URL of your web application endpoint as an argument. The URL is composed of the protocol, hostname, and path of your endpoint. In this article, we will use as our URL for our web application endpoint. curl https://web-app.example.com/ - Check the output of the curl command on the terminal window. You will see the status code, headers, and body of the response from your web application endpoint. The status code indicates the result of your request, such as 200 for success, 404 for not found, 500 for internal server error, etc. The headers contain information about the server, content type, date, etc. The body contains the actual content of the response, such as HTML, JSON, XML, etc. Here is an example of how to send requests to your web application endpoint with curl: $ curl https://web-app.example.com/ HTTP/1.1 200 OK Server: nginx/1.19.10 Date: Tue, 10 Oct 2023 19:19:51 GMT Content-Type: text/html; charset=utf-8 Content-Length: 1234 Connection: keep-alive X-Powered-By: Aptible <html> <head> <title>Web App</title> </head> <body> <h1>Welcome to Web App!</h1> <p>This is a sample web application deployed with Aptible and Kubernetes.</p> </body> </html> You can also use kubectl to monitor the status and logs of your web application pods and service. Kubectl is a command-line tool that allows you to interact with your Kubernetes cluster. You can install kubectl here. To monitor the status of your web application pods and service with kubectl, you need to: - Open a terminal window on your computer. - Use the command with the name or type of your object as an argument. You can also use the `-o wide` flag to get more details about your object, such as the node name, pod IP, labels, etc. kubectl get - Check the output of the kubectl get command on the terminal window. You will see information about your object, such as the name, ready state, up-to-date state, available state, age, etc. Here is an example of how to monitor the status of your web application pods and service with kubectl: $ kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES web-app-deployment-f4c6d9b4f-4jw9m 1/1 Running 0 5m23s 10.100.200.301 node-1 <none> <none> web-app-deployment-f4c6d9b4f-hx7kq 1/1 Running 0 5m23s 10.100.200.302 node-2 <none> <none> web-app-deployment-f4c6d9b4f-z9v7n 1/1 Running 0 5m23s 10.100.200.303 node-3 <none> <none> $ kubectl get service -o wide NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR web-app-service ClusterIP 10.100.200.300 <none> 80/TCP 5m23s app=web-app To monitor the logs of your web application pods with kubectl, you need to: - Open a terminal window on your computer. - Use the command with the name of your pod as an argument. You can also use the flag to follow the logs in real time, or the flag to specify a time range for the logs. kubectl logs -f --since - Check the output of the kubectl logs command on the terminal window. You will see the logs of your pod, which contain the messages and errors from your web application container. Here is an example of how to monitor the logs of your web application pods with kubectl: $ kubectl logs web-app-deployment-f4c6d9b4f-4jw9m -f --since=10m [2023-10-10 19:19:51] INFO WEBrick 1.6.0 [2023-10-10 19:19:51] INFO ruby 2.7.0 (2019-12-25) [x86_64-linux] [2023-10-10 19:19:51] INFO WEBrick::HTTPServer#start: pid=1 port=3000 I, [2023-10-10T19:20:12.345678 #1] INFO -- : Started GET "/" for 10.100.200.400 at 2023-10-10 19:20:12 +0000 I, [2023-10-10T19:20:12.456789 #1] INFO -- : Processing by HomeController#index as HTML I, [2023-10-10T19:20:12.567890 #1] INFO -- : Rendering home/index.html.erb within layouts/application I, [2023-10-10T19:20:12.678901 #1] INFO -- : Rendered home/index.html.erb within layouts/application (Duration: 11.0ms | Allocations: 1234) I, [2023-10-10T19:20:12.789012 #1] INFO -- : Completed 200 OK in 33ms (Views: 22.0ms | ActiveRecord: 0.0ms | Allocations: 4567) You have now tested and verified your web application deployment with Aptible and Kubernetes. You have learned how to use some of the best practices and tools for web development, such as Aptible, Kubernetes, Docker, curl, kubectl, etc. Congratulations! You have successfully deployed a scalable web application with Aptible and Kubernetes! Conclusion In this article, you have learned how to deploy a scalable web application with Aptible and Kubernetes. You have followed these steps: - Create an Aptible app and configure your environment variables - Build and push your web application image to a container registry - Create a Kubernetes deployment and service for your web application - Expose your web application service to the internet with Aptible endpoints - Test and verify your web application deployment By following these steps, you have achieved these outcomes: - You have created a secure and compliant environment for your web application with Aptible - You have orchestrated the deployment and scaling of your web application across multiple nodes with Kubernetes - You have exposed your web application to the internet with SSL encryption, custom domains, path routing, etc. with Aptible - You have tested and verified your web application using curl and kubectl Here are some tips and best practices for deploying a scalable web application with Aptible and Kubernetes: - Use health checks to monitor the readiness and liveness of your pods and containers. Health checks are probes that can be configured to check the status of your pods and containers at regular intervals. If a pod or container fails a health check, Kubernetes will restart or replace it automatically. You can . learn how to configure health checks here - Use rolling updates to update your pods and containers without downtime. Rolling updates are a strategy that can be configured to update your pods and containers gradually, one by one, while maintaining the availability of your service. - Use autoscaling to adjust the number of pods and nodes according to the load of your service. Autoscaling is a feature that can be configured to scale your pods and nodes up or down automatically, based on the CPU utilization, memory usage, or custom metrics of your service. Read Also: How to Optimize Your CI/CD Pipeline for Maximum Efficiency Confessions Of A DevOps Guru How to Monitor Your Kubernetes Cluster with Prometheus and Grafana Additional Resources : The official documentation for Aptible, which covers topics such as getting started, deploying apps, managing databases, creating endpoints, etc. Aptible Documentation : The official documentation for Kubernetes, which covers topics such as concepts, tasks, tutorials, reference, etc. Kubernetes Documentation : The official documentation for Docker. Docker Documentation I hope you enjoyed this article and learned something new. Happy Deployment!