├── .clomonitor.yaml ├── .devfile.yaml ├── .github ├── CODEOWNERS ├── dependabot.yaml └── workflows │ ├── empty-worksapce-smoke-test-on-minikube-ubi9.yaml │ ├── pr-check.yaml │ └── ubi9-build.yaml ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── base └── ubi9 │ ├── .stow-local-ignore │ ├── Dockerfile │ ├── entrypoint.sh │ ├── kubedock_setup.sh │ └── podman-wrapper.sh └── universal └── ubi9 ├── Dockerfile └── containers.conf /.clomonitor.yaml: -------------------------------------------------------------------------------- 1 | # CLOMonitor metadata file 2 | # This file must be located at the root of the repository 3 | 4 | # Checks exemptions 5 | exemptions: 6 | - check: recent_release # Check identifier (see https://github.com/cncf/clomonitor/blob/main/docs/checks.md#exemptions) 7 | reason: "There are no releases planned for GitHub. Releases for images are done on a rolling basis to quay.io at quay.io/devfile/base-developer-image and quay.io/devfile/universal-developer-image." 8 | -------------------------------------------------------------------------------- /.devfile.yaml: -------------------------------------------------------------------------------- 1 | schemaVersion: 2.3.0 2 | metadata: 3 | name: developer-images 4 | attributes: 5 | controller.devfile.io/storage-type: ephemeral 6 | controller.devfile.io/scc: container-build 7 | components: 8 | - name: devtools 9 | container: 10 | image: quay.io/devfile/universal-developer-image:ubi9-latest 11 | memoryLimit: 6Gi 12 | memoryRequest: 256Mi 13 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Global Owners 2 | * @svor @SDawley @dkwon17 3 | -------------------------------------------------------------------------------- /.github/dependabot.yaml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | # Maintain dependencies for GitHub Actions 4 | - package-ecosystem: "github-actions" 5 | directory: "/" 6 | schedule: 7 | interval: "daily" -------------------------------------------------------------------------------- /.github/workflows/empty-worksapce-smoke-test-on-minikube-ubi9.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2019-2024 Red Hat, Inc. 3 | # This program and the accompanying materials are made 4 | # available under the terms of the Eclipse Public License 2.0 5 | # which is available at https://www.eclipse.org/legal/epl-2.0/ 6 | # 7 | # SPDX-License-Identifier: EPL-2.0 8 | # 9 | # Contributors: 10 | # Red Hat, Inc. - initial API and implementation 11 | # 12 | 13 | name: Empty workspace smoke test on udi9 14 | on: 15 | pull_request: 16 | paths-ignore: 17 | - '**/*.md' 18 | - .devfile.yaml 19 | - LICENSE 20 | 21 | env: 22 | USERSTORY: CloneGitRepoAPI 23 | TS_API_TEST_KUBERNETES_COMMAND_LINE_TOOL: kubectl 24 | DEPLOYMENT_TIMEOUT: 90s 25 | PULL_POLICY: IfNotPresent 26 | 27 | jobs: 28 | workspace-api-tests-on-minikube: 29 | strategy: 30 | fail-fast: false 31 | matrix: 32 | runners: ['ubuntu-22.04', 'ubuntu-22.04-arm'] 33 | runs-on: ${{matrix.runners}} 34 | steps: 35 | 36 | - name: Checkout 37 | uses: actions/checkout@master 38 | - name: Free runner space 39 | run: | 40 | sudo rm -rf /usr/local/lib/android 41 | # obtain the PR number for tegging the image 42 | - name: Get PR number 43 | id: get_pr_number 44 | run: | 45 | pr_number=$(echo $GITHUB_REF | awk 'BEGIN { FS = "/" } ; { print $3 }') 46 | echo "PR_NUMBER=$pr_number" >> $GITHUB_ENV 47 | echo ">>>>>>>>>>>$pr_number" 48 | 49 | - name: Cleanup build-in images 50 | run: | 51 | # remove build-in images from the VM because it is not used 52 | docker rmi -f $(docker images -aq) 53 | 54 | - name: Set arch environment variable 55 | run: | 56 | if [[ ${{matrix.runners}} == 'ubuntu-22.04' ]]; then 57 | echo arch="amd64" >> $GITHUB_ENV 58 | else 59 | echo arch="arm64" >> $GITHUB_ENV 60 | fi 61 | 62 | - name: Start minikube cluster 63 | run: | 64 | curl -LO https://github.com/kubernetes/minikube/releases/latest/download/minikube-linux-${{env.arch}} 65 | install minikube-linux-${{env.arch}} /usr/local/bin/minikube && rm minikube-linux-${{env.arch}} 66 | minikube start --vm-driver=docker --addons=ingress --cpus 2 --memory 6500 67 | 68 | # connect with docker daemon in the minikube and build an image there 69 | # we need to build the image in the minikube because we have just 14 GB of space on the runner 70 | # the UBI have more than 9 GB size this approach saves the disk space 71 | - name: Build base image 72 | run: | 73 | eval $(minikube docker-env) 74 | cd base/ubi9 && docker build -t quay.io/devfile/base-developer-image:ubi9-latest . 75 | 76 | - name: Build universal image 77 | run: | 78 | eval $(minikube docker-env) 79 | cd universal/ubi9 && docker build -t quay.io/devfile/universal-developer-image:${{ env.PR_NUMBER }} . 80 | 81 | - name: Checkout DWO 82 | uses: actions/checkout@master 83 | with: 84 | repository: devfile/devworkspace-operator 85 | path: devworkspace-operator 86 | 87 | - name: Setup cert manager 88 | run: | 89 | cd devworkspace-operator 90 | make install_cert_manager 91 | kubectl wait deployment -n cert-manager cert-manager --for condition=Available=True --timeout=$DEPLOYMENT_TIMEOUT 92 | kubectl wait deployment -n cert-manager cert-manager-cainjector --for condition=Available=True --timeout=$DEPLOYMENT_TIMEOUT 93 | kubectl wait deployment -n cert-manager cert-manager-webhook --for condition=Available=True --timeout=$DEPLOYMENT_TIMEOUT 94 | 95 | - name: Setup DWO 96 | run: | 97 | cd devworkspace-operator 98 | make install 99 | kubectl rollout status deployment -n devworkspace-controller devworkspace-controller-manager --timeout=$DEPLOYMENT_TIMEOUT 100 | kubectl rollout status deployment -n devworkspace-controller devworkspace-webhook-server --timeout=$DEPLOYMENT_TIMEOUT 101 | kubectl wait deployment -n devworkspace-controller devworkspace-webhook-server --for condition=Available=True --timeout=$DEPLOYMENT_TIMEOUT 102 | kubectl wait deployment -n devworkspace-controller devworkspace-controller-manager --for condition=Available=True --timeout=$DEPLOYMENT_TIMEOUT 103 | 104 | - name: Check that UDI is present in the image list 105 | run: | 106 | # we used it for the build above and do not need it anymore. It saves the disk space 107 | minikube image rm quay.io/devfile/base-developer-image:ubi9-latest 108 | minikube image list --format table 109 | 110 | - name: Install NodeJs 111 | uses: actions/setup-node@v4 112 | 113 | - name: Checkout tests codebase 114 | uses: actions/checkout@master 115 | with: 116 | ref: api-test-with-clone-project-without-generating 117 | repository: eclipse/che 118 | path: che 119 | 120 | # Host devfile locally. 121 | # Use the insiders tag for the che-code image and the PR number for the universal-developer-image 122 | - name: Host devfile locally 123 | run: | 124 | kubectl apply -f - < /checode/entrypoint-logs.txt 2>&1 & 142 | events: 143 | preStart: 144 | - init-container-command 145 | postStart: 146 | - init-che-code-command 147 | components: 148 | - name: che-code-injector 149 | container: 150 | image: quay.io/che-incubator/che-code:insiders 151 | command: 152 | - /entrypoint-init-container.sh 153 | volumeMounts: 154 | - name: checode 155 | path: /checode 156 | memoryLimit: 256Mi 157 | memoryRequest: 32Mi 158 | cpuLimit: 500m 159 | cpuRequest: 30m 160 | - name: che-code-runtime-description 161 | container: 162 | image: quay.io/devfile/universal-developer-image:${{ env.PR_NUMBER }} 163 | memoryLimit: 1024Mi 164 | memoryRequest: 256Mi 165 | cpuLimit: 500m 166 | cpuRequest: 30m 167 | volumeMounts: 168 | - name: checode 169 | path: /checode 170 | endpoints: 171 | - name: che-code 172 | attributes: 173 | type: main 174 | cookiesAuthEnabled: true 175 | discoverable: false 176 | urlRewriteSupported: true 177 | targetPort: 3100 178 | exposure: public 179 | secure: true 180 | protocol: https 181 | - name: code-redirect-1 182 | targetPort: 13131 183 | exposure: public 184 | protocol: https 185 | attributes: 186 | discoverable: false 187 | urlRewriteSupported: false 188 | - name: code-redirect-2 189 | targetPort: 13132 190 | exposure: public 191 | protocol: https 192 | attributes: 193 | discoverable: false 194 | urlRewriteSupported: false 195 | - name: code-redirect-3 196 | targetPort: 13133 197 | exposure: public 198 | protocol: https 199 | attributes: 200 | discoverable: false 201 | urlRewriteSupported: false 202 | attributes: 203 | app.kubernetes.io/component: che-code-runtime 204 | app.kubernetes.io/part-of: che-code.eclipse.org 205 | controller.devfile.io/container-contribution: true 206 | - name: checode 207 | volume: {} 208 | --- 209 | apiVersion: v1 210 | kind: Pod 211 | metadata: 212 | name: file-server 213 | labels: 214 | app: file-server 215 | spec: 216 | containers: 217 | - name: nginx-container 218 | image: nginx 219 | ports: 220 | - containerPort: 80 221 | volumeMounts: 222 | - name: server-volume 223 | mountPath: /usr/share/nginx/html 224 | readOnly: true 225 | volumes: 226 | - name: server-volume 227 | configMap: 228 | name: devfile.yaml 229 | --- 230 | apiVersion: v1 231 | kind: Service 232 | metadata: 233 | name: file-service 234 | spec: 235 | selector: 236 | app: file-server 237 | ports: 238 | - protocol: TCP 239 | port: 80 240 | targetPort: 80 241 | EOF 242 | 243 | - name: Run Empty workspace smoke test 244 | run: | 245 | export TS_API_TEST_UDI_IMAGE=quay.io/devfile/universal-developer-image:${{ env.PR_NUMBER }} 246 | export TS_API_TEST_CHE_CODE_EDITOR_DEVFILE_URI=http://file-service.default.svc:80/devfile.yaml 247 | cd che/tests/e2e 248 | npm i 249 | npm run driver-less-test 250 | 251 | -------------------------------------------------------------------------------- /.github/workflows/pr-check.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2021-2025 Red Hat, Inc. 3 | # This program and the accompanying materials are made 4 | # available under the terms of the Eclipse Public License 2.0 5 | # which is available at https://www.eclipse.org/legal/epl-2.0/ 6 | # 7 | # SPDX-License-Identifier: EPL-2.0 8 | # 9 | 10 | name: Pull Request Check 11 | 12 | # Trigger the workflow on pull request 13 | on: [pull_request] 14 | 15 | jobs: 16 | build-base-image: 17 | name: Build base image 18 | strategy: 19 | fail-fast: false 20 | matrix: 21 | runners: ['ubuntu-22.04', 'ubuntu-22.04-arm'] 22 | runs-on: ${{matrix.runners}} 23 | steps: 24 | - name: Checkout 25 | uses: actions/checkout@v4 26 | - name: Set arch environment variable 27 | run: | 28 | if [[ ${{matrix.runners}} == 'ubuntu-22.04' ]]; then 29 | echo arch="amd64" >> $GITHUB_ENV 30 | else 31 | echo arch="arm64" >> $GITHUB_ENV 32 | fi 33 | - name: Free runner space 34 | run: sudo rm -rf /usr/local/lib/android 35 | - name: Cleanup docker images 36 | run: docker system prune -af 37 | - name: Build base image 38 | run: | 39 | cd base/ubi9 && docker buildx build \ 40 | --platform linux/${{env.arch}} \ 41 | --progress=plain \ 42 | -t base-developer-image-${{env.arch}} . 43 | - name: Display docker images 44 | run: docker images 45 | - name: Compress image to a file 46 | run: docker save base-developer-image-${{env.arch}} | gzip > base-developer-image-${{env.arch}}.tgz 47 | - name: Upload image artifact 48 | uses: actions/upload-artifact@v4 49 | with: 50 | name: base-developer-image-${{env.arch}} 51 | path: base-developer-image-${{env.arch}}.tgz 52 | 53 | build-udi: 54 | name: Build udi 55 | strategy: 56 | fail-fast: false 57 | matrix: 58 | runners: ['ubuntu-22.04', 'ubuntu-22.04-arm'] 59 | runs-on: ${{matrix.runners}} 60 | needs: build-base-image 61 | steps: 62 | - name: Set arch environment variable 63 | run: | 64 | if [[ ${{matrix.runners}} == 'ubuntu-22.04' ]]; then 65 | echo arch="amd64" >> $GITHUB_ENV 66 | else 67 | echo arch="arm64" >> $GITHUB_ENV 68 | fi 69 | - name: Checkout 70 | uses: actions/checkout@v4 71 | - name: Free runner space 72 | run: sudo rm -rf /usr/local/lib/android 73 | - name: Cleanup docker images 74 | run: docker system prune -af 75 | - name: Download BDI artifacts 76 | uses: actions/download-artifact@v4 77 | with: 78 | pattern: base-developer-image-* 79 | merge-multiple: true 80 | path: . 81 | - name: List downloaded files 82 | run: ls -lah 83 | - name: Load docker images 84 | run: docker load -i base-developer-image-${{env.arch}}.tgz 85 | - name: Display docker images 86 | run: docker images 87 | - name: Update UDI Dockerfile 88 | run: sed "s|quay.io/devfile/base-developer-image:ubi9-latest|base-developer-image-${{env.arch}}|" -i "universal/ubi9/Dockerfile" 89 | - name: Login to Quay.io 90 | uses: docker/login-action@v3 91 | with: 92 | registry: quay.io 93 | username: ${{ secrets.QUAY_USERNAME }} 94 | password: ${{ secrets.QUAY_PASSWORD }} 95 | - name: Build udi 96 | run: | 97 | cd universal/ubi9 && docker buildx build \ 98 | --platform linux/${{env.arch}} \ 99 | --progress=plain \ 100 | --push \ 101 | -t quay.io/devfile/universal-developer-image:${{env.arch}}-pr-${{github.event.number}} . 102 | 103 | publish-udi: 104 | name: Publish udi 105 | runs-on: ubuntu-22.04 106 | needs: build-udi 107 | steps: 108 | - name: Login to Quay.io 109 | uses: docker/login-action@v3 110 | with: 111 | registry: quay.io 112 | username: ${{ secrets.QUAY_USERNAME }} 113 | password: ${{ secrets.QUAY_PASSWORD }} 114 | - name: publish 115 | run: | 116 | docker manifest create quay.io/devfile/universal-developer-image:pr-${{github.event.number}} \ 117 | --amend quay.io/devfile/universal-developer-image:amd64-pr-${{github.event.number}} \ 118 | --amend quay.io/devfile/universal-developer-image:arm64-pr-${{github.event.number}} 119 | 120 | docker manifest annotate quay.io/devfile/universal-developer-image:pr-${{github.event.number}} \ 121 | quay.io/devfile/universal-developer-image:amd64-pr-${{github.event.number}} \ 122 | --os linux --arch amd64 123 | docker manifest annotate quay.io/devfile/universal-developer-image:pr-${{github.event.number}} \ 124 | quay.io/devfile/universal-developer-image:arm64-pr-${{github.event.number}} \ 125 | --os linux --arch arm64 126 | 127 | docker manifest push quay.io/devfile/universal-developer-image:pr-${{github.event.number}} 128 | - name: 'Comment PR' 129 | uses: actions/github-script@v7 130 | with: 131 | script: | 132 | const { repo: { owner, repo } } = context; 133 | await github.rest.issues.createComment({ 134 | issue_number: ${{github.event.number}}, 135 | owner: context.repo.owner, 136 | repo: context.repo.repo, 137 | body: `Pull Request images published ✨\n\nUDI: [quay.io/devfile/universal-developer-image:pr-${{github.event.number}}](https://quay.io/devfile/universal-developer-image:pr-${{github.event.number}})` 138 | }) 139 | -------------------------------------------------------------------------------- /.github/workflows/ubi9-build.yaml: -------------------------------------------------------------------------------- 1 | 2 | name: Build of UBI 9 based Developer Images 3 | 4 | on: 5 | push: 6 | branches: [ main ] 7 | workflow_dispatch: 8 | 9 | workflow_call: 10 | # Map the workflow outputs to job outputs 11 | secrets: 12 | QUAY_USERNAME: 13 | required: true 14 | QUAY_PASSWORD: 15 | required: true 16 | outputs: 17 | uniq_tag: 18 | description: "The first output string" 19 | value: ${{ jobs.build_universal_ubi9_image.outputs.output1 }} 20 | 21 | jobs: 22 | build-base-image: 23 | name: Build base image 24 | strategy: 25 | fail-fast: false 26 | matrix: 27 | runners: ['ubuntu-22.04', 'ubuntu-22.04-arm'] 28 | runs-on: ${{matrix.runners}} 29 | steps: 30 | - name: Checkout 31 | uses: actions/checkout@v4 32 | - name: Set arch environment variable 33 | run: | 34 | if [[ ${{matrix.runners}} == 'ubuntu-22.04' ]]; then 35 | echo arch="amd64" >> $GITHUB_ENV 36 | else 37 | echo arch="arm64" >> $GITHUB_ENV 38 | fi 39 | - name: Set short_sha environment variable 40 | run: echo short_sha="$(git rev-parse --short=7 HEAD)" >> $GITHUB_ENV 41 | - name: Free runner space 42 | run: sudo rm -rf /usr/local/lib/android 43 | - name: Cleanup docker images 44 | run: docker system prune -af 45 | - name: Login to Quay.io 46 | uses: docker/login-action@v3 47 | with: 48 | registry: quay.io 49 | username: ${{ secrets.QUAY_USERNAME }} 50 | password: ${{ secrets.QUAY_PASSWORD }} 51 | - name: Build base image 52 | run: | 53 | cd base/ubi9 && docker buildx build \ 54 | --platform linux/${{env.arch}} \ 55 | --progress=plain \ 56 | --push \ 57 | -t quay.io/devfile/base-developer-image:${{env.arch}}-${{env.short_sha}} . 58 | 59 | publish-base-image: 60 | name: Publish base image 61 | runs-on: ubuntu-22.04 62 | needs: build-base-image 63 | steps: 64 | - name: Checkout 65 | uses: actions/checkout@v4 66 | - name: Set short_sha environment variable 67 | run: echo short_sha="$(git rev-parse --short=7 HEAD)" >> $GITHUB_ENV 68 | - name: Login to Quay.io 69 | uses: docker/login-action@v3 70 | with: 71 | registry: quay.io 72 | username: ${{ secrets.QUAY_USERNAME }} 73 | password: ${{ secrets.QUAY_PASSWORD }} 74 | - name: publish 75 | run: | 76 | for tag in latest ubi9-latest ubi9-${{env.short_sha}}; 77 | do 78 | docker manifest create quay.io/devfile/base-developer-image:${tag} \ 79 | --amend quay.io/devfile/base-developer-image:amd64-${{env.short_sha}} \ 80 | --amend quay.io/devfile/base-developer-image:arm64-${{env.short_sha}} 81 | 82 | docker manifest annotate quay.io/devfile/base-developer-image:${tag} \ 83 | quay.io/devfile/base-developer-image:amd64-${{env.short_sha}} \ 84 | --os linux --arch amd64 85 | 86 | docker manifest annotate quay.io/devfile/base-developer-image:${tag} \ 87 | quay.io/devfile/base-developer-image:arm64-${{env.short_sha}} \ 88 | --os linux --arch arm64 89 | 90 | docker manifest push quay.io/devfile/base-developer-image:${tag} 91 | done 92 | 93 | build-udi: 94 | name: Build udi 95 | strategy: 96 | fail-fast: false 97 | matrix: 98 | runners: ['ubuntu-22.04', 'ubuntu-22.04-arm'] 99 | runs-on: ${{matrix.runners}} 100 | needs: publish-base-image 101 | steps: 102 | - name: Checkout 103 | uses: actions/checkout@v4 104 | - name: Set arch environment variable 105 | run: | 106 | if [[ ${{matrix.runners}} == 'ubuntu-22.04' ]]; then 107 | echo arch="amd64" >> $GITHUB_ENV 108 | else 109 | echo arch="arm64" >> $GITHUB_ENV 110 | fi 111 | - name: Set short_sha environment variable 112 | run: echo short_sha="$(git rev-parse --short=7 HEAD)" >> $GITHUB_ENV 113 | - name: Free runner space 114 | run: sudo rm -rf /usr/local/lib/android 115 | - name: Cleanup docker images 116 | run: docker system prune -af 117 | - name: Login to Quay.io 118 | uses: docker/login-action@v3 119 | with: 120 | registry: quay.io 121 | username: ${{ secrets.QUAY_USERNAME }} 122 | password: ${{ secrets.QUAY_PASSWORD }} 123 | - name: Build udi 124 | run: | 125 | cd universal/ubi9 && docker buildx build \ 126 | --platform linux/${{env.arch}} \ 127 | --progress=plain \ 128 | --push \ 129 | -t quay.io/devfile/universal-developer-image:${{env.arch}}-${{env.short_sha}} . 130 | 131 | publish-udi: 132 | name: Publish udi 133 | runs-on: ubuntu-22.04 134 | needs: build-udi 135 | steps: 136 | - name: Checkout 137 | uses: actions/checkout@v4 138 | - name: Set short_sha environment variable 139 | run: echo short_sha="$(git rev-parse --short=7 HEAD)" >> $GITHUB_ENV 140 | - name: Login to Quay.io 141 | uses: docker/login-action@v3 142 | with: 143 | registry: quay.io 144 | username: ${{ secrets.QUAY_USERNAME }} 145 | password: ${{ secrets.QUAY_PASSWORD }} 146 | - name: publish 147 | run: | 148 | for tag in latest ubi9-latest ubi9-${{env.short_sha}}; 149 | do 150 | docker manifest create quay.io/devfile/universal-developer-image:${tag} \ 151 | --amend quay.io/devfile/universal-developer-image:amd64-${{env.short_sha}} \ 152 | --amend quay.io/devfile/universal-developer-image:arm64-${{env.short_sha}} 153 | 154 | docker manifest annotate quay.io/devfile/universal-developer-image:${tag} \ 155 | quay.io/devfile/universal-developer-image:amd64-${{env.short_sha}} \ 156 | --os linux --arch amd64 157 | 158 | docker manifest annotate quay.io/devfile/universal-developer-image:${tag} \ 159 | quay.io/devfile/universal-developer-image:arm64-${{env.short_sha}} \ 160 | --os linux --arch arm64 161 | 162 | docker manifest push quay.io/devfile/universal-developer-image:${tag} 163 | done 164 | - name: Get tag with uniq prefix 165 | id: setTagName 166 | # set the image with uniq tag prefix (for example: quay.io/..../base-developer-image:ubi9-7ad6cab) to env. var 167 | # and define it for output. This output with tag image will be used in caller job 168 | run: | 169 | echo "uniq_tag=quay.io/devfile/universal-developer-image:ubi9-${{env.short_sha}}" >> $GITHUB_OUTPUT 170 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Contribute to Developer Images 2 | ================ 3 | 4 | ## Developer Base Image 5 | 6 | ### Red Hat Universal Base Image ([UBI](https://developers.redhat.com/articles/ubi-faq#)) based image ([quay.io/devfile/base-developer-image:ubi9-latest](https://quay.io/repository/devfile/base-developer-image/)) 7 | 8 | Build with Docker buildkit: 9 | 10 | ```bash 11 | $ cd base/ubi9 12 | $ DOCKER_BUILDKIT=1 docker image build --progress=plain -t quay.io/devfile/base-developer-image:ubi9-latest . 13 | ``` 14 | 15 | ## Developer Universal Image 16 | 17 | ### Red Hat Universal Base Image ([UBI](https://developers.redhat.com/articles/ubi-faq#)) based image ([quay.io/devfile/universal-developer-image:ubi9-latest](https://quay.io/repository/devfile/universal-developer-image/)) 18 | 19 | Build with Docker buildkit: 20 | 21 | ```bash 22 | $ cd universal/ubi9 23 | $ DOCKER_BUILDKIT=1 docker image build --progress=plain -t quay.io/devfile/universal-developer-image:ubi9-latest . 24 | ``` 25 | 26 | To build for a specific architecture: 27 | 28 | ```bash 29 | # amd64 30 | $ DOCKER_BUILDKIT=1 docker image build --platform linux/amd64 --progress=plain -t quay.io/devfile/universal-developer-image:ubi9-latest . 31 | 32 | # arm64 33 | $ DOCKER_BUILDKIT=1 docker image build --platform linux/arm64 --progress=plain -t quay.io/devfile/universal-developer-image:ubi9-latest . 34 | ``` 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Contribute](https://www.eclipse.org/che/contribute.svg)](https://workspaces.openshift.com#https://github.com/devfile/developer-images) 2 | [![Dev](https://img.shields.io/static/v1?label=Open%20in&message=Che%20dogfooding%20server%20(with%20VS%20Code)&logo=eclipseche&color=FDB940&labelColor=525C86)](https://che-dogfooding.apps.che-dev.x6e0.p1.openshiftapps.com/#https://github.com/devfile/developer-images) 3 | 4 | # Developer Images 5 | 6 | [![Build of UBI 9 based Developer Images](https://github.com/devfile/developer-images/actions/workflows/ubi9-build.yaml/badge.svg)](https://github.com/devfile/developer-images/actions/workflows/ubi9-build.yaml) 7 | 8 | Containers images with tools for developers 👨‍💻👩‍💻 9 | 10 | ## Developer Base Image 11 | 12 | ### Red Hat Universal Base Image ([UBI](https://developers.redhat.com/articles/ubi-faq#)) based image ([quay.io/devfile/base-developer-image:ubi9-latest](https://quay.io/repository/devfile/base-developer-image)) 13 | 14 | Run the following command to test it with Docker: 15 | 16 | ```bash 17 | $ docker run -ti --rm \ 18 | quay.io/devfile/base-developer-image:ubi9-latest \ 19 | bash 20 | ``` 21 | ### Included Development Tools 22 | 23 | | Tool | ubi9 based image | 24 | |---------------------|-------------------------------------| 25 | | `bash` |`bash` | 26 | | `bat` |`` | 27 | | `buildah` |`buildah` | 28 | | `curl` |`curl` | 29 | | `ps` |`ps` | 30 | | `diff` |`diffutils` | 31 | | `emacs` |`NOT AVAILABLE (fedora only)` | 32 | | `fish` |`NOT AVAILABLE (fedora only)` | 33 | | `gh` |`` | 34 | | `git` |`git` | 35 | | `git-lfs` |`git-lfs` | 36 | | `ip` |`iproute` | 37 | | `jq` |`jq` | 38 | | `htop` |`NOT AVAILABLE (fedora only)` | 39 | | `kubedock` |`` | 40 | | `less` |`less` | 41 | | `lsof` |`lsof` | 42 | | `man` |`man` | 43 | | `nano` |`nano` | 44 | | `netcat` |`NOT AVAILABLE` | 45 | | `netstat` |`net-tools` | 46 | | `openssh-client` |`openssh-clients` | 47 | | `podman` |`podman` | 48 | | `7z` |`p7zip-plugins` | 49 | | `ripgrep` |`` | 50 | | `rsync` |`rsync` | 51 | | `scp` |`openssh-clients` | 52 | | `screen` |`NOT AVAILABLE` | 53 | | `sed` |`sed` | 54 | | `shasum` |`perl-Digest-SHA` | 55 | | `socat` |`socat` | 56 | | `sudo` |`sudo` | 57 | | `ss` |`NOT AVAILABLE` | 58 | | `ssl-cert` |`NOT AVAILABLE` | 59 | | `stow` |`stow` | 60 | | `tail` |`` | 61 | | `tar` |`tar` | 62 | | `time` |`time` | 63 | | `tldr` |`NOT AVAILABLE (fedora only)` | 64 | | `tmux` |`NOT AVAILABLE (fedora only)` | 65 | | `vim` |`vim` | 66 | | `wget` |`wget` | 67 | | `zip` |`zip` | 68 | | `zsh` |`NOT AVAILABLE (fedora only)` | 69 | | **TOTAL SIZE** | **903MB** (341MB compressed) | 70 | 71 | ### Extending the base image 72 | When extending the base image, `source kubedock_setup` should be called in the new image's entrypoint to set up kubedock support. This sets up a wrapper for podman to use kubedock for the following podman commands if the `KUBEDOCK_ENABLED` env variable is set to `true`: 73 | ``` 74 | podman run 75 | podman ps 76 | podman exec 77 | podman cp 78 | podman logs 79 | podman inspect 80 | podman kill 81 | podman rm 82 | podman wait 83 | podman stop 84 | podman start 85 | ``` 86 | 87 | An example is available in the Universal Developer Image dockerfile [here](https://github.com/devfile/developer-images/blob/main/universal/ubi9/entrypoint.sh#L3). 88 | 89 | ## Developer Universal Image 90 | 91 | ### Red Hat Universal Base Image ([UBI](https://developers.redhat.com/articles/ubi-faq#)) based image ([quay.io/devfile/universal-developer-image:ubi9-latest](https://quay.io/repository/devfile/universal-developer-image)) 92 | 93 | Run the following command to test it with Docker: 94 | 95 | ```bash 96 | docker run -ti --rm \ 97 | quay.io/devfile/universal-developer-image:ubi9-latest \ 98 | bash 99 | ``` 100 | ### Included Development Tools 101 | 102 | | Tool or language | ubi9 based image | 103 | |---------------------|-------------------------------------| 104 | |--------JAVA---------|-------------------------------------| 105 | | `sdk` |`` | 106 | | `java` |`<8.0.432-tem via sdkman>` | 107 | | `java` |`<11.0.25-tem via sdkman>` | 108 | | `java` |`<17.0.13-tem via sdkman>/default` | 109 | | `java` |`<21.0.5-tem via sdkman>` | 110 | | `maven` |`` | 111 | | `gradle` |`` | 112 | | `mandrel` |`<22.1.2.r21-mandrel via sdkman>` | 113 | | `jbang` |`` | 114 | |--------SCALA--------|-------------------------------------| 115 | | `cs` |`` | 116 | | `sbt` |`` | 117 | | `mill` |`` | 118 | |--------C/CPP--------|-------------------------------------| 119 | | `clang` |`clang` | 120 | | `clangd` |`llvm-toolset` | 121 | | `gdb` |`gdb` | 122 | |--------PHP----------|-------------------------------------| 123 | | `php` |`php` | 124 | | `composer` |`https://getcomposer.org/` | 125 | | `xdebug` |`pecl` | 126 | |-------NODEJS--------|-------------------------------------| 127 | | `nodejs` |`nodejs` | 128 | | `npm` |`npm` | 129 | | `yarn` |`` | 130 | |--------GO-----------|-------------------------------------| 131 | | `go` |`go-toolset` | 132 | | `gopls` |`golang.org/x/tools/gopls v0.16.2` | 133 | |--------.NET---------|-------------------------------------| 134 | | `dotnet` |`dotnet-sdk-8.0` | 135 | |------PYTHON---------|-------------------------------------| 136 | | `python` |`python3.11` | 137 | | `setuptools` |`python3.11-setuptools` | 138 | | `pip` |`python3.11-pip` | 139 | | `pylint` |`` | 140 | | `yq` |`` | 141 | |--------RUST---------|-------------------------------------| 142 | | `rustup` |`` | 143 | | `rust-src` |`` | 144 | | `rust-analysis` |`` | 145 | |--------Platform-----|-------------------------------------| 146 | | `camel-k` |`` | 147 | |------CLOUD----------|-------------------------------------| 148 | | `oc` |`mirror.openshift.com` | 149 | | `tkn` |`mirror.openshift.com` | 150 | | `podman` |`container-tools:rhel8` | 151 | | `buildah` |`container-tools:rhel8` | 152 | | `skopeo` |`container-tools:rhel8` | 153 | | `kubectl` |`` | 154 | | `krew` |`` | 155 | | `helm` |`` | 156 | | `kustomize` |`` | 157 | | `tkn` |`` | 158 | | `kn` |`` | 159 | | `terraform` |`` | 160 | | `docker` |`` | 161 | | `docker-compose` |`` | 162 | | `kamel` |`` | 163 | | **TOTAL SIZE** | **8.75GB** (3.6GB compressed) | 164 | 165 | ### Included libraries 166 | 167 | #### e2fsprogs v1.46.5 168 | 169 | ### Environment Variables 170 | 171 | #### Java 172 | JAVA_HOME_8, JAVA_HOME_11, JAVA_HOME_17, JAVA_HOME_21 173 | 174 | # Builds 175 | 176 | This repo contains [actions](https://github.com/devfile/developer-images/actions), including: 177 | * [![release latest stable](https://github.com/devfile/developer-images/actions/workflows/ubi9-build.yaml/badge.svg)](https://github.com/devfile/developer-images/actions/workflows/ubi9-build.yaml) 178 | 179 | Downstream builds can be found at the link below, which is _internal to Red Hat_. Stable builds can be found by replacing the 3.x with a specific version like 3.2. 180 | 181 | * [udi_3.x](https://main-jenkins-csb-crwqe.apps.ocp-c1.prod.psi.redhat.com/job/DS_CI/job/udi_3.x) 182 | 183 | # License 184 | 185 | Che is open sourced under the Eclipse Public License 2.0. 186 | -------------------------------------------------------------------------------- /base/ubi9/.stow-local-ignore: -------------------------------------------------------------------------------- 1 | # .viminfo cannot be a symlink for security reasons 2 | \.viminfo 3 | 4 | # We store bash related files in /home/tooling/ so they aren't overriden if persistUserHome is enabled 5 | # but we don't want them to be symbolic links (or to cause stow conflicts). They will be copied to /home/user/ manually. 6 | \.bashrc 7 | \.bash_profile 8 | 9 | # Ignore absolute symbolic links, as they are not supported by stow 10 | \.krew 11 | \.sdkman 12 | \.local/bin/podman 13 | 14 | # Ignore files under .config directory 15 | \.config 16 | -------------------------------------------------------------------------------- /base/ubi9/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax=docker/dockerfile:1.3-labs 2 | 3 | # https://registry.access.redhat.com/ubi9/ubi 4 | FROM registry.access.redhat.com/ubi9/ubi:9.6-1747219013 5 | 6 | ARG TARGETARCH 7 | LABEL maintainer="Red Hat, Inc." 8 | 9 | LABEL com.redhat.component="devfile-base-container" 10 | LABEL name="devfile/base-developer-image" 11 | LABEL version="ubi9" 12 | 13 | #label for EULA 14 | LABEL com.redhat.license_terms="https://www.redhat.com/en/about/red-hat-end-user-license-agreements#UBI" 15 | 16 | #labels for container catalog 17 | LABEL summary="devfile base developer image" 18 | LABEL description="Image with base developers tools. Languages SDK and runtimes excluded." 19 | LABEL io.k8s.display-name="devfile-developer-base" 20 | LABEL io.openshift.expose-services="" 21 | 22 | USER 0 23 | 24 | ENV HOME=/home/tooling 25 | RUN mkdir -p /home/tooling/ 26 | 27 | ## add epel repos so that p7zip p7zip-plugins stow can be found 28 | RUN dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm && \ 29 | dnf install -y diffutils git git-lfs iproute jq less lsof man nano procps p7zip p7zip-plugins \ 30 | perl-Digest-SHA net-tools openssh-clients rsync socat sudo time vim wget zip stow && \ 31 | dnf update -y && \ 32 | dnf clean all 33 | 34 | ## podman buildah skopeo 35 | RUN dnf -y reinstall shadow-utils && \ 36 | dnf -y install podman buildah skopeo fuse-overlayfs && \ 37 | dnf clean all 38 | 39 | # Download and install gh-cli depending on the architecture. 40 | # See release page for details https://github.com/cli/cli/releases/tag/v2.73.0 41 | RUN \ 42 | TEMP_DIR="$(mktemp -d)"; \ 43 | cd "${TEMP_DIR}"; \ 44 | GH_VERSION="2.73.0"; \ 45 | GH_ARCH="linux_$TARGETARCH"; \ 46 | GH_TGZ="gh_${GH_VERSION}_${GH_ARCH}.tar.gz"; \ 47 | GH_TGZ_URL="https://github.com/cli/cli/releases/download/v${GH_VERSION}/${GH_TGZ}"; \ 48 | GH_CHEKSUMS_URL="https://github.com/cli/cli/releases/download/v${GH_VERSION}/gh_${GH_VERSION}_checksums.txt"; \ 49 | curl -sSLO "${GH_TGZ_URL}"; \ 50 | curl -sSLO "${GH_CHEKSUMS_URL}"; \ 51 | sha256sum --ignore-missing -c "gh_${GH_VERSION}_checksums.txt" 2>&1 | grep OK; \ 52 | tar -zxv --no-same-owner -f "${GH_TGZ}"; \ 53 | mv "gh_${GH_VERSION}_${GH_ARCH}"/bin/gh /usr/local/bin/; \ 54 | mv "gh_${GH_VERSION}_${GH_ARCH}"/share/man/man1/* /usr/local/share/man/man1; \ 55 | cd -; \ 56 | rm -rf "${TEMP_DIR}" 57 | 58 | # Download and install ripgrep depending on the architecture. 59 | # See release page for details https://github.com/BurntSushi/ripgrep/releases/tag/13.0.0 60 | RUN \ 61 | TEMP_DIR="$(mktemp -d)"; \ 62 | cd "${TEMP_DIR}"; \ 63 | RG_VERSION="13.0.0"; \ 64 | if [ "$TARGETARCH" = "arm64" ]; then \ 65 | RG_ARCH="arm-unknown-linux-gnueabihf"; \ 66 | else \ 67 | RG_ARCH="x86_64-unknown-linux-musl"; \ 68 | fi; \ 69 | RG_TGZ="ripgrep-${RG_VERSION}-${RG_ARCH}.tar.gz"; \ 70 | RG_TGZ_URL="https://github.com/BurntSushi/ripgrep/releases/download/${RG_VERSION}/${RG_TGZ}"; \ 71 | curl -sSLO "${RG_TGZ_URL}"; \ 72 | tar -zxv --no-same-owner -f "${RG_TGZ}"; \ 73 | mv "ripgrep-${RG_VERSION}-${RG_ARCH}"/rg /usr/local/bin/; \ 74 | mv "ripgrep-${RG_VERSION}-${RG_ARCH}"/doc/rg.1 /usr/local/share/man/man1; \ 75 | cd -; \ 76 | rm -rf "${TEMP_DIR}" 77 | 78 | # Download and install bat depending on the architecture. 79 | # See release page for details https://github.com/sharkdp/bat/releases/tag/v0.18.3 80 | RUN \ 81 | TEMP_DIR="$(mktemp -d)"; \ 82 | cd "${TEMP_DIR}"; \ 83 | BAT_VERSION="0.18.3"; \ 84 | if [ "$TARGETARCH" = "arm64" ]; then \ 85 | BAT_ARCH="aarch64-unknown-linux-gnu"; \ 86 | else \ 87 | BAT_ARCH="x86_64-unknown-linux-musl"; \ 88 | fi; \ 89 | BAT_TGZ="bat-v${BAT_VERSION}-${BAT_ARCH}.tar.gz"; \ 90 | BAT_TGZ_URL="https://github.com/sharkdp/bat/releases/download/v${BAT_VERSION}/${BAT_TGZ}"; \ 91 | curl -sSLO "${BAT_TGZ_URL}"; \ 92 | tar -zxv --no-same-owner -f "${BAT_TGZ}"; \ 93 | mv "bat-v${BAT_VERSION}-${BAT_ARCH}"/bat /usr/local/bin/; \ 94 | mv "bat-v${BAT_VERSION}-${BAT_ARCH}"/bat.1 /usr/local/share/man/man1; \ 95 | cd -; \ 96 | rm -rf "${TEMP_DIR}" 97 | 98 | # Download and install fd depending on the architecture. 99 | # See release page for details https://github.com/sharkdp/fd/releases/tag/v8.7.0 100 | RUN \ 101 | TEMP_DIR="$(mktemp -d)" && \ 102 | cd "${TEMP_DIR}" && \ 103 | FD_VERSION="8.7.0" && \ 104 | if [ "$TARGETARCH" = "arm64" ]; then \ 105 | FD_ARCH="aarch64-unknown-linux-gnu"; \ 106 | else \ 107 | FD_ARCH="x86_64-unknown-linux-musl"; \ 108 | fi && \ 109 | FD_TGZ="fd-v${FD_VERSION}-${FD_ARCH}.tar.gz" && \ 110 | FD_TGZ_URL="https://github.com/sharkdp/fd/releases/download/v${FD_VERSION}/${FD_TGZ}" && \ 111 | curl -sSLO "${FD_TGZ_URL}" && \ 112 | tar -xv --no-same-owner -f "${FD_TGZ}" && \ 113 | mv "fd-v${FD_VERSION}-${FD_ARCH}"/fd /usr/local/bin && \ 114 | mv "fd-v${FD_VERSION}-${FD_ARCH}"/fd.1 /usr/local/share/man/man1 && \ 115 | cd - && \ 116 | rm -rf "${TEMP_DIR}" 117 | 118 | # Define user directory for binaries 119 | ENV PATH="/home/user/.local/bin:$PATH" 120 | 121 | # Set up environment variables to note that this is 122 | # not starting with usernamespace and default to 123 | # isolate the filesystem with chroot. 124 | ENV _BUILDAH_STARTED_IN_USERNS="" BUILDAH_ISOLATION=chroot 125 | 126 | # Tweaks to make rootless buildah work 127 | RUN touch /etc/subgid /etc/subuid && \ 128 | chmod g=u /etc/subgid /etc/subuid /etc/passwd && \ 129 | echo user:10000:65536 > /etc/subuid && \ 130 | echo user:10000:65536 > /etc/subgid 131 | 132 | # Adjust storage.conf to enable Fuse storage. 133 | RUN sed -i -e 's|^#mount_program|mount_program|g' -e '/additionalimage.*/a "/var/lib/shared",' /etc/containers/storage.conf 134 | RUN mkdir -p /var/lib/shared/overlay-images /var/lib/shared/overlay-layers; \ 135 | touch /var/lib/shared/overlay-images/images.lock; \ 136 | touch /var/lib/shared/overlay-layers/layers.lock 137 | 138 | # Add kubedock 139 | # See release page for details https://github.com/joyrex2001/kubedock/releases/tag/0.18.1 140 | ENV KUBEDOCK_VERSION 0.18.1 141 | ENV KUBECONFIG=/home/user/.kube/config 142 | RUN KUBEDOCK_ARCH="linux_amd64" && \ 143 | curl -L https://github.com/joyrex2001/kubedock/releases/download/${KUBEDOCK_VERSION}/kubedock_${KUBEDOCK_VERSION}_${KUBEDOCK_ARCH}.tar.gz | tar -C /usr/local/bin -xz --no-same-owner \ 144 | && chmod +x /usr/local/bin/kubedock 145 | COPY --chown=0:0 kubedock_setup.sh /usr/local/bin/kubedock_setup 146 | 147 | # Configure Podman wrapper 148 | ENV PODMAN_WRAPPER_PATH=/usr/bin/podman.wrapper 149 | ENV ORIGINAL_PODMAN_PATH=/usr/bin/podman.orig 150 | COPY --chown=0:0 podman-wrapper.sh "${PODMAN_WRAPPER_PATH}" 151 | RUN mv /usr/bin/podman "${ORIGINAL_PODMAN_PATH}" 152 | 153 | COPY --chown=0:0 entrypoint.sh / 154 | COPY --chown=0:0 .stow-local-ignore /home/tooling/ 155 | RUN \ 156 | # add user and configure it 157 | useradd -u 10001 -G wheel,root -d /home/user --shell /bin/bash -m user && \ 158 | # Setup $PS1 for a consistent and reasonable prompt 159 | touch /etc/profile.d/udi_prompt.sh && \ 160 | chown 10001 /etc/profile.d/udi_prompt.sh && \ 161 | echo "export PS1='\W \`git branch --show-current 2>/dev/null | sed -r -e \"s@^(.+)@\(\1\) @\"\`$ '" >> /etc/profile.d/udi_prompt.sh && \ 162 | # Copy the global git configuration to user config as global /etc/gitconfig 163 | # file may be overwritten by a mounted file at runtime 164 | cp /etc/gitconfig ${HOME}/.gitconfig && \ 165 | chown 10001 ${HOME}/ ${HOME}/.viminfo ${HOME}/.gitconfig ${HOME}/.stow-local-ignore && \ 166 | # Set permissions on /etc/passwd and /home to allow arbitrary users to write 167 | chgrp -R 0 /home && \ 168 | chmod -R g=u /etc/passwd /etc/group /home && \ 169 | chmod +x /entrypoint.sh && \ 170 | # Create symbolic links from /home/tooling/ -> /home/user/ 171 | stow . -t /home/user/ -d /home/tooling/ && \ 172 | # .viminfo cannot be a symbolic link for security reasons, so copy it to /home/user/ 173 | cp /home/tooling/.viminfo /home/user/.viminfo && \ 174 | # Bash-related files are backed up to /home/tooling/ incase they are deleted when persistUserHome is enabled. 175 | cp /home/user/.bashrc /home/tooling/.bashrc && \ 176 | cp /home/user/.bash_profile /home/tooling/.bash_profile && \ 177 | chown 10001 /home/tooling/.bashrc /home/tooling/.bash_profile 178 | 179 | USER 10001 180 | ENV HOME=/home/user 181 | WORKDIR /projects 182 | ENTRYPOINT [ "/entrypoint.sh" ] 183 | CMD ["tail", "-f", "/dev/null"] 184 | -------------------------------------------------------------------------------- /base/ubi9/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Ensure $HOME exists when starting 4 | if [ ! -d "${HOME}" ]; then 5 | mkdir -p "${HOME}" 6 | fi 7 | 8 | # Configure container builds to use vfs or fuse-overlayfs 9 | if [ ! -d "${HOME}/.config/containers" ]; then 10 | mkdir -p ${HOME}/.config/containers 11 | if [ -c "/dev/fuse" ] && [ -f "/usr/bin/fuse-overlayfs" ]; then 12 | (echo '[storage]';echo 'driver = "overlay"';echo '[storage.options.overlay]';echo 'mount_program = "/usr/bin/fuse-overlayfs"') > ${HOME}/.config/containers/storage.conf 13 | else 14 | (echo '[storage]';echo 'driver = "vfs"') > "${HOME}"/.config/containers/storage.conf 15 | fi 16 | fi 17 | 18 | # Create Sym Link for Composer Keys in /home/tooling/.config 19 | if [ -d /home/tooling/.config/composer ] && [ ! -d "${HOME}/.config/composer" ]; then 20 | mkdir -p ${HOME}/.config/composer 21 | ln -s /home/tooling/.config/composer/keys.dev.pub ${HOME}/.config/composer/keys.dev.pub 22 | ln -s /home/tooling/.config/composer/keys.tags.pub ${HOME}/.config/composer/keys.tags.pub 23 | fi 24 | 25 | # Setup $PS1 for a consistent and reasonable prompt 26 | if [ -w "${HOME}" ] && [ ! -f "${HOME}"/.bashrc ]; then 27 | echo "PS1='[\u@\h \W]\$ '" > "${HOME}"/.bashrc 28 | fi 29 | 30 | # Add current (arbitrary) user to /etc/passwd and /etc/group 31 | if ! whoami &> /dev/null; then 32 | if [ -w /etc/passwd ]; then 33 | echo "${USER_NAME:-user}:x:$(id -u):0:${USER_NAME:-user} user:${HOME}:/bin/bash" >> /etc/passwd 34 | echo "${USER_NAME:-user}:x:$(id -u):" >> /etc/group 35 | fi 36 | fi 37 | 38 | source kubedock_setup 39 | 40 | 41 | # Stow 42 | ## Required for https://github.com/eclipse/che/issues/22412 43 | 44 | # /home/user/ will be mounted to by a PVC if persistUserHome is enabled 45 | mountpoint -q /home/user/; HOME_USER_MOUNTED=$? 46 | 47 | # This file will be created after stowing, to guard from executing stow everytime the container is started 48 | STOW_COMPLETE=/home/user/.stow_completed 49 | 50 | if [ $HOME_USER_MOUNTED -eq 0 ] && [ ! -f $STOW_COMPLETE ]; then 51 | # There may be regular, non-symlink files in /home/user that match the 52 | # pathing of files in /home/tooling. Stow will error out when it tries to 53 | # stow on top of that. Instead, we can append to the current 54 | # /home/tooling/.stow-local-ignore file to ignore pre-existing, 55 | # non-symlinked files in /home/user that match those in /home/tooling before 56 | # we run stow. 57 | # 58 | # Create two text files containing a sorted path-based list of files in 59 | # /home/tooling and /home/user. Cut off "/home/user" and "/home/tooling" and 60 | # only get the sub-paths so we can do a proper comparison 61 | # 62 | # In the case of /home/user, we want regular file types and not symbolic 63 | # links. 64 | find /home/user -type f -xtype f -print | sort | sed 's|/home/user||g' > /tmp/user.txt 65 | find /home/tooling -print | sort | sed 's|/home/tooling||g' > /tmp/tooling.txt 66 | # We compare the two files, trying to find files that exist in /home/user 67 | # and /home/tooling. Being that the files that get flagged here are not 68 | # already synlinks, we will want to ignore them. 69 | IGNORE_FILES="$(comm -12 /tmp/user.txt /tmp/tooling.txt)" 70 | # We no longer require the file lists, so remove them 71 | rm /tmp/user.txt /tmp/tooling.txt 72 | # For each file we need to ignore, append them to 73 | # /home/tooling/.stow-local-ignore. 74 | for f in $IGNORE_FILES; do echo "${f}" >> /home/tooling/.stow-local-ignore;done 75 | # We are now ready to run stow 76 | # 77 | # Create symbolic links from /home/tooling/ -> /home/user/ 78 | stow . -t /home/user/ -d /home/tooling/ --no-folding -v 2 > /tmp/stow.log 2>&1 79 | # Vim does not permit .viminfo to be a symbolic link for security reasons, so manually copy it 80 | cp /home/tooling/.viminfo /home/user/.viminfo 81 | # We have to restore bash-related files back onto /home/user/ (since they will have been overwritten by the PVC) 82 | # but we don't want them to be symbolic links (so that they persist on the PVC) 83 | cp /home/tooling/.bashrc /home/user/.bashrc 84 | cp /home/tooling/.bash_profile /home/user/.bash_profile 85 | touch $STOW_COMPLETE 86 | fi 87 | 88 | exec "$@" 89 | -------------------------------------------------------------------------------- /base/ubi9/kubedock_setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Kubedock setup script meant to be run from the entrypoint script. 4 | 5 | LOCAL_BIN=/home/user/.local/bin 6 | ORIGINAL_PODMAN_PATH=${ORIGINAL_PODMAN_PATH:-"/usr/bin/podman.orig"} 7 | PODMAN_WRAPPER_PATH=${PODMAN_WRAPPER_PATH:-"/usr/bin/podman.wrapper"} 8 | 9 | mkdir -p "${LOCAL_BIN}" 10 | 11 | if [ "${KUBEDOCK_ENABLED:-false}" = "true" ]; then 12 | echo 13 | echo "Kubedock is enabled (env variable KUBEDOCK_ENABLED is set to true)." 14 | 15 | SECONDS=0 16 | KUBEDOCK_TIMEOUT=${KUBEDOCK_TIMEOUT:-10} 17 | until [ -f $KUBECONFIG ]; do 18 | if ((SECONDS > KUBEDOCK_TIMEOUT)); then 19 | break 20 | fi 21 | echo "Kubeconfig doesn't exist yet. Waiting..." 22 | sleep 1 23 | done 24 | 25 | if [ -f $KUBECONFIG ]; then 26 | echo "Kubeconfig found." 27 | 28 | KUBEDOCK_PARAMS=${KUBEDOCK_PARAMS:-"--reverse-proxy --kubeconfig $KUBECONFIG"} 29 | 30 | echo "Starting kubedock with params \"${KUBEDOCK_PARAMS}\"..." 31 | 32 | kubedock server ${KUBEDOCK_PARAMS} >/tmp/kubedock.log 2>&1 & 33 | 34 | echo "Done." 35 | 36 | echo "Replacing podman with podman-wrapper..." 37 | 38 | ln -f -s "${PODMAN_WRAPPER_PATH}" "${LOCAL_BIN}/podman" 39 | 40 | export TESTCONTAINERS_RYUK_DISABLED="true" 41 | export TESTCONTAINERS_CHECKS_DISABLE="true" 42 | 43 | echo "Done." 44 | echo 45 | else 46 | echo "Could not find Kubeconfig at $KUBECONFIG" 47 | echo "Giving up..." 48 | fi 49 | else 50 | echo 51 | echo "Kubedock is disabled. It can be enabled with the env variable \"KUBEDOCK_ENABLED=true\"" 52 | echo "set in the workspace Devfile or in a Kubernetes ConfigMap in the developer namespace." 53 | echo 54 | ln -f -s "${ORIGINAL_PODMAN_PATH}" "${LOCAL_BIN}/podman" 55 | fi 56 | -------------------------------------------------------------------------------- /base/ubi9/podman-wrapper.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -euo pipefail 3 | 4 | PODMAN_ORIGINAL_PATH=${PODMAN_ORIGINAL_PATH:-"/usr/bin/podman.orig"} 5 | KUBEDOCK_SUPPORTED_COMMANDS=${KUBEDOCK_SUPPORTED_COMMANDS:-"run ps exec cp logs inspect kill rm wait stop start"} 6 | 7 | PODMAN_ARGS=( "$@" ) 8 | 9 | TRUE=0 10 | FALSE=1 11 | 12 | exec_original_podman() { 13 | exec ${PODMAN_ORIGINAL_PATH} "${PODMAN_ARGS[@]}" 14 | } 15 | 16 | exec_kubedock_podman() { 17 | exec env CONTAINER_HOST=tcp://127.0.0.1:2475 "${PODMAN_ORIGINAL_PATH}" "${PODMAN_ARGS[@]}" 18 | } 19 | 20 | podman_command() { 21 | echo "${PODMAN_ARGS[0]}" 22 | } 23 | 24 | command_is_supported_by_kubedock() { 25 | CMD=$(podman_command) 26 | for SUPPORTED_CMD in $KUBEDOCK_SUPPORTED_COMMANDS; do 27 | if [ "$SUPPORTED_CMD" = "$CMD" ]; then 28 | return $TRUE 29 | fi 30 | done 31 | return ${FALSE} 32 | } 33 | 34 | if command_is_supported_by_kubedock; then 35 | exec_kubedock_podman 36 | else 37 | exec_original_podman 38 | fi 39 | -------------------------------------------------------------------------------- /universal/ubi9/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax=docker/dockerfile:1.3-labs 2 | 3 | # updateBaseImages.sh can't operate on SHA-based tags as they're not date-based or semver-sequential, and therefore cannot be ordered 4 | FROM quay.io/devfile/base-developer-image:ubi9-latest 5 | 6 | ARG TARGETARCH 7 | LABEL maintainer="Red Hat, Inc." 8 | 9 | LABEL com.redhat.component="devfile-universal-container" 10 | LABEL name="devfile/universal-developer-image" 11 | LABEL version="ubi9" 12 | 13 | #label for EULA 14 | LABEL com.redhat.license_terms="https://www.redhat.com/en/about/red-hat-end-user-license-agreements#UBI" 15 | 16 | #labels for container catalog 17 | LABEL summary="devfile universal developer image" 18 | LABEL description="Image with developers tools. Languages SDK and runtimes included." 19 | LABEL io.k8s.display-name="devfile-developer-universal" 20 | LABEL io.openshift.expose-services="" 21 | 22 | USER 0 23 | 24 | # $PROFILE_EXT contains all additions made to the bash environment 25 | ENV PROFILE_EXT=/etc/profile.d/udi_environment.sh 26 | RUN touch ${PROFILE_EXT} && chown 10001 ${PROFILE_EXT} 27 | 28 | USER 10001 29 | 30 | # We install everything to /home/tooling/ as /home/user/ may get overriden, see github.com/eclipse/che/issues/22412 31 | ENV HOME=/home/tooling 32 | 33 | # Java 34 | RUN curl -fsSL "https://get.sdkman.io/?rcupdate=false" | bash \ 35 | && bash -c ". /home/tooling/.sdkman/bin/sdkman-init.sh \ 36 | && sed -i "s/sdkman_auto_answer=false/sdkman_auto_answer=true/g" /home/tooling/.sdkman/etc/config \ 37 | && sed -i "s/sdkman_auto_env=false/sdkman_auto_env=true/g" /home/tooling/.sdkman/etc/config \ 38 | && sdk install java 8.0.432-tem \ 39 | && sdk install java 11.0.25-tem \ 40 | && sdk install java 17.0.13-tem \ 41 | && sdk install java 21.0.5-tem \ 42 | && sdk install java 23.1.5.r21-mandrel \ 43 | && sdk default java 17.0.13-tem \ 44 | && sdk install gradle \ 45 | && sdk install maven \ 46 | && sdk install jbang \ 47 | && sdk flush archives \ 48 | && sdk flush temp" \ 49 | && chgrp -R 0 /home/tooling && chmod -R g=u /home/tooling 50 | 51 | # sdk home java 52 | ENV JAVA_HOME_8=/home/tooling/.sdkman/candidates/java/8.0.432-tem 53 | ENV JAVA_HOME_11=/home/tooling/.sdkman/candidates/java/11.0.25-tem 54 | ENV JAVA_HOME_17=/home/tooling/.sdkman/candidates/java/17.0.13-tem 55 | ENV JAVA_HOME_21=/home/tooling/.sdkman/candidates/java/21.0.5-tem 56 | 57 | # Java-related environment variables are described and set by ${PROFILE_EXT}, which will be loaded by ~/.bashrc 58 | # To make Java working for dash and other shells, it needs to initialize them in the Dockerfile. 59 | ENV SDKMAN_CANDIDATES_API="https://api.sdkman.io/2" 60 | ENV SDKMAN_CANDIDATES_DIR="/home/tooling/.sdkman/candidates" 61 | ENV SDKMAN_DIR="/home/tooling/.sdkman" 62 | RUN if [ "$TARGETARCH" = "arm64" ]; then \ 63 | export SDKMAN_PLATFORM="linuxarm64"; \ 64 | else \ 65 | export SDKMAN_PLATFORM="linuxx64"; \ 66 | fi 67 | ENV SDKMAN_PLATFORM=${SDKMAN_PLATFORM} 68 | ENV SDKMAN_VERSION="5.18.2" 69 | 70 | ENV GRADLE_HOME="/home/tooling/.sdkman/candidates/gradle/current" 71 | ENV JAVA_HOME="/home/tooling/.sdkman/candidates/java/current" 72 | ENV MAVEN_HOME="/home/tooling/.sdkman/candidates/maven/current" 73 | 74 | ENV GRAALVM_HOME=/home/tooling/.sdkman/candidates/java/23.1.5.r21-mandrel 75 | 76 | ENV PATH="/home/tooling/.krew/bin:$PATH" 77 | ENV PATH="/home/tooling/.sdkman/candidates/maven/current/bin:$PATH" 78 | ENV PATH="/home/tooling/.sdkman/candidates/java/current/bin:$PATH" 79 | ENV PATH="/home/tooling/.sdkman/candidates/gradle/current/bin:$PATH" 80 | ENV PATH="/home/tooling/.local/share/coursier/bin:$PATH" 81 | 82 | # NodeJS 83 | RUN mkdir -p /home/tooling/.nvm/ 84 | ENV NVM_DIR="/home/tooling/.nvm" 85 | ENV NODEJS_20_VERSION=20.18.1 86 | ENV NODEJS_18_VERSION=18.20.5 87 | ENV NODEJS_DEFAULT_VERSION=${NODEJS_18_VERSION} 88 | RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | PROFILE=/dev/null bash 89 | RUN echo 'export NVM_DIR="$HOME/.nvm"' >> ${PROFILE_EXT} \ 90 | && echo '[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"' >> ${PROFILE_EXT} 91 | RUN source /home/user/.bashrc && \ 92 | nvm install v${NODEJS_20_VERSION} && \ 93 | nvm install v${NODEJS_18_VERSION} && \ 94 | nvm alias default v${NODEJS_DEFAULT_VERSION} && nvm use v${NODEJS_DEFAULT_VERSION} && \ 95 | npm install --global yarn@v1.22.22 &&\ 96 | chgrp -R 0 /home/tooling && chmod -R g=u /home/tooling 97 | ENV PATH=$NVM_DIR/versions/node/v${NODEJS_DEFAULT_VERSION}/bin:$PATH 98 | ENV NODEJS_HOME_20=$NVM_DIR/versions/node/v${NODEJS_20_VERSION} 99 | ENV NODEJS_HOME_18=$NVM_DIR/versions/node/v${NODEJS_18_VERSION} 100 | 101 | # kube 102 | ENV KUBECONFIG=/home/user/.kube/config 103 | 104 | USER 0 105 | 106 | # Required packages for AWT 107 | RUN dnf install -y libXext libXrender libXtst libXi 108 | 109 | # Lombok 110 | ENV LOMBOK_VERSION=1.18.18 111 | RUN wget -O /usr/local/lib/lombok.jar https://projectlombok.org/downloads/lombok-${LOMBOK_VERSION}.jar 112 | 113 | # Scala 114 | RUN curl -fLo cs https://git.io/coursier-cli && \ 115 | chmod +x cs && \ 116 | mv cs /usr/local/bin/ 117 | RUN curl -fLo sbt https://raw.githubusercontent.com/dwijnand/sbt-extras/master/sbt && \ 118 | chmod +x sbt && \ 119 | mv sbt /usr/local/bin/ 120 | RUN curl -fLo mill https://raw.githubusercontent.com/lefou/millw/main/millw && \ 121 | chmod +x mill && \ 122 | mv mill /usr/local/bin/ 123 | 124 | # C/CPP 125 | RUN dnf -y install llvm-toolset gcc gcc-c++ clang clang-libs clang-tools-extra gdb 126 | 127 | # Go 1.22+ - installed to /usr/bin/go 128 | # gopls 0.16.2+ - installed to /home/tooling/go/bin/gopls and /home/tooling/go/pkg/mod/ 129 | RUN dnf install -y go-toolset && \ 130 | GO111MODULE=on go install -v golang.org/x/tools/gopls@v0.16.2 && \ 131 | chgrp -R 0 /home/tooling && chmod -R g=u /home/tooling 132 | ENV GOBIN="/home/tooling/go/bin/" 133 | ENV PATH="$GOBIN:$PATH" 134 | 135 | # Python 136 | RUN dnf -y install python3.11 python3.11-devel python3.11-setuptools python3.11-pip nss_wrapper 137 | 138 | RUN cd /usr/bin \ 139 | && if [ ! -L python ]; then ln -s python3.11 python; fi \ 140 | && if [ ! -L pydoc ]; then ln -s pydoc3.11 pydoc; fi \ 141 | && if [ ! -L python-config ]; then ln -s python3.11-config python-config; fi \ 142 | && if [ ! -L pip ]; then ln -s pip-3.11 pip; fi 143 | 144 | RUN pip install pylint yq 145 | 146 | # PHP 147 | ENV PHP_VERSION=8.2 148 | RUN dnf -y module enable php:$PHP_VERSION && \ 149 | dnf install -y --setopt=tsflags=nodocs php php-mysqlnd php-pgsql php-bcmath \ 150 | php-gd php-intl php-json php-ldap php-mbstring php-pdo \ 151 | php-pear php-zlib php-mysqli php-curl php-xml php-devel\ 152 | php-process php-soap php-opcache php-fpm ca-certificates \ 153 | php-gmp php-pecl-xdebug php-pecl-zip mod_ssl hostname && \ 154 | wget https://getcomposer.org/installer -O /tmp/composer-installer.php && \ 155 | php /tmp/composer-installer.php --filename=composer --install-dir=/usr/local/bin 156 | 157 | ENV PHP_DEFAULT_INCLUDE_PATH=/usr/share/pear \ 158 | PHP_SYSCONF_PATH=/etc \ 159 | PHP_HTTPD_CONF_FILE=php.conf \ 160 | HTTPD_MAIN_CONF_PATH=/etc/httpd/conf \ 161 | HTTPD_MAIN_CONF_D_PATH=/etc/httpd/conf.d \ 162 | HTTPD_MODULES_CONF_D_PATH=/etc/httpd/conf.modules.d \ 163 | HTTPD_VAR_RUN=/var/run/httpd \ 164 | HTTPD_DATA_PATH=/var/www \ 165 | HTTPD_DATA_ORIG_PATH=/var/www \ 166 | HTTPD_VAR_PATH=/var 167 | 168 | # .NET 169 | ENV DOTNET_RPM_VERSION=8.0 170 | RUN dnf install -y dotnet-hostfxr-${DOTNET_RPM_VERSION} dotnet-runtime-${DOTNET_RPM_VERSION} dotnet-sdk-${DOTNET_RPM_VERSION} 171 | 172 | # rust 173 | ENV CARGO_HOME=/home/tooling/.cargo \ 174 | RUSTUP_HOME=/home/tooling/.rustup \ 175 | PATH=/home/tooling/.cargo/bin:${PATH} 176 | RUN curl --proto '=https' --tlsv1.2 -sSfo rustup https://sh.rustup.rs && \ 177 | chmod +x rustup && \ 178 | mv rustup /usr/bin/ && \ 179 | rustup -y --no-modify-path --profile minimal -c rust-src -c rust-analysis -c rls && \ 180 | chgrp -R 0 /home/tooling && chmod -R g=u /home/tooling 181 | 182 | # camel-k 183 | ENV KAMEL_VERSION 2.2.0 184 | RUN curl -L https://github.com/apache/camel-k/releases/download/v${KAMEL_VERSION}/camel-k-client-${KAMEL_VERSION}-linux-${TARGETARCH}.tar.gz | tar -C /usr/local/bin -xz --no-same-owner \ 185 | && chmod +x /usr/local/bin/kamel 186 | 187 | # Config directories 188 | RUN mkdir -p /home/tooling/.m2 && \ 189 | mkdir -p /home/tooling/.gradle && \ 190 | mkdir -p /home/tooling/.config/pip && \ 191 | mkdir -p /home/tooling/.sbt/1.0 && \ 192 | mkdir -p /home/tooling/.cargo && \ 193 | mkdir -p /home/tooling/certs && \ 194 | mkdir -p /home/tooling/.composer && \ 195 | mkdir -p /home/tooling/.nuget && \ 196 | chgrp -R 0 /home/tooling && chmod -R g=u /home/tooling 197 | 198 | # Cloud 199 | 200 | # oc client 201 | ENV OC_VERSION=4.15 202 | RUN if [ "$TARGETARCH" = "arm64" ]; then \ 203 | curl -L https://mirror.openshift.com/pub/openshift-v4/arm64/clients/ocp/stable-${OC_VERSION}/openshift-client-linux.tar.gz; \ 204 | else \ 205 | curl -L https://mirror.openshift.com/pub/openshift-v4/x86_64/clients/ocp/stable-${OC_VERSION}/openshift-client-linux.tar.gz; \ 206 | fi | tar -C /usr/local/bin -xz --no-same-owner && \ 207 | chmod +x /usr/local/bin/oc 208 | 209 | # OS Pipelines CLI (tkn) 210 | ENV TKN_VERSION=1.14.0 211 | RUN curl -L https://mirror.openshift.com/pub/openshift-v4/clients/pipelines/${TKN_VERSION}/tkn-linux-${TARGETARCH}.tar.gz | tar -C /usr/local/bin -xz --no-same-owner \ 212 | && chmod +x /usr/local/bin/tkn /usr/local/bin/opc /usr/local/bin/tkn-pac 213 | 214 | RUN echo 'alias docker=podman' >> ${PROFILE_EXT} 215 | 216 | # Configure container engine 217 | COPY --chown=0:0 containers.conf /etc/containers/containers.conf 218 | 219 | ENV K8S_VERSION=1.28 220 | ## kubectl 221 | RUN < /etc/yum.repos.d/kubernetes.repo 225 | [kubernetes] 226 | name=Kubernetes 227 | baseurl=https://pkgs.k8s.io/core:/stable:/v${K8S_VERSION}/rpm/ 228 | enabled=1 229 | gpgcheck=1 230 | gpgkey=https://pkgs.k8s.io/core:/stable:/v${K8S_VERSION}/rpm/repodata/repomd.xml.key 231 | EOF2 232 | 233 | dnf install -y kubectl 234 | curl -sSL -o ~/.kubectl_aliases https://raw.githubusercontent.com/ahmetb/kubectl-alias/master/.kubectl_aliases 235 | echo '[ -f ~/.kubectl_aliases ] && source ~/.kubectl_aliases' >> ${PROFILE_EXT} 236 | EOF 237 | 238 | ## shellcheck 239 | RUN < "${KREW_TGZ}.sha256" 274 | 275 | sha256sum -c "${KREW_TGZ}.sha256" 2>&1 | grep OK 276 | 277 | tar -zxv --no-same-owner -f "${KREW_TGZ}" 278 | ./"krew-${KREW_ARCH}" install krew 279 | echo 'export PATH="${KREW_ROOT:-$HOME/.krew}/bin:$PATH"' >> ${PROFILE_EXT} 280 | export PATH="${KREW_ROOT:-$HOME/.krew}/bin:$PATH" 281 | # kubens and kubectx 282 | kubectl krew install ns 283 | kubectl krew install ctx 284 | cd - 285 | rm -rf "${TEMP_DIR}" 286 | EOF 287 | 288 | ## helm 289 | RUN <&1 | grep OK 300 | tar -zxv --no-same-owner -f "${HELM_TGZ}" 301 | mv "${HELM_ARCH}"/helm /usr/local/bin/helm 302 | cd - 303 | rm -rf "${TEMP_DIR}" 304 | EOF 305 | 306 | ## kustomize 307 | RUN <&1 | grep OK 319 | tar -zxv --no-same-owner -f "${KUSTOMIZE_TGZ}" 320 | mv kustomize /usr/local/bin/ 321 | cd - 322 | rm -rf "${TEMP_DIR}" 323 | EOF 324 | 325 | ## tektoncd-cli 326 | RUN <&1 | grep OK 342 | tar -zxv --no-same-owner -f "${TKN_TGZ}" 343 | mv tkn /usr/local/bin/ 344 | cd - 345 | rm -rf "${TEMP_DIR}" 346 | EOF 347 | 348 | ## knative-cli 349 | RUN <&1 | grep OK 361 | mv "${KN_BIN}" kn 362 | chmod +x kn 363 | mv kn /usr/local/bin 364 | cd - 365 | rm -rf "${TEMP_DIR}" 366 | EOF 367 | 368 | ## terraform-cli 369 | RUN <&1 | grep OK 381 | unzip ${TF_ZIP} 382 | chmod +x terraform 383 | mv terraform /usr/local/bin 384 | cd - 385 | rm -rf "${TEMP_DIR}" 386 | EOF 387 | 388 | ## skaffold 389 | RUN curl -Lo skaffold https://storage.googleapis.com/skaffold/releases/latest/skaffold-linux-${TARGETARCH} && \ 390 | install skaffold /usr/local/bin/ 391 | 392 | # e2fsprogs setup 393 | # Since e2fsprogs-static package has removed RHEL 8 distribution, it is not possible to install from the repository 394 | # https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html-single/considerations_in_adopting_rhel_8/index#removed-packages_changes-to-packages 395 | RUN <&1 | grep OK 406 | tar -zxv --no-same-owner -f "${E2FSPROGS_TGZ}" 407 | cd "e2fsprogs-${E2FSPROGS_VERSION}" 408 | mkdir build 409 | cd build 410 | ../configure --prefix=/usr --with-root-prefix="" --enable-elf-shlibs --disable-evms 411 | make 412 | make install 413 | make install-libs 414 | cd - 415 | rm -rf "${TEMP_DIR}" 416 | EOF 417 | 418 | # Bash completions 419 | RUN dnf -y install bash-completion \ 420 | && dnf clean all \ 421 | && rm -rf /var/cache/yum 422 | 423 | RUN < /usr/share/bash-completion/completions/oc 425 | tkn completion bash > /usr/share/bash-completion/completions/tkn 426 | kubectl completion bash > /usr/share/bash-completion/completions/kubectl 427 | cat ${NVM_DIR}/bash_completion > /usr/share/bash-completion/completions/nvm 428 | EOF 429 | 430 | ## Add sdkman's init script launcher to the end of ${PROFILE_EXT} since we are not adding it on sdkman install 431 | ## NOTE: all modifications to ${PROFILE_EXT} must happen BEFORE this step in order for sdkman to function correctly 432 | RUN echo 'export SDKMAN_DIR="/home/tooling/.sdkman"' >> ${PROFILE_EXT} 433 | RUN echo '[[ -s "$SDKMAN_DIR/bin/sdkman-init.sh" ]] && source "$SDKMAN_DIR/bin/sdkman-init.sh"' >> ${PROFILE_EXT} 434 | 435 | 436 | # Create symbolic links from /home/tooling/ -> /home/user/ 437 | RUN stow . -t /home/user/ -d /home/tooling/ --no-folding 438 | 439 | # Set permissions on /etc/passwd, /etc/group, /etc/pki and /home to allow arbitrary users to write 440 | RUN chgrp -R 0 /home && chmod -R g=u /etc/passwd /etc/group /home /etc/pki 441 | 442 | # cleanup dnf cache 443 | RUN dnf -y clean all --enablerepo='*' 444 | 445 | USER 10001 446 | 447 | ENV HOME=/home/user 448 | -------------------------------------------------------------------------------- /universal/ubi9/containers.conf: -------------------------------------------------------------------------------- 1 | [containers] 2 | default_ulimits = [ 3 | "nofile=65535:65535", 4 | ] 5 | --------------------------------------------------------------------------------