すべてのプロダクト
Search
ドキュメントセンター

Container Registry:Jenkins を使用したイメージの CI/CD

最終更新日:Apr 25, 2026

このチュートリアルでは、ソースコードからイメージをビルドし、リポジトリにプッシュしてアプリケーションをデプロイする完全自動化ワークフローの作成方法を説明します。GitLab、Container Registry (ACR)、および Container Service for Kubernetes (ACK) と Jenkins を組み合わせることで、ソースコードがコミットされた際に自動的にイメージをビルドし、アプリケーションをデプロイし、DingTalk グループにイベント通知を送信できます。

前提条件

  • Git、GitLab、および Jenkins がインストール済みです。

    説明

    GitLab には JDK 8 が必要です。一部のプラグインは JDK 11 では実行されません。

  • ACR Enterprise Edition インスタンスを作成済みで、インターネットアクセスが有効になっています。詳細については、「Enterprise Edition インスタンスの作成」および「インターネットアクセスの設定」をご参照ください。

  • ご利用の ACR インスタンスと同じリージョンに ACK クラスターを作成済みです。詳細については、「ACK マネージドクラスターの作成」をご参照ください。

  • DingTalk チャットボットを作成済みで、その Webhook URL およびシークレットトークンを記録済みです。詳細については、「ステップ 1:DingTalk チャットボットの作成」をご参照ください。

  • Container Registry (ACR) のデリバリーチェーン機能を使用するには、インスタンスをアドバンストエディションにスペックアップする必要があります。詳細については、「課金」をご参照ください。

Jenkins を使用したイメージの CI

GitLab にソースコードをコミットすると、Container Registry (ACR) が自動的にイメージをビルドします。その後、そのイメージに対してセキュリティスキャンを実行できます。スキャンが完了すると、イベント通知が DingTalk グループに送信されます。

  1. GitLab でプロジェクトを作成します。

    1. GitLab にログインします。

    2. 上部ナビゲーションバーで、Projects > Your projects を選択します。

    3. Projects ページの右上隅で New Project をクリックし、Create blank project をクリックします。

    4. Create blank project ページで、Project nameProject URL、および Project slug を設定します。Visibility LevelPrivate に設定し、Create project をクリックします。

      创建Project

    5. ローカルコンピューター上で、次の内容を使用して Dockerfilepom.xmlDemoApplication.java、および HelloController.java ファイルを作成します。

      • Dockerfile

        FROM registry.cn-hangzhou.aliyuncs.com/public-toolbox/maven:3.8.3-openjdk-8-aliyun AS build
        COPY src /home/app/src
        COPY pom.xml /home/app
        RUN ["/usr/local/bin/mvn-entrypoint.sh","mvn","-f","/home/app/pom.xml","clean","package","-Dmaven.test.skip=true"]
        
        FROM registry.cn-hangzhou.aliyuncs.com/public-toolbox/openjdk:8-jdk-alpine
        COPY --from=build /home/app/target/demo-0.0.1-SNAPSHOT.jar /usr/local/lib/demo-0.0.1-SNAPSHOT.jar
        EXPOSE 8080
        ENTRYPOINT ["java","-jar","/usr/local/lib/demo-0.0.1-SNAPSHOT.jar"]
      • pom.xml

        <?xml version="1.0" encoding="UTF-8"?>
        <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
            <modelVersion>4.0.0</modelVersion>
            <parent>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-parent</artifactId>
                <version>2.6.1</version>
                <relativePath/> <!-- lookup parent from repository -->
            </parent>
            <groupId>com.example</groupId>
            <artifactId>demo</artifactId>
            <version>0.0.1-SNAPSHOT</version>
            <name>demo</name>
            <description>Demo project for Spring Boot</description>
            <properties>
                <java.version>1.8</java.version>
            </properties>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-freemarker</artifactId>
                </dependency>
                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-web</artifactId>
                </dependency>
        
                <dependency>
                    <groupId>org.projectlombok</groupId>
                    <artifactId>lombok</artifactId>
                    <optional>true</optional>
                </dependency>
                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-test</artifactId>
                    <scope>test</scope>
                </dependency>
                <dependency>
                    <groupId>org.apache.logging.log4j</groupId>
                    <artifactId>log4j-core</artifactId>
                    <version>2.13.2</version>
                </dependency>
            </dependencies>
        
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-maven-plugin</artifactId>
                        <configuration>
                            <excludes>
                                <exclude>
                                    <groupId>org.projectlombok</groupId>
                                    <artifactId>lombok</artifactId>
                                </exclude>
                            </excludes>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
        
        </project>
      • DemoApplication.java

        package com.example.demo;
        
        import org.springframework.boot.SpringApplication;
        import org.springframework.boot.autoconfigure.SpringBootApplication;
        
        import java.util.TimeZone;
        
        @SpringBootApplication
        public class DemoApplication {
        
            public static void main(String[] args) {
                TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"));
                SpringApplication.run(DemoApplication.class, args);
            }
        
        }
      • HelloController.java

        package com.example.demo;
        
        import lombok.extern.slf4j.Slf4j;
        import org.springframework.web.bind.annotation.RequestMapping;
        import org.springframework.web.bind.annotation.RestController;
        
        import javax.servlet.http.HttpServletRequest;
        import java.text.SimpleDateFormat;
        import java.util.Date;
        
        @RestController
        @Slf4j
        public class HelloController {
        
            @RequestMapping({"/hello", "/"})
            public String hello(HttpServletRequest request) {
                return "Hello World at " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
            }
        }
    6. 次のコマンドを実行して、ビルドファイルを GitLab にアップロードします。

      cd java-web  # ビルドファイルが配置されているディレクトリに移動します。
      git remote set-url origin http://8.218.20*.***/shoppingmall/java-web.git
      git push origin master
      * [new branch]      master -> master
  2. Jenkins でイメージをビルドするためのパイプラインを構成します。

    1. Jenkins で GitLab SSH キーを構成します。

      1. Jenkins にログインします。

      2. 左側のナビゲーションウィンドウで、Manage Jenkins をクリックします。

      3. Security セクションで、Manage Credentials をクリックします。

      4. Stores scoped to Jenkins セクションで、Store 列の Jenkins をクリックし、Global credentials をクリックします。

      5. 左側のナビゲーションウィンドウで、Add Credentials をクリックします。

      6. KindSSH Username with private key に設定します。Description および Username を入力します。秘密鍵については、Enter directly を選択し、OK をクリックします。

        Global credentials ページで、認証情報の ID が自動生成されます。この ID は後ほど使用するため、保存しておいてください。

    2. パイプラインを作成します。

      1. Jenkins ダッシュボードの左側ナビゲーションウィンドウで、New Item をクリックします。

      2. アイテム名を入力し、Pipeline を選択して、OK をクリックします。

      3. Build Triggers タブをクリックします。Build when a change is pushed to GitLab を選択し、Push Events を選択します。

        Build when a change is pushed to GitLab の右側にある Webhook URL をコピーします。

      4. Advanced をクリックし、Secret token の横にある Generate をクリックします。

        Jenkins によってシークレットトークンが生成されます。このトークンは後ほど使用するため、保存しておいてください。

      5. Pipeline タブをクリックします。以下のテンプレートで、プレースホルダーの値を実際の情報に置き換えます。その後、テキストボックスに内容をコピーして、Save をクリックします。

        def git_auth_id = "6d5a2c06-f0a7-43c8-9b79-37b8c266****"  # 認証情報 ID。
        def git_branch_name = "master" # ブランチ名。
        def git_url = "git@172.16.1*.***:shoppingmall/java-web.git"   # GitLab リポジトリ URL。
        def acr_url = "s*****-devsecops-registry.cn-hongkong.cr.aliyuncs.com"  # イメージリポジトリ URL。
        def acr_username = "acr_test_*****@test.aliyunid.com"   # Container Registry ユーザー名。
        def acr_password = "HelloWorld2021"   # Container Registry パスワード。
        def acr_namespace = "ns"    # 名前空間。
        def acr_repo_name = "test"   # イメージリポジトリ名。
        def tag_version = "0.0.1"   # イメージタグ。
        node {
        
            stage('checkout git repo') {
                checkout([$class: 'GitSCM', branches: [[name: "*/${git_branch_name}"]], extensions: [], userRemoteConfigs: [[credentialsId: "${git_auth_id}", url: "${git_url}"]]])
            }
            stage('build image') {
                sh "sudo docker build -t java-web:${tag_version} ."
                sh "sudo docker tag java-web:${tag_version} ${acr_url}/${acr_namespace}/${acr_repo_name}:${tag_version}"
            }
            stage('push image') {
                sh "sudo docker login --username=${acr_username} --password=${acr_password} ${acr_url}"
                sh "sudo docker push ${acr_url}/${acr_namespace}/${acr_repo_name}:${tag_version}"
            }
        }
  3. Webhook URL を GitLab に追加します。

    1. GitLab にログインします。

    2. Projects ページで、作成したプロジェクトをクリックします。

    3. 左側のナビゲーションウィンドウで、Settings > Webhooks を選択します。Webhook URL およびシークレットトークンを入力します。Enable SSL verification チェックボックスをオフにして、Add webhooks をクリックします。

  4. イベント通知ルールを作成します。

    1. Container Registry コンソール にログインします。

    2. 上部ナビゲーションバーで、リージョンを選択します。

    3. 左側のナビゲーションウィンドウで、Instances をクリックします。

    4. Instances ページで、管理対象の Enterprise Edition インスタンスをクリックします。

    5. インスタンス詳細ページの左側ナビゲーションウィンドウで、インスタンス > インシデント通知 を選択します。

    6. イベントルール タブで、ルールの作成 をクリックします。

    7. イベントの範囲 ステップで、ルール名 を設定します。イベントタイプイメージをスキャンしました。 に設定し、スキャンしました。 を選択します。適用範囲名前空間 に設定し、ns 名前空間を選択して、次へ をクリックします。

    8. インシデント通知 ステップで、通知方法DingTalk に設定します。DingTalk チャットボットの Webhook URL およびシークレットトークンを入力して、保存 をクリックします。

  5. イメージビルドをトリガーします。

    次のコマンドを実行して、HelloController.java ファイルを変更し、GitLab にコミットします。これにより、イメージビルドがトリガーされます。

    vim java/com/example/demo/HelloController.java # ローカルで HelloController.java ファイルを必要に応じて変更します。
    git add . && git commit -m 'commit' && git push origin # ファイルを GitLab にコミットします。

    しばらく待ちます。Enterprise Edition インスタンスの詳細ページで、左側ナビゲーションから リポジトリ > リポジトリ を選択します。表示されたページで、対象のリポジトリ test をクリックします。リポジトリ ページで、左側ナビゲーションの タグ をクリックします。タグ ページにイメージが生成されていることを確認できます。

  6. セキュリティスキャンを設定します。

    1. セキュリティスキャン ページで、対象のイメージタグを見つけ、セキュリティスキャン 列の セキュリティスキャン をクリックします。

    2. セキュリティスキャン ページで、スキャン をクリックします。

      セキュリティスキャンが完了すると、DingTalk グループに通知が届きます。

Jenkins を使用したイメージの CD

GitLab へのソースコードのコミットにより、Container Registry (ACR) で自動的にイメージがビルドされます。ビルド完了によりデリバリーチェーンがトリガーされます。デリバリーチェーンが完了すると、HTTP リクエストが Jenkins に送信され、ACK デプロイメントが最新のイメージをプルしてアプリケーションを再デプロイします。

  1. アプリケーションを作成します。

    1. Container Service 管理コンソール にログインします。

    2. 左側ナビゲーションウィンドウで、クラスター をクリックします。

    3. クラスターリスト ページで、送信先クラスターの名前をクリックするか、詳細操作 列でクリックします。

    4. クラスター管理ページの左側ナビゲーションウィンドウで、ワークロード > 展開 を選択します。

    5. デプロイメント ページで、名前空間 を選択し、YAML のリソースの作成 をクリックします。

    6. YAML のリソースの作成 パネルで、サンプルテンプレートカスタム に設定します。次のコードをテンプレートにコピーし、デプロイ をクリックします。

      説明

      パスワード不要でのイメージプルを構成していない場合は、Container Registry (ACR) のインターネットアクセスを有効にし、イメージリポジトリを公開にする必要があります。詳細については、「インターネットアクセスの設定」をご参照ください。

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        creationTimestamp: null
        labels:
          app: demo
        name: demo
      spec:
        replicas: 3
        minReadySeconds: 5
        progressDeadlineSeconds: 60
        revisionHistoryLimit: 5
        selector:
          matchLabels:
            app: demo
        strategy:
          rollingUpdate:
            maxUnavailable: 1
          type: RollingUpdate
        template:
          metadata:
            annotations:
              prometheus.io/port: "9797"
              prometheus.io/scrape: "true"
            creationTimestamp: null
            labels:
              app: demo
          spec:
            containers:
            - image: s*****-devsecops-registry.cn-hongkong.cr.aliyuncs.com/ns/test:0.0.1 
              imagePullPolicy: Always
              name: demo
              ports:
              - containerPort: 8080
                name: http
                protocol: TCP
              readinessProbe:
                initialDelaySeconds: 5
                tcpSocket:
                  port: 8080
                timeoutSeconds: 5
              resources:
                limits:
                  cpu: "2"
                  memory: 512Mi
                requests:
                  cpu: 100m
                  memory: 64Mi
      status: {}
      ---
      apiVersion: v1
      kind: Service
      metadata:
        name: demo-svc
      spec:
        selector:
          app: demo
        ports:
          - protocol: TCP
            port: 80
            targetPort: 8080
      ---
      apiVersion: extensions/v1beta1
      kind: Ingress
      metadata:
        name: demo
        labels:
          app: demo
      spec:
        rules:
          - host: app.demo.example.com
            http:
              paths:
                - backend:
                    serviceName: demo-svc
                    servicePort: 80
      ---
                                      
    7. デプロイメント ページで、アプリケーション demo をクリックし、アクセス方法 タブをクリックします。

      アクセス方法 タブで、外部エンドポイントを取得します。

    8. ローカルの hosts ファイルに次のエントリを追加します。

      <external endpoint address> app.demo.example.com
    9. ブラウザのアドレスバーに app.demo.example.com を入力します。

      Application上記のページが表示されれば、アプリケーションが正常にデプロイされています。

  2. トリガーを作成します。

    1. Deployments ページで、demo アプリケーションをクリックします。

    2. アプリケーション詳細ページで、トリガー タブをクリックし、トリガーの作成 をクリックします。

    3. トリガーの作成 ダイアログボックスで、アクション再デプロイ に設定し、OK をクリックします。

      トリガー タブで、トリガー URL を取得します。

  3. パイプラインを作成します。

    1. Jenkins にログインします。

    2. 左側のナビゲーションウィンドウで、New Item をクリックします。

    3. アイテム名を入力し、Pipeline を選択して、OK をクリックします。

    4. Build Triggers タブをクリックし、Generic Webhook Trigger を選択します。

      Generic Webhook Trigger セクションで、HTTP リクエストトリガー URL は JENKINS_URL/generic-webhook-trigger/invoke です。本チュートリアルでは、Generic Webhook tokenhelloworld2021 に設定されています。したがって、Webhook URL は JENKINS_URL/generic-webhook-trigger/invoke?token=helloworld2021 になります。

    5. Pipeline タブをクリックします。以下のテンプレートで、プレースホルダーの Generic Webhook トークンおよびトリガー URL を実際の値に置き換えます。修正後の内容をテキストボックスにコピーし、Save をクリックします。

      pipeline {
        agent any
        triggers {
          GenericTrigger(
           genericVariables: [
            [key: 'InstanceId', value: '$.data.InstanceId'],   
            [key: 'RepoNamespaceName', value: '$.data.RepoNamespaceName'],
            [key: 'RepoName', value: '$.data.RepoName'],
            [key: 'Tag', value: '$.data.Tag']
           ],
           causeString: 'Triggered on $ref',
           token: 'helloworld2021',   # Generic Webhook トークン。実際のトークンに置き換えてください。
           tokenCredentialId: '',
           printContributedVariables: true,
           printPostContent: true,
           silentResponse: false,
           regexpFilterText: '$ref'
          )
        }
        stages {
          stage('Some step') {
            steps {
              sh "echo 'will print post content'"
              sh "echo $InstanceId"
              sh "echo $RepoNamespaceName"
              sh "echo $RepoName"
              sh "echo $Tag"
              sh "echo 'redeploy to ACK or you can deoloy to other platforms use before message'"
              sh "curl 'https://cs.console.alibabacloud.com/hook/trigger?token=g****'  # トリガー URL。実際の URL に置き換えてください。
              sh "echo 'done'"
            }
          }
        }
      }
  4. デリバリーチェーンを作成します。詳細については、「デリバリーチェーンの作成」をご参照ください。

  5. イベントルールを作成します。

    1. ACR Enterprise Edition インスタンスの管理ページで、左側ナビゲーションウィンドウから インスタンス > インシデント通知 を選択します。

    2. イベントルール タブで、ルールの作成 をクリックします。

    3. イベントの範囲 ステップで、ルール名 を設定します。イベントタイプデリバリーチェーンを処理しました。 に設定し、成功 を選択します。適用範囲名前空間 に設定し、ns 名前空間を選択して、次へ をクリックします。

    4. インシデント通知 ステップで、通知方法HTTP に設定します。ステップ 3 で取得した Webhook URL を入力し、保存 をクリックします。

  6. 次のコマンドを実行して、HelloController.java ファイルを変更し、コードを GitLab にコミットします。これにより、イメージビルドがトリガーされます。

    vim java/com/example/demo/HelloController.java # ローカルで HelloController.java ファイルを必要に応じて変更します。
    git add . && git commit -m 'add update' && git push origin   # ファイルを GitLab にコミットします。

    イメージビルドによりデリバリーチェーンがトリガーされます。チェーンが完了すると、ACK デプロイメントがトリガーされ、新しいイメージをプルしてアプリケーションを再デプロイします。

  7. 次のコマンドを実行して、アプリケーションが再デプロイされたことを確認します。

    curl app.demo.example.com

    出力が変化すれば、アプリケーションが正常に再デプロイされています。