<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Cedric Clyburn</title>
    <description>The latest articles on DEV Community by Cedric Clyburn (@cedricclyburn).</description>
    <link>https://dev.to/cedricclyburn</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F893501%2Fdb880f67-42bf-4d24-92df-e40d23fff782.jpeg</url>
      <title>DEV Community: Cedric Clyburn</title>
      <link>https://dev.to/cedricclyburn</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/cedricclyburn"/>
    <language>en</language>
    <item>
      <title>How to create cloud-native CI/CD Pipelines with Tekton</title>
      <dc:creator>Cedric Clyburn</dc:creator>
      <pubDate>Thu, 04 Aug 2022 15:23:00 +0000</pubDate>
      <link>https://dev.to/cedricclyburn/how-to-create-cloud-native-cicd-pipelines-with-tekton-39d9</link>
      <guid>https://dev.to/cedricclyburn/how-to-create-cloud-native-cicd-pipelines-with-tekton-39d9</guid>
      <description>&lt;p&gt;For modern applications that require &lt;a href="https://www.redhat.com/en/topics/devops/what-is-ci-cd" rel="noopener noreferrer"&gt;CI/CD&lt;/a&gt; (continuous integration and continuous delivery/continuous deployment), how do you continuously deliver your code changes from source to production on Kubernetes? In this tutorial, you’ll learn how to use &lt;a href="https://tekton.dev/" rel="noopener noreferrer"&gt;Tekton&lt;/a&gt; to clone your repository, build an image, and push it to the Docker Hub. Let's get started with Tekton, an open-source cloud native CI/CD solution, by creating a real-world CI/CD pipeline.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;The CI/CD process is fundamental to combining all parts of your code to validate, test, and build before releasing to production or any other stage. Tekton, originally started from the &lt;a href="https://knative.dev/docs/" rel="noopener noreferrer"&gt;Knative&lt;/a&gt; project by Google developers, brings highly reusable and declarative CI/CD components to your cloud-native environment through Kubernetes &lt;a href="https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/" rel="noopener noreferrer"&gt;CRDs&lt;/a&gt;. This can help you to concentrate more on developing without worrying about the complexities of the underlying implementation details.&lt;/p&gt;

&lt;p&gt;Since Tekton is optimized for simplicity and reusability, let's look at the different building blocks that can help us build a continuous delivery pipeline.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh6.googleusercontent.com%2FCiWCvkUl2-ssMfUpZ25za_yhzGySMcWV7uWATYj7PYj0zXjPO5OA3PMQWLWRB6C9iroFZmne-pHLnw4cTWQGGAg3hqK8jAkbfT3PJRXnu0A5MdXG6Uy5WKAqSJ2IcFcrY3iDSbYKWPS9HpY86dvHA8w" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh6.googleusercontent.com%2FCiWCvkUl2-ssMfUpZ25za_yhzGySMcWV7uWATYj7PYj0zXjPO5OA3PMQWLWRB6C9iroFZmne-pHLnw4cTWQGGAg3hqK8jAkbfT3PJRXnu0A5MdXG6Uy5WKAqSJ2IcFcrY3iDSbYKWPS9HpY86dvHA8w" alt="Various building blocks that Tekton provides"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;-&lt;em&gt;Step&lt;/em&gt;: The most basic component of Tekton, a Step is a Kubernetes container image that executes on a specific tool or input (ex. Writing or reading a file)&lt;/p&gt;

&lt;p&gt;-&lt;em&gt;Task&lt;/em&gt;: A sequence of steps to perform a single functionality that can be reused (ex. Cloning a repository)&lt;/p&gt;

&lt;p&gt;-&lt;em&gt;Pipeline&lt;/em&gt;: Series of tasks executed in series or parallel (ex. Clone a repository, build an image, and push it to a container registry)&lt;/p&gt;

&lt;p&gt;Because these components are configured as Custom Resource Definitions on Kubernetes, you can create highly reusable pipelines, and Tekton is also compatible with &lt;a href="https://www.jenkins.io/" rel="noopener noreferrer"&gt;Jenkins&lt;/a&gt;, &lt;a href="https://skaffold.dev/" rel="noopener noreferrer"&gt;Skaffold&lt;/a&gt;, &lt;a href="https://knative.dev/" rel="noopener noreferrer"&gt;Knative&lt;/a&gt;, and other CI/CD tools. Let’s take a look at getting started with Tekton, and start working on building our pipeline.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting started with Tekton
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh6.googleusercontent.com%2FI0_6LsZmTMMH54NjNQjW7Gooyuf2CbBQgu_0lKNUd8d_y5anAHLRiOxN6BJ7VBRZVMi_-ELFRVr_xisd_-l2ILRZKTfZmMvfraxHp6a2LzydWcDealkGS7ncV_1FlaiwthuNSM-1j-1plUL03rWfC3s" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh6.googleusercontent.com%2FI0_6LsZmTMMH54NjNQjW7Gooyuf2CbBQgu_0lKNUd8d_y5anAHLRiOxN6BJ7VBRZVMi_-ELFRVr_xisd_-l2ILRZKTfZmMvfraxHp6a2LzydWcDealkGS7ncV_1FlaiwthuNSM-1j-1plUL03rWfC3s" alt="Tekton logo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To start, let's install &lt;a href="https://tekton.dev/" rel="noopener noreferrer"&gt;Tekton&lt;/a&gt; and any extras. What we’ll be using Tekton for is the classic container build process, where the Pipeline typically looks like the graphic below. Of course, there are always additional steps like testing, packaging, and deploying to our cluster, but for simplicity, our Pipeline will clone, build an image, and push an image to a container registry like the &lt;a href="https://hub.docker.com/" rel="noopener noreferrer"&gt;Docker Hub&lt;/a&gt; or &lt;a href="https://quay.io/repository/" rel="noopener noreferrer"&gt;Quay.io&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh6.googleusercontent.com%2F2xesYmBsYaPU6bkrPsLaIkR6Rts29Lc3enJifP-ynNiToCDD8QKuYZ-BpNJ_Q1h171dSO9z7pbPBEBzjZQ9uo3OOQ-jYxWMWu8DEE6tK5EJST4MyQ8nXa4bN90u7v9zWPzQdWaG-_Dpo37IyAK078Q8" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh6.googleusercontent.com%2F2xesYmBsYaPU6bkrPsLaIkR6Rts29Lc3enJifP-ynNiToCDD8QKuYZ-BpNJ_Q1h171dSO9z7pbPBEBzjZQ9uo3OOQ-jYxWMWu8DEE6tK5EJST4MyQ8nXa4bN90u7v9zWPzQdWaG-_Dpo37IyAK078Q8" alt="Example Pipeline graph we'll be using"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We'll work with Tasks from the &lt;a href="https://hub.tekton.dev/" rel="noopener noreferrer"&gt;Tekton Hub&lt;/a&gt;, create the configurations for our Docker Hub and ServiceAccount, and use a &lt;code&gt;PipelineRun&lt;/code&gt; to instantiate our final Pipeline. Let’s begin!&lt;/p&gt;

&lt;h3&gt;
  
  
  Installing Tekton
&lt;/h3&gt;

&lt;p&gt;Simply use a single &lt;code&gt;kubectl&lt;/code&gt; command to install the latest version of Tekton Pipelines.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl apply --filename https://storage.googleapis.com/tekton-releases/pipeline/latest/release.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You’ll also want to install the &lt;code&gt;tkn&lt;/code&gt; &lt;a href="https://github.com/tektoncd/cli" rel="noopener noreferrer"&gt;CLI&lt;/a&gt; to interact with Tekton; instructions can be found in the &lt;a href="https://tekton.dev/docs/cli/" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Additionally, feel free to install the Tekton dashboard to visualize our pipeline in a GUI using the &lt;a href="https://github.com/tektoncd/dashboard" rel="noopener noreferrer"&gt;Tekton Dashboard&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl apply --filename https://storage.googleapis.com/tekton-releases/dashboard/latest/tekton-dashboard-release.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Tekton Dashboard is not exposed outside the cluster by default, but you can port-forward it using the following command and access it at &lt;code&gt;localhost:9097&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl port-forward -n tekton-pipelines service/tekton-dashboard 9097:9097
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh4.googleusercontent.com%2FbYSnqHEoeZ3XB00F1Nf6_xFYt-DmBTHOdNfNDTwmse5cvrUo-GK5WA7Miw9_241IRca3bh5gFkygsI3LUC01EKFdXnE6gWB_p5AGw_Cxm7xbJC8W5KuWv6k-OUj3Wy2XLw3SNEtm2DLETmdupXnNUXI" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh4.googleusercontent.com%2FbYSnqHEoeZ3XB00F1Nf6_xFYt-DmBTHOdNfNDTwmse5cvrUo-GK5WA7Miw9_241IRca3bh5gFkygsI3LUC01EKFdXnE6gWB_p5AGw_Cxm7xbJC8W5KuWv6k-OUj3Wy2XLw3SNEtm2DLETmdupXnNUXI" alt="Default Tekton Dashboard View"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating Tekton Tasks
&lt;/h3&gt;

&lt;p&gt;The tasks we’ll need to create our specific pipeline are already available at the &lt;a href="https://hub.tekton.dev/" rel="noopener noreferrer"&gt;Tekton Hub&lt;/a&gt;, a central portal for discovering and sharing Tekton resources, tasks, and pipelines. We’ll use the &lt;a href="https://hub.tekton.dev/tekton/task/git-clone" rel="noopener noreferrer"&gt;git-clone&lt;/a&gt; and &lt;a href="https://hub.tekton.dev/tekton/task/buildah" rel="noopener noreferrer"&gt;buildah&lt;/a&gt; Tasks to clone our repository, build an image, and push the image to a container registry. Feel free to check out the details of these Tasks and their source code.&lt;/p&gt;

&lt;p&gt;First, let’s install these Tasks with &lt;code&gt;tkn hub install&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ tkn hub install task git-clone &amp;amp;&amp;amp; tkn hub install task buildah

Task git-clone(0.7) installed in default namespace
Task buildah(0.4) installed in default namespace
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let’s confirm the tasks have been successfully installed with &lt;code&gt;tkn task list&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ tkn task list

NAME                 DESCRIPTION              AGE
git-clone            These Tasks are Git...   2 minutes ago
buildah              Buildah task builds...   2 minutes ago
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Image Push Secrets
&lt;/h3&gt;

&lt;p&gt;To push the image to the Docker Hub, you’ll need to provide your credentials, which we can do by creating a file named &lt;code&gt;secret.yaml&lt;/code&gt;, with the following content. Be sure to replace &lt;code&gt;username&lt;/code&gt; and &lt;code&gt;password&lt;/code&gt; with your Docker Hub credentials.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: v1
kind: Secret
metadata:
  name: docker-secret
  annotations:
    tekton.dev/docker-0: https://index.docker.io/
type: kubernetes.io/basic-auth
stringData:
    username: username
    password: password
--- 
apiVersion: v1
kind: ServiceAccount
metadata:
  name: docker-login
secrets:
  - name: docker-secret
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will create a &lt;code&gt;Secret&lt;/code&gt; and &lt;code&gt;ServiceAccount&lt;/code&gt;, which can now be used when running Tekton tasks, and we can apply it with &lt;code&gt;kubectl&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl apply -f secret.yaml

secret/docker-secret created

serviceaccount/docker-login created
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Creating a Pipeline
&lt;/h3&gt;

&lt;p&gt;Great! You’re ready to create a pipeline using the two &lt;code&gt;git-clone&lt;/code&gt; and &lt;code&gt;buildah&lt;/code&gt; tasks. Create a file named &lt;code&gt;pipeline.yaml&lt;/code&gt; with the following content.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
  name: example-pipeline
spec:
  params:
    - name: REPO
    - name: IMAGE
    - name: TAG
  workspaces:
    - name: workspace
  tasks:
    - name: fetch-repository
      taskRef:
        name: git-clone
      workspaces:
        - name: output
          workspace: workspace
      params:
        - name: url
          value: $(params.REPO)
        - name: deleteExisting
          value: "true"
    - name: build-push-image
      taskRef:
        name: buildah
      runAfter:
        - fetch-repository
      workspaces:
        - name: source
          workspace: workspace
      params:
        - name: IMAGE
          value: "$(params.IMAGE):$(params.TAG)"
        - name: FORMAT
          value: "docker"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This pipeline includes the two tasks we recently installed. First, a &lt;code&gt;git-clone&lt;/code&gt; Task to clone our repository, using a url we’ll specify in a PipelineRun. Next, we build and push an image using the &lt;code&gt;buildah&lt;/code&gt; Task, using an image and tag we’ll also specify in the PipelineRun to instantiate our Pipeline.&lt;/p&gt;

&lt;p&gt;All we need to do to apply this Pipeline configuration to our cluster is use a standard &lt;code&gt;kubectl&lt;/code&gt; command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl apply -f pipeline.yaml

pipeline.tekton.dev/example-pipeline created
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Creating a PipelineRun
&lt;/h3&gt;

&lt;p&gt;To run the pipeline, we can create a PipelineRun and specify our specific values for the repository, image, and reference to the pipeline. Create a file named &lt;code&gt;pipelinerun.yaml&lt;/code&gt; with the following content. Being that Tekton Pipelines are highly reusable, you’re able to use any repository you’d like, and be sure to change your Docker Hub username.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
  name: tutorial-pipeline-run
spec:
  serviceAccountName: docker-login
  pipelineRef:
    name: example-pipeline
  params:
    - name: REPO
      value: "https://github.com/cedricclyburn/tekton-tutorial"
    - name: IMAGE
      value: "docker.io/cedricclyburn/tekton-tutorial"
    - name: TAG
      value: latest
  workspaces:
    - name: workspace
      volumeClaimTemplate:
        spec:
          accessModes:
            - ReadWriteOnce
          resources:
            requests:
              storage: 10Gi
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let’s apply the file, and start the deployment with a &lt;code&gt;kubectl&lt;/code&gt; command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl apply -f pipelinerun.yaml

pipelinerun.tekton.dev/tutorial-pipeline-run created
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We’ve successfully run a pipeline, and to see the logs of the Pipeline, feel free to run the following command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ tkn pipeline logs -f

[1/3] STEP 1/5: FROM node:16-alpine AS deps
Resolved "node" as an alias (/etc/containers/registries.conf.d/000-shortnames.conf)
Trying to pull docker.io/library/node:16-alpine...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Checking the Results
&lt;/h3&gt;

&lt;p&gt;Fantastic! We’ve successfully used a PipelineRun to run our Pipeline, so it’s time to check that everything worked properly. First, let’s use the Tekton Dashboard to view the logs and ensure the PipelineRun has succeeded. From your dashboard, navigate to the _PipelineRuns _tab to view your PipelineRuns, and select the &lt;code&gt;tutorial-pipeline-run&lt;/code&gt; we’ve created.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh5.googleusercontent.com%2FzH0663a2iByVTAFdRZiplNRLLCpwp5-JZPt7oJOQn3u2jEPiGFF-CdbdFvQ4qYx-eLr6TCE1Dir4Uc0Bj2MoHw3FHQUSppS20bwuOV_lF2xsqt3V7VOim5jp60iP5Doswk5sMVmq7kE9z9Zfw9dSdKk" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh5.googleusercontent.com%2FzH0663a2iByVTAFdRZiplNRLLCpwp5-JZPt7oJOQn3u2jEPiGFF-CdbdFvQ4qYx-eLr6TCE1Dir4Uc0Bj2MoHw3FHQUSppS20bwuOV_lF2xsqt3V7VOim5jp60iP5Doswk5sMVmq7kE9z9Zfw9dSdKk" alt="View of all the PipelineRuns in the Tekton Dashboard"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From here, you can visualize the various Tasks of your Pipeline, including the parameters, results, logs, and status of each Task.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh3.googleusercontent.com%2FElCoAqShh5PNns5he1iT04P76jnmhPEq2aaA6i0vm_AtVQ98DZEE8J4pYce3N_zIEUU1WrMUk2xTiVlsZSl_yqesmtzmhf8_Yxu-rEluxTmnHs8hX8Ui9JziOQJLKJ0SyoBCHlhkti6UGJdBNFs3xkE" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh3.googleusercontent.com%2FElCoAqShh5PNns5he1iT04P76jnmhPEq2aaA6i0vm_AtVQ98DZEE8J4pYce3N_zIEUU1WrMUk2xTiVlsZSl_yqesmtzmhf8_Yxu-rEluxTmnHs8hX8Ui9JziOQJLKJ0SyoBCHlhkti6UGJdBNFs3xkE" alt="View of the newly created PipelineRun in the Tekton Dashboard"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, as everything we’ve seen looks good from the Pipeline logs using &lt;code&gt;tkn pipeline logs&lt;/code&gt; and from the Tekton Dashboard, let’s run the image using &lt;a href="https://www.docker.com" rel="noopener noreferrer"&gt;Docker&lt;/a&gt;. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Feel free to use &lt;a href="https://podman.io/" rel="noopener noreferrer"&gt;Podman&lt;/a&gt;, a daemonless and rootless container engine, instead as well, by replacing &lt;code&gt;docker&lt;/code&gt; with &lt;code&gt;podman&lt;/code&gt; in the following command.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker run -p 3000:3000 docker.io/cedricclyburn/tekton-tutorial
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When visiting &lt;code&gt;localhost:3000&lt;/code&gt;, you’ll see the Next.js example application running like so. Congratulations!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh6.googleusercontent.com%2FQBHiBxBNLn1iUkj8I4N7mwAbJp-tTfQGfHHftK5or_eOj2gje5r2SmhPuixpRzFNB2hmvT1074xcWPzK9uv6_pl-fD5UDleyEBxM6RL21_dalRVT-MxsaRwqiazFH08KOVbZ5yBABzxjiCFQsfODwfk" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh6.googleusercontent.com%2FQBHiBxBNLn1iUkj8I4N7mwAbJp-tTfQGfHHftK5or_eOj2gje5r2SmhPuixpRzFNB2hmvT1074xcWPzK9uv6_pl-fD5UDleyEBxM6RL21_dalRVT-MxsaRwqiazFH08KOVbZ5yBABzxjiCFQsfODwfk" alt="Next.js application running in the browser"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Through this guide, you’ve learned how to work with &lt;a href="https://tekton.dev/" rel="noopener noreferrer"&gt;Tekton&lt;/a&gt; to create cloud-native CI/CD Pipelines. You’ve also been able to build your own Pipeline to clone a repository, build an image, and push that image to the Docker Hub, all by using Tasks from the &lt;a href="https://hub.tekton.dev/" rel="noopener noreferrer"&gt;Tekton Hub&lt;/a&gt;. There are plenty more reusable Tasks and Pipelines there, but I also encourage you to learn about &lt;a href="https://github.com/tektoncd/triggers/blob/main/docs/getting-started/README.md" rel="noopener noreferrer"&gt;Tekton Triggers&lt;/a&gt; (automatically running a Pipeline), other projects of the &lt;a href="https://cd.foundation/" rel="noopener noreferrer"&gt;Continuous Delivery Foundation&lt;/a&gt; and the &lt;a href="https://tekton.dev/docs/" rel="noopener noreferrer"&gt;Tekton documentation&lt;/a&gt; for more information!&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1549061815165825024-758" src="https://platform.twitter.com/embed/Tweet.html?id=1549061815165825024"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1549061815165825024-758');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1549061815165825024&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;Feel free to follow me on Twitter &lt;a href="https://twitter.com/cedricclyburn" rel="noopener noreferrer"&gt;@cedricclyburn&lt;/a&gt; for more cloud-native tutorials!&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>devops</category>
      <category>tekton</category>
      <category>linux</category>
    </item>
    <item>
      <title>Containers without Docker (podman, buildah, and skopeo)</title>
      <dc:creator>Cedric Clyburn</dc:creator>
      <pubDate>Tue, 19 Jul 2022 20:07:00 +0000</pubDate>
      <link>https://dev.to/cedricclyburn/containers-without-docker-podman-buildah-and-skopeo-1eal</link>
      <guid>https://dev.to/cedricclyburn/containers-without-docker-podman-buildah-and-skopeo-1eal</guid>
      <description>&lt;p&gt;While &lt;a href="https://www.docker.com/" rel="noopener noreferrer"&gt;Docker&lt;/a&gt; is commonly the standard when it comes to containers, we're starting to see why alternatives like &lt;a href="https://podman.io/" rel="noopener noreferrer"&gt;Podman&lt;/a&gt; are quickly becoming popular replacements for container-based development. Although Docker has been around for almost 10 years and standardized containerization, Podman has some huge advantages, namely being "&lt;a href="https://medium.com/easyread/daemonless-container-engine-5364394b80ec" rel="noopener noreferrer"&gt;daemonless&lt;/a&gt;" (not needing &lt;code&gt;systemd&lt;/code&gt; or any other service to run in the background). Are there alternatives to Docker? Yes, and let's take a look at how we can get started with Podman, Buildah, and Skopeo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Docker has been an innovator in how developers build and deploy applications, and is a good tool. From building images, pushing/pulling images from registries, and running images, Docker does it all. However, Docker is a &lt;a href="https://martinheinz.dev/blog/35" rel="noopener noreferrer"&gt;huge monolithic application&lt;/a&gt; and relies on a heavy daemon, which, if at a point failed, all child processes would become unreachable. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh4.googleusercontent.com%2FvZlRKQINPgO6RJ6ks8S5JxkZiCMw932F5dw16ttzAw9Jxt4h1aWJWjRbyyaeCnAISovILy81KXHtO-jOmVS2074r8pZ8jQR8lUrQhp0leG9ofI_f0Z2l7ib_GSWaMcf_36zEm1_3M7_vLLOcgMDAdcE" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh4.googleusercontent.com%2FvZlRKQINPgO6RJ6ks8S5JxkZiCMw932F5dw16ttzAw9Jxt4h1aWJWjRbyyaeCnAISovILy81KXHtO-jOmVS2074r8pZ8jQR8lUrQhp0leG9ofI_f0Z2l7ib_GSWaMcf_36zEm1_3M7_vLLOcgMDAdcE" alt="Differences between the architecture of Docker and Podman"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is what Podman, an open-source daemonless and rootless container engine, was developed with in mind. Podman runs using the &lt;a href="https://github.com/opencontainers/runc" rel="noopener noreferrer"&gt;runC&lt;/a&gt; container runtime process, directly on the Linux kernel, and launches containers and pods as child processes. In addition, it was developed for the Docker developer, with most commands and syntax seamlessly mirroring Docker's. &lt;a href="https://buildah.io/" rel="noopener noreferrer"&gt;Buildah&lt;/a&gt;, an image builder, and &lt;a href="https://github.com/containers/skopeo" rel="noopener noreferrer"&gt;Skopeo&lt;/a&gt;, the image utility tool, are both complimentary to Podman as well, and extend the range of operations able to be performed.&lt;/p&gt;

&lt;p&gt;Due to Docker being such a large tool, we can break it down into a few components, mainly, this includes the container engine, image builder, and image distribution. Instead of relying on Docker, let’s take a look at some light-weight replacements that can achieve the same functionality.&lt;/p&gt;

&lt;h2&gt;
  
  
  Podman
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh5.googleusercontent.com%2FnWn4PK7jIJ36O_Qf4r5QvRKguci7qJwu51ZisfAu5W7ZonwNFzSCK8lfujSCunIxI2i0pnBVi0Lsr4u4Wmd8S4THaLcOqdKY3RTcwcfSlFnc7xol7MMOo6sDXAi3hBKEE1Ntk0-M53bfBq9YMpU" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh5.googleusercontent.com%2FnWn4PK7jIJ36O_Qf4r5QvRKguci7qJwu51ZisfAu5W7ZonwNFzSCK8lfujSCunIxI2i0pnBVi0Lsr4u4Wmd8S4THaLcOqdKY3RTcwcfSlFnc7xol7MMOo6sDXAi3hBKEE1Ntk0-M53bfBq9YMpU" alt="Podman logo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://podman.io/" rel="noopener noreferrer"&gt;Podman&lt;/a&gt; is a daemonless and rootless container engine, allowing you to run, manage, and interact with containers. The commands are the same as Docker due to the standards of the &lt;a href="https://opencontainers.org/" rel="noopener noreferrer"&gt;Open Container Initiative&lt;/a&gt; (OCI), and you can even alias Docker to Podman (&lt;code&gt;alias docker=podman&lt;/code&gt;). While the Docker daemon normally runs as root, a long-standing security concern, Podman can be run in rootless mode. Podman even includes the functionality to &lt;a href="https://developers.redhat.com/blog/2019/01/29/podman-kubernetes-yaml#enough_teasing__show_me_the_goods" rel="noopener noreferrer"&gt;orchestrate containers with Kubernetes&lt;/a&gt;!&lt;/p&gt;

&lt;h3&gt;
  
  
  Getting started with Podman
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Firstly, let’s install Podman. Based on your runtime, you can use the various installation methods in the &lt;a href="https://podman.io/getting-started/installation.html" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;. You can even easily use Podman on Mac using &lt;code&gt;brew install podman&lt;/code&gt; and Windows using this &lt;a href="https://www.redhat.com/sysadmin/run-podman-windows" rel="noopener noreferrer"&gt;blog&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

$ sudo dnf -y install podman


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Run a httpd container&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

$ podman run -dt -p 8080:80/tcp docker.io/library/httpd

Trying to pull docker.io/library/httpd:latest...
Getting image source signatures
Copying blob d6bc17b4451a done 
…


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Check container status&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

$ podman ps

CONTAINER ID  IMAGE                           COMMAND           CREATED         STATUS             PORTS                 NAMES

5d5f92a59ea3  docker.io/library/httpd:latest  httpd-foreground  24 seconds ago  Up 25 seconds ago  0.0.0.0:8080-&amp;gt;80/tcp  happy_beaver


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Access your application! We could simply do a &lt;code&gt;curl&lt;/code&gt; command, or access the IP of our application with port 8080 on a browser, and we’ll see our &lt;code&gt;httpd&lt;/code&gt; server running.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

$ curl localhost:8080

&amp;lt;html&amp;gt;&amp;lt;body&amp;gt;&amp;lt;h1&amp;gt;It works!&amp;lt;/h1&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh6.googleusercontent.com%2FSB5YjKBc4ZKYl6INn2XH8-z6Kk_Tyd6zrEfaH8KGU2QtlcwGGQ8IltPmodvd4hdPpXRyxX2ieIDUfg9subopfW3QwB8dWhz8cSFUXyoEgZEMQv4Glc5MCk_hzY7dkfSVFo-QNPuoISNTe5H178S52wM" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh6.googleusercontent.com%2FSB5YjKBc4ZKYl6INn2XH8-z6Kk_Tyd6zrEfaH8KGU2QtlcwGGQ8IltPmodvd4hdPpXRyxX2ieIDUfg9subopfW3QwB8dWhz8cSFUXyoEgZEMQv4Glc5MCk_hzY7dkfSVFo-QNPuoISNTe5H178S52wM" alt="Working webpage using httpd"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Buildah
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh5.googleusercontent.com%2Fvyju91y_OxXpkaGHuFjnsrnIsxcJq5m1Rvnl-VmgdjFhqWYpVerzKl9tQGmk360bfkmrAgxInoLQyh4fKTAOlvYANUY2jbHsKe2w7p-8BApYhFdNjzLMBP3MnzzvgHvpgDfoKy_oZh_EeKfG-hy3MEk" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh5.googleusercontent.com%2Fvyju91y_OxXpkaGHuFjnsrnIsxcJq5m1Rvnl-VmgdjFhqWYpVerzKl9tQGmk360bfkmrAgxInoLQyh4fKTAOlvYANUY2jbHsKe2w7p-8BApYhFdNjzLMBP3MnzzvgHvpgDfoKy_oZh_EeKfG-hy3MEk" alt="Buildah logo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://buildah.io/" rel="noopener noreferrer"&gt;Buildah&lt;/a&gt; is a daemonless and rootless image builder tool complimentary to Podman that produces OCI compliant images. It’s able to build images from &lt;code&gt;Dockerfile&lt;/code&gt;, and can be run directly inside of containers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Getting started with Buildah
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Let’s install Buildah, which can be done by checking the &lt;a href="https://github.com/containers/buildah/blob/main/install.md" rel="noopener noreferrer"&gt;installation documentation&lt;/a&gt;. Just like Podman, Buildah is shipped on Fedora 35/36, RHEL 8+, CentOS, OpenSUSE, and Ubuntu, and more.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

$ sudo dnf -y install buildah


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Build an image from &lt;code&gt;Dockerfile&lt;/code&gt;. While the default command to build any container image is &lt;code&gt;buildah bud -t tag-name .&lt;/code&gt; in a directory with a &lt;code&gt;Dockerfile&lt;/code&gt;, let’s say we’re working on a Next.js application. Firstly, let’s download the bootstrap using &lt;code&gt;npx&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

$ npx create-next-app --example with-docker nextjs-docker

$ cd next-js docker


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Now, we’ve got a Next.js application, with a Dockerfile inside ready to build our app. Let’s go ahead and build our container image.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

$ buildah build -t nextjs-docker .

[1/3] STEP 1/5: FROM node:16-alpine AS deps

Resolved "node" as an alias (/etc/containers/registries.conf.d/000-shortnames.conf)

Trying to pull docker.io/library/node:16-alpine…

Successfully tagged localhost/nextjs-docker:latest


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Check image status.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

$ buildah images

REPOSITORY               TAG         IMAGE ID      CREATED         SIZE

localhost/nextjs-docker  latest      162bee38beb9  8 seconds ago   118 MB


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Run container and check the installation, looks great!&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

$ podman run -p 3000:3000 nextjs-docker


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh4.googleusercontent.com%2FJjoF5N0mfyJOOMa4scURKo9GSG69aCSwAwlyK3k5GRbIWmmVM_OSU4GmZ342xFqkRyu9qFzSFq2Ul4n_vxp-t67f2kT5WCOvLPldpe8CR-xNUWUH5dGGBCF3X9KwKPDnvhvU1NGEvU4Wt1cJShswTjs" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh4.googleusercontent.com%2FJjoF5N0mfyJOOMa4scURKo9GSG69aCSwAwlyK3k5GRbIWmmVM_OSU4GmZ342xFqkRyu9qFzSFq2Ul4n_vxp-t67f2kT5WCOvLPldpe8CR-xNUWUH5dGGBCF3X9KwKPDnvhvU1NGEvU4Wt1cJShswTjs" alt="Example of Next.js viewable in browser"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Skopeo
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh5.googleusercontent.com%2Fv_dZWerfvOUU6VBUyRq_uHEA5sQ3tvmK8ts8zWVkUvabtYj5S3Kh_-mrZfATojrIz2YF3XhDMciVui6gOUezwFCozAnKb_FsAK8xjJcCNoPqlkY45QXVW5GJLruz8bCCAA5VttG-Da740PE8ADZdPNw" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh5.googleusercontent.com%2Fv_dZWerfvOUU6VBUyRq_uHEA5sQ3tvmK8ts8zWVkUvabtYj5S3Kh_-mrZfATojrIz2YF3XhDMciVui6gOUezwFCozAnKb_FsAK8xjJcCNoPqlkY45QXVW5GJLruz8bCCAA5VttG-Da740PE8ADZdPNw" alt="Skopeo logo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/containers/skopeo" rel="noopener noreferrer"&gt;Skopeo&lt;/a&gt; is an image utility tool that complements Podman and Buildah, allowing you to remotely inspect images, copy images between registries, and more. Like the others, it doesn’t require a daemon to be running or root privileges, and can work with OCI compatible images.&lt;/p&gt;

&lt;h3&gt;
  
  
  Getting started with Skopeo
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Let’s install Skopeo, which can be done using the &lt;a href="https://github.com/containers/skopeo/blob/main/install.md" rel="noopener noreferrer"&gt;installation documentation&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

$ sudo dnf -y install skopeo


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Push our image to a remote registry. If we haven’t already done so, let’s upload the image we just built with Buildah to the Docker hub.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

$ podman login docker.io

$ podman push nextjs-docker docker.io/cedricclyburn/nextjs-docker


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh5.googleusercontent.com%2FWq1VXraDxBb2CNCRl0GuWfuoPQgDvJEbVxly6PtCLljxY9ApCaZg81C0JAiwX4z7YdzYFLBzyyVnHltRYxhqyLDASFfzHJzZucPDco3NgkbHpVNoG-nzutOekCOb-BtVMFjAQ50E8TxK9Dr8TbH-Jrk" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh5.googleusercontent.com%2FWq1VXraDxBb2CNCRl0GuWfuoPQgDvJEbVxly6PtCLljxY9ApCaZg81C0JAiwX4z7YdzYFLBzyyVnHltRYxhqyLDASFfzHJzZucPDco3NgkbHpVNoG-nzutOekCOb-BtVMFjAQ50E8TxK9Dr8TbH-Jrk" alt="View of image in Docker Hub"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Copy image to a different registry. Recently, Docker Hub rate limits and paid tier changes have encouraged engineers to start using alternative image registries like Quay.io. Let’s take our existing image from Docker, and copy it over to Quay.io.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

$ skopeo login quay.io

$ skopeo copy docker://cedricclyburn/nextjs-docker:latest docker://quay.io/cedric-clyburn/nextjs-docker:latest


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh3.googleusercontent.com%2FnSsgA886rNPKwEvZD1qe84Gsg0K6ZPCSxXiMtMpDIPLkeHtstZiwqbFWVhv_iV5VAkozyLErqdobDQEpqE3mxZgLvETN6eO0Clc_1Zn9S5s0x_hZ_ttdt0bTrBpPYXI2KY3ffrmGPZjgPkGuGfGu66U" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh3.googleusercontent.com%2FnSsgA886rNPKwEvZD1qe84Gsg0K6ZPCSxXiMtMpDIPLkeHtstZiwqbFWVhv_iV5VAkozyLErqdobDQEpqE3mxZgLvETN6eO0Clc_1Zn9S5s0x_hZ_ttdt0bTrBpPYXI2KY3ffrmGPZjgPkGuGfGu66U" alt="View of image in Quay.io"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Inspect the image. Skopeo allows us to inspect properties or configuration of an image on remote repositories using &lt;code&gt;skopeo inspect&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

&lt;p&gt;$ skopeo inspect docker://quay.io/cedric-clyburn/nextjs-docker&lt;/p&gt;

&lt;p&gt;{&lt;/p&gt;

&lt;p&gt;    "Name": "quay.io/cedric-clyburn/nextjs-docker",&lt;/p&gt;

&lt;p&gt;    "Digest": "sha256:779bf91bd2d407b4db9e7e7035cc77dfbd0f2cbd435067a40f485960d2889ded",&lt;/p&gt;

&lt;p&gt;    "RepoTags": [&lt;/p&gt;

&lt;p&gt;        "latest"&lt;/p&gt;

&lt;p&gt;    ],&lt;/p&gt;

&lt;p&gt;    "Created": "2022-07-19T18:30:29.872420186Z",&lt;br&gt;
…&lt;/p&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Conclusion&lt;br&gt;
&lt;/h2&gt;

&lt;p&gt;As we’ve seen, you can use Podman, Buildah, and Skopeo as replacements to the traditional Docker workflow, without the use of a daemon or root privileges. There are plenty of great advantages that result from using these tools, and due to the increase of developer adoption there’s only more to come. I believe there’s a future for containers without Docker, and Podman (as well as the Buildah and Skopeo family) is a great alternative to work with.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1329559076058132483-843" src="https://platform.twitter.com/embed/Tweet.html?id=1329559076058132483"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1329559076058132483-843');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1329559076058132483&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: This content comes from one of my DevNation Tech Talks, and the full presentation + slides can be found &lt;a href="https://developers.redhat.com/devnation/tech-talks/containers-without-docker" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/em&gt;!&lt;/p&gt;

</description>
      <category>docker</category>
      <category>kubernetes</category>
      <category>tutorial</category>
      <category>podman</category>
    </item>
  </channel>
</rss>
