artifact-management
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseArtifact Management
制品管理
Overview
概述
Implement comprehensive artifact management strategies for storing, versioning, and distributing built binaries, Docker images, and packages across environments.
实施全面的制品管理策略,用于在不同环境中存储、版本控制和分发构建好的二进制文件、Docker镜像和包。
When to Use
适用场景
- Docker image registry management
- Package publication and versioning
- Build artifact storage and retrieval
- Container image optimization
- Artifact retention policies
- Multi-registry distribution
- Dependency caching
- Docker镜像仓库管理
- 包发布与版本控制
- 构建产物的存储与检索
- 容器镜像优化
- 制品保留策略
- 多仓库分发
- 依赖缓存
Implementation Examples
实现示例
1. Docker Registry Configuration
1. Docker Registry配置
dockerfile
undefineddockerfile
undefinedDockerfile with multi-stage build for optimization
Dockerfile with multi-stage build for optimization
FROM node:18-alpine AS dependencies
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM node:18-alpine AS runtime
WORKDIR /app
COPY --from=dependencies /app/node_modules ./node_modules
COPY --from=builder /app/dist ./dist
COPY package*.json ./
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=3s --start-period=40s --retries=3
CMD node healthcheck.js
CMD node healthcheck.js
CMD ["node", "dist/server.js"]
LABEL org.opencontainers.image.version="1.0.0"
org.opencontainers.image.description="Production application"
org.opencontainers.image.authors="DevOps Team"
org.opencontainers.image.description="Production application"
org.opencontainers.image.authors="DevOps Team"
undefinedFROM node:18-alpine AS dependencies
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM node:18-alpine AS runtime
WORKDIR /app
COPY --from=dependencies /app/node_modules ./node_modules
COPY --from=builder /app/dist ./dist
COPY package*.json ./
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=3s --start-period=40s --retries=3
CMD node healthcheck.js
CMD node healthcheck.js
CMD ["node", "dist/server.js"]
LABEL org.opencontainers.image.version="1.0.0"
org.opencontainers.image.description="Production application"
org.opencontainers.image.authors="DevOps Team"
org.opencontainers.image.description="Production application"
org.opencontainers.image.authors="DevOps Team"
undefined2. GitHub Container Registry (GHCR) Push
2. GitHub容器注册表(GHCR)推送
yaml
undefinedyaml
undefined.github/workflows/publish-image.yml
.github/workflows/publish-image.yml
name: Publish to GHCR
on:
push:
tags: ['v*']
branches: [main]
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Log in to registry
uses: docker/login-action@v2
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v4
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=sha
- name: Build and push
uses: docker/build-push-action@v4
with:
context: .
file: ./Dockerfile.prod
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache
cache-to: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache,mode=maxundefinedname: Publish to GHCR
on:
push:
tags: ['v*']
branches: [main]
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Log in to registry
uses: docker/login-action@v2
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v4
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=sha
- name: Build and push
uses: docker/build-push-action@v4
with:
context: .
file: ./Dockerfile.prod
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache
cache-to: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache,mode=maxundefined3. npm Package Publishing
3. npm包发布
json
{
"name": "@myorg/awesome-library",
"version": "1.2.3",
"description": "Awesome library for developers",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"files": [
"dist",
"README.md",
"LICENSE"
],
"publishConfig": {
"registry": "https://npm.pkg.github.com",
"access": "public"
},
"repository": {
"type": "git",
"url": "https://github.com/myorg/awesome-library.git"
},
"scripts": {
"prepublishOnly": "npm run build && npm run test",
"prepack": "npm run build"
}
}json
{
"name": "@myorg/awesome-library",
"version": "1.2.3",
"description": "Awesome library for developers",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"files": [
"dist",
"README.md",
"LICENSE"
],
"publishConfig": {
"registry": "https://npm.pkg.github.com",
"access": "public"
},
"repository": {
"type": "git",
"url": "https://github.com/myorg/awesome-library.git"
},
"scripts": {
"prepublishOnly": "npm run build && npm run test",
"prepack": "npm run build"
}
}4. Artifact Retention Policy
4. 制品保留策略
yaml
undefinedyaml
undefined.github/workflows/cleanup-artifacts.yml
.github/workflows/cleanup-artifacts.yml
name: Cleanup Old Artifacts
on:
schedule:
- cron: '0 2 * * *' # Daily at 2 AM
workflow_dispatch:
jobs:
cleanup:
runs-on: ubuntu-latest
steps:
- name: Delete artifacts older than 30 days
uses: geekyeggo/delete-artifact@v2
with:
name: '*'
minCreatedTime: 30d
failOnError: false
undefinedname: Cleanup Old Artifacts
on:
schedule:
- cron: '0 2 * * *' # Daily at 2 AM
workflow_dispatch:
jobs:
cleanup:
runs-on: ubuntu-latest
steps:
- name: Delete artifacts older than 30 days
uses: geekyeggo/delete-artifact@v2
with:
name: '*'
minCreatedTime: 30d
failOnError: false
undefined5. Artifact Versioning
5. 制品版本控制
bash
#!/bin/bashbash
#!/bin/bashartifact-version.sh
artifact-version.sh
BUILD_DATE=$(date -u +'%Y%m%d')
GIT_HASH=$(git rev-parse --short HEAD)
VERSION=$(grep '"version"' package.json | sed 's/."version": "([^"])".*/\1/')
BUILD_DATE=$(date -u +'%Y%m%d')
GIT_HASH=$(git rev-parse --short HEAD)
VERSION=$(grep '"version"' package.json | sed 's/."version": "([^"])".*/\1/')
Full version tag
Full version tag
FULL_VERSION="${VERSION}-${BUILD_DATE}.${GIT_HASH}"
FULL_VERSION="${VERSION}-${BUILD_DATE}.${GIT_HASH}"
Create artifact with version
Create artifact with version
docker build -t myapp:${FULL_VERSION} .
docker tag myapp:${FULL_VERSION} myapp:latest
echo "Built artifact version: ${FULL_VERSION}"
undefineddocker build -t myapp:${FULL_VERSION} .
docker tag myapp:${FULL_VERSION} myapp:latest
echo "Built artifact version: ${FULL_VERSION}"
undefined10. GitLab Package Registry
10. GitLab包注册表
yaml
undefinedyaml
undefined.gitlab-ci.yml
.gitlab-ci.yml
publish-package:
stage: publish
script:
- npm config set @myorg:registry https://gitlab.example.com/api/v4/packages/npm/
- npm config set '//gitlab.example.com/api/v4/packages/npm/:_authToken' "${CI_JOB_TOKEN}"
- npm publish
only:
- tags
undefinedpublish-package:
stage: publish
script:
- npm config set @myorg:registry https://gitlab.example.com/api/v4/packages/npm/
- npm config set '//gitlab.example.com/api/v4/packages/npm/:_authToken' "${CI_JOB_TOKEN}"
- npm publish
only:
- tags
undefinedBest Practices
最佳实践
✅ DO
✅ 建议
- Use semantic versioning for artifacts
- Implement image scanning before deployment
- Set retention policies for old artifacts
- Use multi-stage builds for Docker images
- Sign and verify artifacts
- Implement artifact immutability
- Document artifact metadata
- Use specific base image versions
- Implement vulnerability scanning
- Cache layers aggressively
- Tag images with commit SHA
- Compress artifacts for storage
- 对制品使用语义化版本控制
- 在部署前实施镜像扫描
- 为旧制品设置保留策略
- 对Docker镜像使用多阶段构建
- 签名并验证制品
- 实现制品不可变性
- 记录制品元数据
- 使用特定的基础镜像版本
- 实施漏洞扫描
- 积极缓存镜像层
- 用提交SHA标记镜像
- 压缩制品以节省存储空间
❌ DON'T
❌ 避免
- Use tag as sole identifier
latest - Store secrets in artifacts
- Push artifacts without scanning
- Use untrusted base images
- Skip artifact verification
- Overwrite published artifacts
- Mix binary and source artifacts
- Ignore image layer optimization
- Store build logs with sensitive data
- 仅使用标签作为唯一标识符
latest - 在制品中存储密钥
- 未扫描就推送制品
- 使用不可信的基础镜像
- 跳过制品验证
- 覆盖已发布的制品
- 混合二进制制品和源制品
- 忽略镜像层优化
- 存储包含敏感数据的构建日志
Artifact Storage Standards
制品存储标准
bash
undefinedbash
undefinedNaming convention
Naming convention
{registry}/{org}/{repo}/{service}:{version}-{build}-{commit}
{registry}/{org}/{repo}/{service}:{version}-{build}-{commit}
Examples
Examples
docker.io/myorg/web-app:1.2.3-123-abc1234
ghcr.io/myorg/api-service:2.0.0-456-def5678
artifactory.example.com/releases/core:3.1.0-789-ghi9012
undefineddocker.io/myorg/web-app:1.2.3-123-abc1234
ghcr.io/myorg/api-service:2.0.0-456-def5678
artifactory.example.com/releases/core:3.1.0-789-ghi9012
undefined