diff --git a/.drone/drone.yml b/.drone/drone.yml deleted file mode 100644 index b7a9989..0000000 --- a/.drone/drone.yml +++ /dev/null @@ -1,139 +0,0 @@ -kind: pipeline -type: exec -name: linux-amd64 - -platform: - arch: amd64 - os: linux - -steps: -- name: test - commands: - - mkdir -p $HOMEPATH/.docker; echo $IMAGE_PULL_SECRETS > $HOMEPATH/.docker/config.json - - make docker-build test - environment: - VERSION: ${DRONE_TAG:-latest}-linux-amd64 - DEV_REGISTRY: - from_secret: dev_registry - DRYCC_REGISTRY: - from_secret: drycc_registry - IMAGE_PULL_SECRETS: - from_secret: container_pull_secrets - when: - event: - - push - - tag - - pull_request - -- name: publish - commands: - - echo $CONTAINER_PASSWORD | docker login $DRYCC_REGISTRY --username $CONTAINER_USERNAME --password-stdin > /dev/null 2>&1 - - make docker-build docker-immutable-push - environment: - VERSION: ${DRONE_TAG:-latest}-linux-amd64 - DEV_REGISTRY: - from_secret: dev_registry - DRYCC_REGISTRY: - from_secret: drycc_registry - CONTAINER_USERNAME: - from_secret: container_username - CONTAINER_PASSWORD: - from_secret: container_password - when: - event: - - push - - tag - ---- -kind: pipeline -type: exec -name: linux-arm64 - -platform: - arch: arm64 - os: linux - -steps: -- name: publish - commands: - - echo $CONTAINER_PASSWORD | docker login $DRYCC_REGISTRY --username $CONTAINER_USERNAME --password-stdin > /dev/null 2>&1 - - make docker-build docker-immutable-push - environment: - VERSION: ${DRONE_TAG:-latest}-linux-arm64 - DEV_REGISTRY: - from_secret: dev_registry - DRYCC_REGISTRY: - from_secret: drycc_registry - CONTAINER_USERNAME: - from_secret: container_username - CONTAINER_PASSWORD: - from_secret: container_password - when: - event: - - push - - tag - ---- -kind: pipeline -type: docker -name: manifest -image_pull_secrets: -- container_pull_secrets - -steps: -- name: generate manifest - image: registry.drycc.cc/drycc/python-dev - pull: always - commands: - - sed -i "s/registry.drycc.cc/$${DRYCC_REGISTRY}/g" .drone/manifest.tmpl - environment: - DRYCC_REGISTRY: - from_secret: drycc_registry - -- name: publish - image: plugins/manifest - settings: - spec: .drone/manifest.tmpl - username: - from_secret: container_username - password: - from_secret: container_password - environment: - DEV_REGISTRY: - from_secret: dev_registry - DRYCC_REGISTRY: - from_secret: drycc_registry - -trigger: - event: - - push - - tag - -depends_on: -- linux-amd64 -- linux-arm64 - ---- -kind: pipeline -type: exec -name: chart - -steps: -- name: generate chart - commands: - - IMAGE_TAG=$([ ! -z $DRONE_TAG ] && echo ${DRONE_TAG:1} || echo \"canary\") - - sed -i "s/imageTag:\ \"canary\"/imageTag:\ $IMAGE_TAG/g" charts/registry/values.yaml - - helm package -u charts/registry --version $([ -z $DRONE_TAG ] && echo 1.0.0 || echo ${DRONE_TAG#v}) - - echo $CONTAINER_PASSWORD | helm registry login $DRYCC_REGISTRY -u $CONTAINER_USERNAME --password-stdin - - helm push registry-$([ -z $DRONE_TAG ] && echo 1.0.0 || echo ${DRONE_TAG#v}).tgz oci://$DRYCC_REGISTRY/$([ -z $DRONE_TAG ] && echo charts-testing || echo charts) - environment: - DRYCC_REGISTRY: - from_secret: drycc_registry - CONTAINER_USERNAME: - from_secret: container_username - CONTAINER_PASSWORD: - from_secret: container_password - when: - event: - - push - - tag diff --git a/.drone/manifest.tmpl b/.drone/manifest.tmpl deleted file mode 100644 index 04806b3..0000000 --- a/.drone/manifest.tmpl +++ /dev/null @@ -1,18 +0,0 @@ -image: registry.drycc.cc/drycc/registry:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}canary{{/if}} -{{#if build.tags}} -tags: -{{#each build.tags}} - - {{this}} -{{/each}} -{{/if}} -manifests: - - - image: registry.drycc.cc/drycc/registry:{{#if build.tag}}{{build.tag}}-{{else}}latest-{{/if}}linux-amd64 - platform: - architecture: amd64 - os: linux - - - image: registry.drycc.cc/drycc/registry:{{#if build.tag}}{{build.tag}}-{{else}}latest-{{/if}}linux-arm64 - platform: - architecture: arm64 - os: linux diff --git a/.gitignore b/.gitignore index 1b73338..e5361b7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ -rootfs/opt/ contrib/ci/tmp/ .vscode/ +rootfs/opt/registry/sbin \ No newline at end of file diff --git a/.woodpecker/build-linux.yml b/.woodpecker/build-linux.yml new file mode 100644 index 0000000..ef4ecfd --- /dev/null +++ b/.woodpecker/build-linux.yml @@ -0,0 +1,35 @@ +matrix: + platform: + - linux/amd64 + - linux/arm64 + +labels: + type: exec + platform: ${platform} + +steps: +- name: publish-linux + image: bash + commands: + - export VERSION=$([ -z $CI_COMMIT_TAG ] && echo latest || echo $CI_COMMIT_TAG)-$(sed 's#/#-#g' <<< $CI_SYSTEM_PLATFORM) + - echo $CONTAINER_PASSWORD | podman login $DRYCC_REGISTRY --username $CONTAINER_USERNAME --password-stdin > /dev/null 2>&1 + - make podman-build podman-immutable-push + environment: + CODENAME: + from_secret: codename + DEV_REGISTRY: + from_secret: dev_registry + DRYCC_REGISTRY: + from_secret: drycc_registry + CONTAINER_USERNAME: + from_secret: container_username + CONTAINER_PASSWORD: + from_secret: container_password + when: + event: + - push + - tag + - cron + +depends_on: +- test-linux \ No newline at end of file diff --git a/.woodpecker/chart.yaml b/.woodpecker/chart.yaml new file mode 100644 index 0000000..cfcd3ec --- /dev/null +++ b/.woodpecker/chart.yaml @@ -0,0 +1,33 @@ +labels: + type: exec + platform: linux/amd64 + +steps: +- name: generate-chart + image: bash + commands: + - export VERSION=$(sed 's#v##' <<< $CI_COMMIT_TAG) + - export IMAGE_TAG=$([ ! -z $CI_COMMIT_TAG ] && echo \"$VERSION\" || echo \"canary\") + - export APP_VERSION=$([ -z $CI_COMMIT_TAG ] && echo $CI_COMMIT_SHA || echo $VERSION) + - export CHART_VERSION=$([ -z $CI_COMMIT_TAG ] && echo 1.0.0 || echo $VERSION) + - sed -i "s/imageTag:\ \"canary\"/imageTag:\ $IMAGE_TAG/g" charts/$${CI_REPO_NAME}/values.yaml + - helm package -u charts/$${CI_REPO_NAME} --version $CHART_VERSION --app-version $APP_VERSION + - echo $CONTAINER_PASSWORD | helm registry login $DRYCC_REGISTRY -u $CONTAINER_USERNAME --password-stdin + - helm push $${CI_REPO_NAME}-$CHART_VERSION.tgz oci://$DRYCC_REGISTRY/$([ -z $CI_COMMIT_TAG ] && echo charts-testing || echo charts) + environment: + DEV_REGISTRY: + from_secret: dev_registry + DRYCC_REGISTRY: + from_secret: drycc_registry + CONTAINER_USERNAME: + from_secret: container_username + CONTAINER_PASSWORD: + from_secret: container_password + when: + event: + - push + - tag + - cron + +depends_on: +- manifest diff --git a/.woodpecker/manifest.tmpl b/.woodpecker/manifest.tmpl new file mode 100644 index 0000000..8739535 --- /dev/null +++ b/.woodpecker/manifest.tmpl @@ -0,0 +1,18 @@ +image: registry.drycc.cc/drycc/{{project}}:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}canary{{/if}} +{{#if build.tags}} +tags: +{{#each build.tags}} + - {{this}} +{{/each}} +{{/if}} +manifests: + - + image: registry.drycc.cc/drycc/{{project}}:{{#if build.tag}}{{build.tag}}-{{else}}latest-{{/if}}linux-amd64 + platform: + architecture: amd64 + os: linux + - + image: registry.drycc.cc/drycc/{{project}}:{{#if build.tag}}{{build.tag}}-{{else}}latest-{{/if}}linux-arm64 + platform: + architecture: arm64 + os: linux diff --git a/.woodpecker/manifest.yml b/.woodpecker/manifest.yml new file mode 100644 index 0000000..19fc70c --- /dev/null +++ b/.woodpecker/manifest.yml @@ -0,0 +1,43 @@ +labels: + type: exec + platform: linux/amd64 + +steps: +- name: generate-manifest + image: bash + commands: + - sed -i "s/{{project}}/$${CI_REPO_NAME}/g" .woodpecker/manifest.tmpl + - sed -i "s/registry.drycc.cc/$${DRYCC_REGISTRY}/g" .woodpecker/manifest.tmpl + environment: + DRYCC_REGISTRY: + from_secret: drycc_registry + when: + event: + - tag + - push + - cron + +- name: publish-manifest + image: bash + commands: + - podman run --rm + -e PLUGIN_SPEC=.woodpecker/manifest.tmpl + -e PLUGIN_USERNAME=$CONTAINER_USERNAME + -e PLUGIN_PASSWORD=$CONTAINER_PASSWORD + -e DRONE_TAG=$CI_COMMIT_TAG + -v $(pwd):$(pwd) + -w $(pwd) + docker.io/plugins/manifest + environment: + CONTAINER_USERNAME: + from_secret: container_username + CONTAINER_PASSWORD: + from_secret: container_password + when: + event: + - tag + - push + - cron + +depends_on: +- build-linux diff --git a/.woodpecker/test-linux.yml b/.woodpecker/test-linux.yml new file mode 100644 index 0000000..194832f --- /dev/null +++ b/.woodpecker/test-linux.yml @@ -0,0 +1,24 @@ +matrix: + platform: + - linux/amd64 + - linux/arm64 + +labels: + type: exec + platform: ${platform} + +steps: +- name: test-linux + image: bash + commands: + - make test + environment: + CODENAME: + from_secret: codename + DEV_REGISTRY: + from_secret: dev_registry + when: + event: + - push + - tag + - cron diff --git a/Dockerfile b/Dockerfile index f7f96d2..e9e37c3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,31 +1,31 @@ +ARG CODENAME + FROM registry.drycc.cc/drycc/go-dev:latest AS build ARG LDFLAGS ADD . /workspace RUN export GO111MODULE=on \ && cd /workspace \ - && CGO_ENABLED=0 init-stack go build -ldflags "${LDFLAGS}" -o /usr/local/bin/registry main.go \ - && upx -9 --brute /usr/local/bin/registry + && CGO_ENABLED=0 init-stack go build -ldflags "${LDFLAGS}" -o /bin/start-registry main.go \ + && upx -9 --brute /bin/start-registry -FROM registry.drycc.cc/drycc/base:bullseye +FROM registry.drycc.cc/drycc/base:${CODENAME} -ENV DRYCC_UID=1001 \ +ARG DRYCC_UID=1001 \ DRYCC_GID=1001 \ DRYCC_HOME_DIR=/var/lib/registry \ - JQ_VERSION="1.6" \ - MC_VERSION="2022.08.28.20.08.11" \ - REGISTRY_VERSION="2.8.0" - -COPY rootfs/bin/ /bin/ -COPY --from=build /usr/local/bin/registry /opt/registry/bin/registry + JQ_VERSION="1.7.1" \ + NGINX_VERSION="1.29.1" \ + RCLONE_VERSION="1.71.1" \ + REGISTRY_VERSION="3.0.0" RUN groupadd drycc --gid ${DRYCC_GID} \ && useradd drycc -u ${DRYCC_UID} -g ${DRYCC_GID} -s /bin/bash -m -d ${DRYCC_HOME_DIR} \ && install-packages apache2-utils \ && install-stack jq $JQ_VERSION \ - && install-stack mc $MC_VERSION \ + && install-stack nginx ${NGINX_VERSION} \ + && install-stack rclone $RCLONE_VERSION \ && install-stack registry $REGISTRY_VERSION \ - && chmod +x /bin/init_registry \ && rm -rf \ /usr/share/doc \ /usr/share/man \ @@ -40,12 +40,16 @@ RUN groupadd drycc --gid ${DRYCC_GID} \ /usr/lib/`echo $(uname -m)`-linux-gnu/gconv/IBM* \ /usr/lib/`echo $(uname -m)`-linux-gnu/gconv/EBC* \ && mkdir -p /usr/share/man/man{1..8} \ - && chown -R ${DRYCC_UID}:${DRYCC_GID} ${DRYCC_HOME_DIR} + && chown -R ${DRYCC_UID}:${DRYCC_GID} /opt/drycc +COPY --from=build /bin/start-registry /bin/start-registry +COPY --chown=${DRYCC_UID}:${DRYCC_GID} rootfs/bin/ /bin/ +COPY --chown=${DRYCC_UID}:${DRYCC_GID} rootfs/opt/drycc/nginx /opt/drycc/nginx COPY --chown=${DRYCC_UID}:${DRYCC_GID} rootfs/config-example.yml /opt/drycc/registry/etc/config.yml -ENV DRYCC_REGISTRY_CONFIG /opt/drycc/registry/etc/config.yml + +ENV OTEL_TRACES_EXPORTER=none \ + DRYCC_REGISTRY_CONFIG=/opt/drycc/registry/etc/config.yml USER ${DRYCC_UID} VOLUME ["${DRYCC_HOME_DIR}"] -CMD ["/opt/registry/bin/registry"] EXPOSE 5000 diff --git a/Makefile b/Makefile index d75fcb0..7fce73e 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ # Short name: Short name, following [a-zA-Z_], used all over the place. # Some uses for short name: -# - Docker image name +# - Container image name # - Kubernetes service, deployment, pod names SHORT_NAME := registry DRYCC_REGISTRY ?= ${DEV_REGISTRY} @@ -17,7 +17,7 @@ SHELL_SCRIPTS = $(wildcard rootfs/bin/* _scripts/*.sh contrib/ci/*.sh) # and other build options DEV_ENV_IMAGE := ${DEV_REGISTRY}/drycc/go-dev DEV_ENV_WORK_DIR := /opt/drycc/go/src/${REPO_PATH} -DEV_ENV_PREFIX := docker run --rm -v ${CURDIR}:${DEV_ENV_WORK_DIR} -w ${DEV_ENV_WORK_DIR} +DEV_ENV_PREFIX := podman run --rm -v ${CURDIR}:${DEV_ENV_WORK_DIR} -w ${DEV_ENV_WORK_DIR} DEV_ENV_CMD := ${DEV_ENV_PREFIX} ${DEV_ENV_IMAGE} LDFLAGS := "-s -w -X main.version=${VERSION}" BINDIR := ./rootfs/opt/registry/sbin @@ -29,31 +29,28 @@ endif all: @echo "Use a Makefile to control top-level building of the project." -build: check-docker +build: check-podman mkdir -p ${BINDIR} $(MAKE) build-binary # For cases where we're building from local # We also alter the RC file to set the image name. -docker-build: check-docker - docker build ${DOCKER_BUILD_FLAGS} -t ${IMAGE} --build-arg LDFLAGS=${LDFLAGS} . - docker tag ${IMAGE} ${MUTABLE_IMAGE} - -docker-buildx: check-docker - docker buildx build --platform ${PLATFORM} -t ${IMAGE} --build-arg LDFLAGS=${LDFLAGS} . --push +podman-build: check-podman + podman build --build-arg CODENAME=${CODENAME} -t ${IMAGE} --build-arg LDFLAGS=${LDFLAGS} . + podman tag ${IMAGE} ${MUTABLE_IMAGE} build-binary: ${DEV_ENV_CMD} go build -ldflags ${LDFLAGS} -o $(BINDIR)/${SHORT_NAME} main.go $(call check-static-binary,$(BINDIR)/${SHORT_NAME}) ${DEV_ENV_CMD} upx -9 --brute $(BINDIR)/${SHORT_NAME} -test: check-docker test-style +test: check-podman podman-build test-style contrib/ci/test.sh ${IMAGE} test-style: ${DEV_ENV_CMD} shellcheck $(SHELL_SCRIPTS) -deploy: check-kubectl docker-build docker-push +deploy: check-kubectl podman-build podman-push kubectl --namespace=drycc patch deployment drycc-$(SHORT_NAME) --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"$(IMAGE)"}]' -.PHONY: all build build-binary docker-build test test-style deploy +.PHONY: all build build-binary podman-build test test-style deploy diff --git a/README.md b/README.md index d3c5a7a..ae7eea3 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Drycc Registry v2 -[![Build Status](https://drone.drycc.cc/api/badges/drycc/registry/status.svg)](https://drone.drycc.cc/drycc/registry) +[![Build Status](https://woodpecker.drycc.cc/api/badges/drycc/registry/status.svg)](https://woodpecker.drycc.cc/drycc/registry) [![Go Report Card](https://goreportcard.com/badge/github.com/drycc/registry)](https://goreportcard.com/report/github.com/drycc/registry) @@ -12,11 +12,19 @@ We welcome your input! If you have feedback, please submit an [issue][issues]. I # About -The registry is a [Docker registry](https://docs.docker.com/registry/) component for use in Kubernetes. While it's intended for use inside of the Drycc open source [PaaS](https://en.wikipedia.org/wiki/Platform_as_a_service), it's flexible enough to be used as a standalone pod on any Kubernetes cluster. +Registry consists of two components, namely the proxy component and the registry component. -If you decide to use this component standalone, you can host your own Docker registry in your own Kubernetes cluster. +## Proxy -The Docker image that this repository builds is based on [the official Docker v2 registry image](https://github.com/docker/distribution). +The proxy component is a proxy deployed on every Kubernetes worker node, proxying all requests to the Drycc Workflow [registry][registry]. This allows the worker nodes daemons to communicate to the registry over localhost, bypassing the need for adding the `--insecure-registry` flag to the daemons. + +## Registry + +The registry component is a [Container registry](https://github.com/distribution/distribution) component for use in Kubernetes. While it's intended for use inside of the Drycc open source [PaaS](https://en.wikipedia.org/wiki/Platform_as_a_service), it's flexible enough to be used as a standalone pod on any Kubernetes cluster. + +If you decide to use this component standalone, you can host your own Container registry in your own Kubernetes cluster. + +The Container image that this repository builds is based on [the official Container v2 registry image](https://github.com/distribution/distribution). # Development @@ -49,7 +57,7 @@ $ export IMAGE_PREFIX=youruser/ # if using Quay or Dockerhub To build and push the image run: ```console -$ make docker-build docker-push +$ make podman-build podman-push ``` To deploy the image via patching the registry deployment run: diff --git a/charts/registry/Chart.yaml b/charts/registry/Chart.yaml index 733f9f4..cd8abff 100644 --- a/charts/registry/Chart.yaml +++ b/charts/registry/Chart.yaml @@ -1,11 +1,12 @@ name: registry home: https://github.com/drycc/registry apiVersion: v2 +appVersion: 1.0.0 dependencies: - name: common repository: oci://registry.drycc.cc/charts - version: ~1.1.1 -description: Docker registry for Drycc Workflow. + version: ~1.1.2 +description: Container registry for Drycc Workflow. maintainers: - name: Drycc Team email: engineering@drycc.com diff --git a/charts/registry/templates/_helper.tpl b/charts/registry/templates/_helper.tpl index df13657..cd87b72 100644 --- a/charts/registry/templates/_helper.tpl +++ b/charts/registry/templates/_helper.tpl @@ -24,26 +24,37 @@ env: secretKeyRef: name: registry-secret key: password -- name: "DRYCC_STORAGE_LOOKUP" +{{- if (.Values.storageEndpoint) }} +- name: "DRYCC_STORAGE_BUCKET" valueFrom: secretKeyRef: - name: storage-creds - key: lookup -- name: "DRYCC_STORAGE_HEALTH" + name: registry-secret + key: storage-bucket +- name: "DRYCC_STORAGE_ENDPOINT" valueFrom: secretKeyRef: - name: storage-creds - key: health -- name: "DRYCC_STORAGE_BUCKET" + name: registry-secret + key: storage-endpoint +- name: "DRYCC_STORAGE_ACCESSKEY" valueFrom: secretKeyRef: - name: storage-creds - key: registry-bucket -- name: "DRYCC_STORAGE_ENDPOINT" + name: registry-secret + key: storage-accesskey +- name: "DRYCC_STORAGE_SECRETKEY" valueFrom: secretKeyRef: - name: storage-creds - key: endpoint + name: registry-secret + key: storage-secretkey +- name: "DRYCC_STORAGE_PATH_STYLE" + valueFrom: + secretKeyRef: + name: registry-secret + key: storage-path-style +{{- else if .Values.storage.enabled }} +- name: "DRYCC_STORAGE_BUCKET" + value: "registry" +- name: "DRYCC_STORAGE_ENDPOINT" + value: http://drycc-storage:9000 - name: "DRYCC_STORAGE_ACCESSKEY" valueFrom: secretKeyRef: @@ -54,24 +65,7 @@ env: secretKeyRef: name: storage-creds key: secretkey +- name: "DRYCC_STORAGE_PATH_STYLE" + value: "true" {{- end }} - -{{/* Generate registry deployment limits */}} -{{- define "registry.limits" -}} -{{- if or (.Values.limitsCpu) (.Values.limitsMemory)}} -resources: - limits: - {{- if (.Values.limitsCpu) }} - cpu: {{.Values.limitsCpu}} - {{- end }} - {{- if (.Values.limitsMemory) }} - memory: {{.Values.limitsMemory}} - {{- end }} - {{- if (.Values.limitsHugepages2Mi) }} - hugepages-2Mi: {{.Values.limitsHugepages2Mi}} - {{- end }} - {{- if (.Values.limitsHugepages1Gi) }} - hugepages-1Gi: {{.Values.limitsHugepages1Gi}} - {{- end }} {{- end }} -{{- end }} \ No newline at end of file diff --git a/charts/registry/templates/registry-cronjob-daily.yaml b/charts/registry/templates/registry-cronjob-daily.yaml index 30f9d3f..442841b 100644 --- a/charts/registry/templates/registry-cronjob-daily.yaml +++ b/charts/registry/templates/registry-cronjob-daily.yaml @@ -1,4 +1,3 @@ -{{- if eq .Values.global.registryLocation "on-cluster" }} apiVersion: batch/v1 kind: CronJob metadata: @@ -23,22 +22,25 @@ spec: image: {{.Values.imageRegistry}}/{{.Values.imageOrg}}/python-dev:latest imagePullPolicy: {{.Values.imagePullPolicy}} args: - - netcat - - -v - - -u - - $(DRYCC_STORAGE_ENDPOINT) - {{- include "builder.envs" . | indent 12 }} + - netcat + - -v + - -u + - $(DRYCC_STORAGE_ENDPOINT) + {{- include "registry.envs" . | indent 12 }} containers: - image: {{.Values.imageRegistry}}/{{.Values.imageOrg}}/registry:{{.Values.imageTag}} imagePullPolicy: {{.Values.imagePullPolicy}} name: drycc-registry-garbage-collect + {{- if .Values.diagnosticMode.enabled }} + command: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.command "context" $) | nindent 14 }} + args: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.args "context" $) | nindent 14 }} + {{- else }} args: - - /bin/bash - - -c - - /opt/registry/bin/registry - - garbage-collect - - $(DRYCC_REGISTRY_CONFIG) - - --dry-run - - --delete-untagged - {{- include "builder.envs" . | indent 12 }} -{{- end }} + - /usr/bin/env + - bash + - -ec + - | + # run garbage collect + start-registry garbage-collect ${DRYCC_REGISTRY_CONFIG} --dry-run --delete-untagged + {{- end }} + {{- include "registry.envs" . | indent 12 }} diff --git a/charts/registry/templates/registry-deployment.yaml b/charts/registry/templates/registry-deployment.yaml index e1bdcae..dc362e3 100644 --- a/charts/registry/templates/registry-deployment.yaml +++ b/charts/registry/templates/registry-deployment.yaml @@ -1,4 +1,3 @@ -{{- if eq .Values.global.registryLocation "on-cluster" }} apiVersion: apps/v1 kind: Deployment metadata: @@ -19,12 +18,12 @@ spec: app: drycc-registry template: metadata: - labels: + labels: {{- include "common.labels.standard" . | nindent 8 }} app: drycc-registry spec: affinity: - podAffinity: {{- include "common.affinities.pods" (dict "type" .Values.podAffinityPreset.type "key" .Values.podAffinityPreset.key "values" .Values.podAffinityPreset.values ) | nindent 10 }} - podAntiAffinity: {{- include "common.affinities.pods" (dict "type" .Values.podAntiAffinityPreset.type "key" .Values.podAntiAffinityPreset.key "values" .Values.podAntiAffinityPreset.values ) | nindent 10 }} + podAffinity: {{- include "common.affinities.pods" (dict "type" .Values.podAffinityPreset.type "component" "" "extraMatchLabels" .Values.podAffinityPreset.extraMatchLabels "topologyKey" "" "context" $) | nindent 10 }} + podAntiAffinity: {{- include "common.affinities.pods" (dict "type" .Values.podAntiAffinityPreset.type "component" "" "extraMatchLabels" .Values.podAntiAffinityPreset.extraMatchLabels "topologyKey" "" "context" $) | nindent 10 }} nodeAffinity: {{- include "common.affinities.nodes" (dict "type" .Values.nodeAffinityPreset.type "key" .Values.nodeAffinityPreset.key "values" .Values.nodeAffinityPreset.values ) | nindent 10 }} serviceAccount: drycc-registry initContainers: @@ -32,17 +31,28 @@ spec: image: {{.Values.imageRegistry}}/{{.Values.imageOrg}}/python-dev:latest imagePullPolicy: {{.Values.imagePullPolicy}} args: - - netcat - - -v - - -g - - $(DRYCC_STORAGE_HEALTH) + - netcat + - -v + - -u + - $(DRYCC_STORAGE_ENDPOINT) {{- include "registry.envs" . | indent 8 }} containers: - name: drycc-registry image: {{.Values.imageRegistry}}/{{.Values.imageOrg}}/registry:{{.Values.imageTag}} imagePullPolicy: {{.Values.imagePullPolicy}} - {{- include "registry.limits" . | indent 8 }} + {{- if .Values.diagnosticMode.enabled }} + command: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.command "context" $) | nindent 10 }} + args: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.args "context" $) | nindent 10 }} + {{- else }} + args: + - start-registry + {{- end }} + {{- with index .Values "resources" }} + resources: + {{- toYaml . | nindent 10 }} + {{- end }} {{- include "registry.envs" . | indent 8 }} + {{- if not .Values.diagnosticMode.enabled }} startupProbe: tcpSocket: port: 5000 @@ -69,16 +79,17 @@ spec: timeoutSeconds: 1 successThreshold: 1 failureThreshold: 5 + {{- end }} ports: - - containerPort: 5000 + - containerPort: 5000 + name: http volumeMounts: - - name: registry-storage - mountPath: /var/lib/registry + - name: registry-storage + mountPath: /var/lib/registry securityContext: fsGroup: 1001 runAsGroup: 1001 runAsUser: 1001 volumes: - - name: registry-storage - emptyDir: {} -{{- end }} + - name: registry-storage + emptyDir: {} diff --git a/charts/registry/templates/registry-proxy-daemonset.yaml b/charts/registry/templates/registry-proxy-daemonset.yaml new file mode 100644 index 0000000..c83a364 --- /dev/null +++ b/charts/registry/templates/registry-proxy-daemonset.yaml @@ -0,0 +1,98 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: drycc-registry-proxy + labels: + heritage: drycc + annotations: + component.drycc.cc/version: {{ .Values.imageTag }} +spec: + updateStrategy: + type: RollingUpdate + selector: + matchLabels: + app: drycc-registry-proxy + heritage: drycc + template: + metadata: + name: drycc-registry-proxy + labels: + heritage: drycc + app: drycc-registry-proxy + spec: + securityContext: + fsGroup: 1001 + runAsGroup: 1001 + runAsUser: 1001 + initContainers: + - name: drycc-registry-init + image: {{.Values.imageRegistry}}/{{.Values.imageOrg}}/python-dev:latest + imagePullPolicy: {{.Values.imagePullPolicy}} + args: + - netcat + - -v + - -a + - $(DRYCC_REGISTRY_HOST) + env: + - name: "DRYCC_REGISTRY_HOST" + value: drycc-registry:5000 + containers: + - name: drycc-registry-proxy + image: {{.Values.imageRegistry}}/{{.Values.imageOrg}}/registry:{{.Values.imageTag}} + imagePullPolicy: {{.Values.imagePullPolicy}} + {{- if .Values.diagnosticMode.enabled }} + command: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.command "context" $) | nindent 10 }} + args: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.args "context" $) | nindent 10 }} + {{- else }} + args: + - start-proxy + {{- end }} + {{- with index .Values "proxy" "resources" }} + resources: + {{- toYaml . | nindent 10 }} + {{- end }} + {{- if not .Values.diagnosticMode.enabled }} + startupProbe: + httpGet: + path: / + port: 8080 + initialDelaySeconds: 30 + periodSeconds: 5 + timeoutSeconds: 1 + successThreshold: 1 + failureThreshold: 5 + livenessProbe: + httpGet: + path: / + port: 8080 + initialDelaySeconds: 30 + periodSeconds: 5 + timeoutSeconds: 1 + successThreshold: 1 + failureThreshold: 5 + readinessProbe: + httpGet: + path: / + port: 8080 + initialDelaySeconds: 30 + periodSeconds: 5 + timeoutSeconds: 1 + successThreshold: 1 + failureThreshold: 5 + {{- end }} + env: + - name: "DRYCC_REGISTRY_HOST" + value: drycc-registry:5000 + - name: "DRYCC_REGISTRY_USERNAME" + valueFrom: + secretKeyRef: + name: registry-secret + key: username + - name: "DRYCC_REGISTRY_PASSWORD" + valueFrom: + secretKeyRef: + name: registry-secret + key: password + ports: + - containerPort: 8080 + hostPort: {{.Values.proxy.port}} diff --git a/charts/registry/templates/registry-secret.yaml b/charts/registry/templates/registry-secret.yaml index ce46a36..9fa12be 100644 --- a/charts/registry/templates/registry-secret.yaml +++ b/charts/registry/templates/registry-secret.yaml @@ -4,17 +4,16 @@ metadata: name: registry-secret labels: heritage: drycc - annotations: - drycc.cc/registry-location: "{{ .Values.global.registryLocation }}" type: Opaque data: - {{- if eq .Values.global.registryLocation "on-cluster" }} - host: {{ printf "drycc-registry.%s.svc.%s:80" .Release.Namespace .Values.global.clusterDomain | b64enc }} - secret: {{ randAlphaNum 32 | b64enc }} - {{- else }} - host: {{ .Values.host | b64enc }} - organization: {{ .Values.organization | b64enc }} - {{- end }} - username: {{ if .Values.username | default "" | ne "" }}{{ .Values.username | b64enc }}{{ else }}{{ randAlphaNum 32 | b64enc }}{{ end }} - password: {{ if .Values.password | default "" | ne "" }}{{ .Values.password | b64enc }}{{ else }}{{ randAlphaNum 32 | b64enc }}{{ end }} + secret: {{ include "common.secrets.lookup" (dict "secret" "registry-secret" "key" "secret" "defaultValue" (randAlphaNum 32) "context" $) }} + username: {{ include "common.secrets.lookup" (dict "secret" "registry-secret" "key" "username" "defaultValue" (.Values.username | default (randAlphaNum 32)) "context" $) }} + password: {{ include "common.secrets.lookup" (dict "secret" "registry-secret" "key" "password" "defaultValue" (.Values.password | default (randAlphaNum 32)) "context" $) }} redirect: {{ .Values.redirect | b64enc }} + {{- if (.Values.storageEndpoint) }} + storage-bucket: {{ .Values.storageBucket | b64enc }} + storage-endpoint: {{ .Values.storageEndpoint | b64enc }} + storage-accesskey: {{ .Values.storageAccesskey | b64enc }} + storage-secretkey: {{ .Values.storageSecretkey | b64enc }} + storage-path-style: {{ .Values.storagePathStyle | b64enc }} + {{- end }} diff --git a/charts/registry/templates/registry-service-account.yaml b/charts/registry/templates/registry-service-account.yaml index 3766311..a3b2b78 100644 --- a/charts/registry/templates/registry-service-account.yaml +++ b/charts/registry/templates/registry-service-account.yaml @@ -1,8 +1,6 @@ -{{- if eq .Values.global.registryLocation "on-cluster" }} apiVersion: v1 kind: ServiceAccount metadata: name: drycc-registry labels: heritage: drycc -{{- end }} diff --git a/charts/registry/templates/registry-service.yaml b/charts/registry/templates/registry-service.yaml index 1b792c1..fbafcf2 100644 --- a/charts/registry/templates/registry-service.yaml +++ b/charts/registry/templates/registry-service.yaml @@ -1,20 +1,17 @@ -{{- if eq .Values.global.registryLocation "on-cluster" }} apiVersion: v1 kind: Service metadata: name: drycc-registry annotations: + prometheus.io/path: /metrics + prometheus.io/port: "9000" + prometheus.io/scrape: "true" {{- with .Values.service.annotations }} {{- toYaml . | nindent 4 }} {{- end }} labels: heritage: drycc spec: - ports: - - name: http - port: 80 - targetPort: 5000 + clusterIP: None selector: app: drycc-registry - sessionAffinity: ClientIP -{{- end }} diff --git a/charts/registry/values.yaml b/charts/registry/values.yaml index 5997f66..87a2895 100644 --- a/charts/registry/values.yaml +++ b/charts/registry/values.yaml @@ -2,8 +2,22 @@ imageOrg: "drycc" imagePullPolicy: "Always" imageTag: "canary" imageRegistry: "registry.drycc.cc" -# limitsCpu: "100m" -# limitsMemory: "50Mi" + +## Enable diagnostic mode +## +diagnosticMode: + ## @param diagnosticMode.enabled Enable diagnostic mode (all probes will be disabled and the command will be overridden) + ## + enabled: false + ## @param diagnosticMode.command Command to override all containers + ## + command: + - sleep + ## @param diagnosticMode.args Args to override all containers + ## + args: + - infinity + nodeAffinityPreset: key: "drycc.cc/node" type: "soft" @@ -11,23 +25,60 @@ nodeAffinityPreset: - "true" podAffinityPreset: - key: "security" type: "" - values: - - "drycc-security" + extraMatchLabels: + security: "drycc-security" podAntiAffinityPreset: - key: "app" type: "soft" - values: - - "drycc-registry" + extraMatchLabels: + app: "drycc-registry" # registry replicas replicas: 1 +# registry storage redirect +redirect: "false" + +proxy: + # host port for the registry proxy in the daemonset + port: 5555 + resources: {} + # limits: + # cpu: 200m + # memory: 50Mi + # requests: + # cpu: 100m + # memory: 30Mi + +resources: {} + # limits: + # cpu: 200m + # memory: 50Mi + # requests: + # cpu: 100m + # memory: 30Mi concurrencyPolicy: "Replace" +# The following parameters will no longer use the built-in storage component. +storageBucket: "builder" +storageEndpoint: "" +storageAccesskey: "" +storageSecretkey: "" +storagePathStyle: "auto" + +storage: + enabled: true + # Service service: # Provide any additional service annotations - annotations: {} \ No newline at end of file + annotations: {} + +resources: {} + # limits: + # cpu: 200m + # memory: 50Mi + # requests: + # cpu: 100m + # memory: 30Mi diff --git a/contrib/ci/test.sh b/contrib/ci/test.sh index dc59be0..6be70b3 100755 --- a/contrib/ci/test.sh +++ b/contrib/ci/test.sh @@ -2,36 +2,73 @@ set -eoxf pipefail -s3Accesskey=drycc -s3Secretkey=123456789 +DRYCC_STORAGE_ACCESSKEY=f4c4281665bc11ee8e0400163e04a9cd +DRYCC_STORAGE_SECRETKEY=f4c4281665bc11ee8e0400163e04a9cd -STORAGE_JOB=$(docker run -d --name storage \ - -e DRYCC_STORAGE_ACCESSKEY=$s3Accesskey \ - -e DRYCC_STORAGE_SECRETKEY=$s3Secretkey \ - "${DEV_REGISTRY}"/drycc/storage:canary minio server /data/storage/ --console-address :9001) -sleep 5 -docker logs "${STORAGE_JOB}" +STORAGE_JOB=$(podman run -d --rm --entrypoint init-stack \ + -e RUSTFS_ACCESS_KEY="${DRYCC_STORAGE_ACCESSKEY}" \ + -e RUSTFS_SECRET_KEY="${DRYCC_STORAGE_SECRETKEY}" \ + "${DEV_REGISTRY}"/drycc/storage:canary rustfs /data) -STORAGE_IP=$(docker inspect --format "{{ .NetworkSettings.IPAddress }}" "${STORAGE_JOB}") +# wait for port +STORAGE_IP=$(podman inspect --format "{{ .NetworkSettings.IPAddress }}" "${STORAGE_JOB}") +echo -e "\\033[32m---> Waitting for ${STORAGE_IP}:9000\\033[0m" +wait-for-port --host="${STORAGE_IP}" 9000 +echo -e "\\033[32m---> S3 service ${STORAGE_IP}:9000 ready...\\033[0m" +podman logs "${STORAGE_JOB}" -JOB=$(docker run --add-host storage:"${STORAGE_IP}" \ - -d \ - -p 5000:5000 \ - -e REGISTRY_HTTP_SECRET=drycc \ +REGISTRY_JOB=$(podman run -d --rm \ -e DRYCC_REGISTRY_REDIRECT=false \ -e DRYCC_REGISTRY_USERNAME=admin \ -e DRYCC_REGISTRY_PASSWORD=admin \ - -e DRYCC_STORAGE_LOOKUP=path \ -e DRYCC_STORAGE_BUCKET=registry \ - -e DRYCC_STORAGE_ENDPOINT=http://storage:9000 \ - -e DRYCC_STORAGE_ACCESSKEY=$s3Accesskey \ - -e DRYCC_STORAGE_SECRETKEY=$s3Secretkey \ - "$1") + -e DRYCC_STORAGE_ENDPOINT="http://${STORAGE_IP}:9000" \ + -e DRYCC_STORAGE_ACCESSKEY="${DRYCC_STORAGE_ACCESSKEY}" \ + -e DRYCC_STORAGE_SECRETKEY="${DRYCC_STORAGE_SECRETKEY}" \ + -e DRYCC_STORAGE_PATH_STYLE=true \ + "$1" start-registry) + +# shellcheck disable=SC2317 +function clean_before_exit { + # delay before exiting, so stdout/stderr flushes through the logging system + podman kill "${REGISTRY_JOB}" + podman kill "${STORAGE_JOB}" + podman kill "${PROXY_JOB}" +} +trap clean_before_exit EXIT # let the registry run for a few seconds -sleep 5 +REGISTRY_IP=$(podman inspect --format "{{ .NetworkSettings.IPAddress }}" "${REGISTRY_JOB}") +echo -e "\\033[32m---> Waitting for ${REGISTRY_IP}:5000\\033[0m" +wait-for-port --host="${REGISTRY_IP}" 5000 +echo -e "\\033[32m---> S3 service ${REGISTRY_IP}:5000 ready...\\033[0m" + +# proxy job +PROXY_JOB=$(podman run -d \ + -p 15555:8080 \ + -e DRYCC_REGISTRY_HOST="${REGISTRY_IP}:5000" \ + -e DRYCC_REGISTRY_USERNAME=admin \ + -e DRYCC_REGISTRY_PASSWORD=admin \ + "$1" start-proxy) + +# let the registry proxy run for a few seconds +REGISTRY_PROXY_IP=$(podman inspect --format "{{ .NetworkSettings.IPAddress }}" "${PROXY_JOB}") +echo -e "\\033[32m---> Waitting for ${REGISTRY_PROXY_IP}:8080\\033[0m" +wait-for-port --host="${REGISTRY_PROXY_IP}" 8080 +echo -e "\\033[32m---> S3 service ${REGISTRY_PROXY_IP}:8080 ready...\\033[0m" + # check that the registry is still up -docker logs "${JOB}" -docker ps -q --no-trunc=true | grep "${JOB}" -docker rm -f "${JOB}" "${STORAGE_JOB}" +http_status_code=$(curl -X GET -s -o /dev/null -w "%{http_code}" "http://${REGISTRY_PROXY_IP}:8080/v2/") +if [ "$http_status_code" != "200" ]; then + echo "Expected http status code: 200, actual: ${http_status_code}" + exit 1 +fi + +http_status_code=$(curl -X POST -s -o /dev/null -w "%{http_code}" "http://${REGISTRY_PROXY_IP}:8080/v2/") +if [ "$http_status_code" != "403" ]; then + echo "Expected http status code: 403, actual: ${http_status_code}" + exit 1 +fi + +echo -e "\\033[32m---> All test success...\\033[0m" \ No newline at end of file diff --git a/includes.mk b/includes.mk index 5bc8456..4634e38 100644 --- a/includes.mk +++ b/includes.mk @@ -1,6 +1,6 @@ -check-docker: - @if [ -z $$(which docker) ]; then \ - echo "Missing \`docker\` client which is required for development"; \ +check-podman: + @if [ -z $$(which podman) ]; then \ + echo "Missing \`podman\` client which is required for development"; \ exit 2; \ fi diff --git a/main.go b/main.go index 4488ee9..27b534c 100644 --- a/main.go +++ b/main.go @@ -14,11 +14,11 @@ const ( registryHtpasswd = "/opt/drycc/registry/etc/htpasswd" registryConfigEnvVar = "DRYCC_REGISTRY_CONFIG" registryRedirectEnvVar = "DRYCC_REGISTRY_REDIRECT" - storageLookupEnvVar = "DRYCC_STORAGE_LOOKUP" storageBucketEnvVar = "DRYCC_STORAGE_BUCKET" storageEndpointEnvVar = "DRYCC_STORAGE_ENDPOINT" storageAccesskeyEnvVar = "DRYCC_STORAGE_ACCESSKEY" storageSecretkeyEnvVar = "DRYCC_STORAGE_SECRETKEY" + storagePathStyleEnvVar = "DRYCC_STORAGE_PATH_STYLE" defaultCommand = "serve" ) @@ -39,9 +39,8 @@ func main() { os.Setenv("REGISTRY_STORAGE_S3_ACCESSKEY", os.Getenv(storageAccesskeyEnvVar)) os.Setenv("REGISTRY_STORAGE_S3_SECRETKEY", os.Getenv(storageSecretkeyEnvVar)) os.Setenv("REGISTRY_STORAGE_S3_BUCKET", os.Getenv(storageBucketEnvVar)) - os.Setenv("REGISTRY_STORAGE_S3_ROOTDIRECTORY", "/registry") - if os.Getenv(storageLookupEnvVar) == "path" { + if os.Getenv(storagePathStyleEnvVar) == "true" { os.Setenv("REGISTRY_STORAGE_S3_FORCEPATHSTYLE", "true") } @@ -50,17 +49,26 @@ func main() { } else { os.Setenv("REGISTRY_STORAGE_REDIRECT_DISABLE", "true") } + // set default env + os.Setenv("REGISTRY_STORAGE_S3_V4AUTH", "true") + os.Setenv("REGISTRY_STORAGE_S3_SECURE", "false") + os.Setenv("REGISTRY_STORAGE_S3_SKIPVERIFY", "true") + os.Setenv("REGISTRY_STORAGE_DELETE_ENABLED", "true") + os.Setenv("REGISTRY_VALIDATION_DISABLED", "true") + os.Setenv("REGISTRY_STORAGE_S3_ROOTDIRECTORY", "/registry") - // run /bin/init_registry + // run /bin/init-registry os.Setenv("REGISTRY_AUTH", "htpasswd") os.Setenv("REGISTRY_AUTH_HTPASSWD_REALM", "basic-realm") os.Setenv("REGISTRY_AUTH_HTPASSWD_PATH", registryHtpasswd) - cmd := exec.Command("/bin/init_registry") + cmd := exec.Command("/bin/init-registry") cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr if err := cmd.Run(); err != nil { log.Fatal("Error creating the registry bucket: ", err) } + // avoid conflicts with env variables + os.Unsetenv("REGISTRY_VERSION") if len(os.Args) > 1 { cmd = exec.Command(registryBinary, os.Args[1:]...) } else { diff --git a/rootfs/bin/init-registry b/rootfs/bin/init-registry new file mode 100755 index 0000000..4d05fc8 --- /dev/null +++ b/rootfs/bin/init-registry @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +set -e + + +mkdir -p ~/.config/rclone +touch ~/.config/rclone/rclone.conf +rclone config create storage s3 \ + provider=Other \ + access_key_id="${DRYCC_STORAGE_ACCESSKEY}" \ + secret_access_key="${DRYCC_STORAGE_SECRETKEY}" \ + endpoint="${DRYCC_STORAGE_ENDPOINT}" \ + force_path_style="${DRYCC_STORAGE_PATH_STYLE:-true}" --no-output + +if ! rclone lsd storage: > /dev/null 2>&1; then + sleep 9s + echo "waiting for object storage to become ready..." +fi + +rclone mkdir "storage:${DRYCC_STORAGE_BUCKET}" + +htpasswd -Bbn "${DRYCC_REGISTRY_USERNAME}" "${DRYCC_REGISTRY_PASSWORD}" > "${REGISTRY_AUTH_HTPASSWD_PATH}" +echo "create ${REGISTRY_AUTH_HTPASSWD_PATH} success" diff --git a/rootfs/bin/init_registry b/rootfs/bin/init_registry deleted file mode 100755 index a3a6041..0000000 --- a/rootfs/bin/init_registry +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env bash - -set -e - -mc config host add storage \ - "${DRYCC_STORAGE_ENDPOINT}" \ - "${DRYCC_STORAGE_ACCESSKEY}" \ - "${DRYCC_STORAGE_SECRETKEY}" \ - --lookup "${DRYCC_STORAGE_LOOKUP}" \ - --api s3v4 - -has_bucket(){ - mc ls storage -json|jq -r '.key'|grep -w "${DRYCC_STORAGE_BUCKET}" -} - -if [ -z "$(has_bucket)" ] ;then - mc mb storage/"${DRYCC_STORAGE_BUCKET}" - if [ -z "$(has_bucket)" ] ;then - echo "create bucket ${DRYCC_STORAGE_BUCKET} error" - exit 1 - fi -fi -echo "create bucket ${DRYCC_STORAGE_BUCKET} success" - -htpasswd -Bbn "${DRYCC_REGISTRY_USERNAME}" "${DRYCC_REGISTRY_PASSWORD}" > "${REGISTRY_AUTH_HTPASSWD_PATH}" -echo "create ${REGISTRY_AUTH_HTPASSWD_PATH} success" \ No newline at end of file diff --git a/rootfs/bin/start-proxy b/rootfs/bin/start-proxy new file mode 100755 index 0000000..5354551 --- /dev/null +++ b/rootfs/bin/start-proxy @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +REGISTRY_HOST=${DRYCC_REGISTRY_HOST:?no host} +AUTHORIZATION=$(echo -ne "${DRYCC_REGISTRY_USERNAME:? no username}":"${DRYCC_REGISTRY_PASSWORD:? no password}" | base64 -w 0) + +cat /opt/drycc/nginx/conf/registry.conf.tpl > /opt/drycc/nginx/conf/registry.conf +sed -i "s#%REGISTRY_HOST%#${REGISTRY_HOST}#g" /opt/drycc/nginx/conf/registry.conf +sed -i "s#%AUTHORIZATION%#${AUTHORIZATION}#g" /opt/drycc/nginx/conf/registry.conf + +# wait for registry to come online +while ! curl -sS "$REGISTRY_HOST" &>/dev/null; do + echo "waiting for the registry (%s) to come online..." + echo "$REGISTRY_HOST" + sleep 1 +done + +echo "starting registry-proxy..." +exec nginx -g "daemon off;" diff --git a/rootfs/config-example.yml b/rootfs/config-example.yml index 3277f9a..a55566c 100644 --- a/rootfs/config-example.yml +++ b/rootfs/config-example.yml @@ -9,6 +9,11 @@ storage: rootdirectory: /var/lib/registry http: addr: :5000 + debug: + addr: :9000 + prometheus: + enabled: true + path: /metrics headers: X-Content-Type-Options: [nosniff] health: diff --git a/rootfs/opt/drycc/nginx/conf/nginx.conf b/rootfs/opt/drycc/nginx/conf/nginx.conf new file mode 100644 index 0000000..bd3f31d --- /dev/null +++ b/rootfs/opt/drycc/nginx/conf/nginx.conf @@ -0,0 +1,22 @@ +worker_processes 1; + +error_log /dev/stderr warn; +pid /opt/drycc/nginx/logs/nginx.pid; + +events { + worker_connections 1024; +} + +http { + include /opt/drycc/nginx/conf/mime.types; + default_type application/octet-stream; + + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + access_log /dev/stdout main; + sendfile on; + keepalive_timeout 65; + include /opt/drycc/nginx/conf/registry.conf; +} diff --git a/rootfs/opt/drycc/nginx/conf/registry.conf.tpl b/rootfs/opt/drycc/nginx/conf/registry.conf.tpl new file mode 100644 index 0000000..627f2f2 --- /dev/null +++ b/rootfs/opt/drycc/nginx/conf/registry.conf.tpl @@ -0,0 +1,24 @@ +upstream container-registry { + server %REGISTRY_HOST%; +} + +server { + listen 8080; + server_name localhost; + # disable any limits to avoid HTTP 413 for large image uploads + client_max_body_size 0; + # required to avoid HTTP 411: see Issue #1486 (https://github.com/moby/moby/issues/1486) + chunked_transfer_encoding on; + location / { + proxy_pass http://container-registry; + proxy_set_header Host $http_host; # required for container client's sake + proxy_set_header X-Real-IP $remote_addr; # pass on real client's IP + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_read_timeout 900; + proxy_set_header Authorization "Basic %AUTHORIZATION%"; + limit_except GET HEAD OPTIONS { + deny all; + } + } +} \ No newline at end of file diff --git a/versioning.mk b/versioning.mk index 2bfd999..8b30958 100644 --- a/versioning.mk +++ b/versioning.mk @@ -11,13 +11,13 @@ info: @echo "Immutable tag: ${IMAGE}" @echo "Mutable tag: ${MUTABLE_IMAGE}" -.PHONY: docker-push -docker-push: docker-immutable-push docker-mutable-push +.PHONY: podman-push +podman-push: podman-immutable-push podman-mutable-push -.PHONY: docker-immutable-push -docker-immutable-push: - docker push ${IMAGE} +.PHONY: podman-immutable-push +podman-immutable-push: + podman push ${IMAGE} -.PHONY: docker-mutable-push -docker-mutable-push: - docker push ${MUTABLE_IMAGE} +.PHONY: podman-mutable-push +podman-mutable-push: + podman push ${MUTABLE_IMAGE}