Does multistage docker images have the same layers?












0















Let's say I decided to make following multistage build:



FROM node:8.6-alpine AS build1
#some other commands
FROM node:8.5-alpine AS build2
# yet another commands


definitely there are some layers which will be common between build1 and build2. Will docker duplicate layers, or append somehow reference already built layers?










share|improve this question























  • The interesting result of a multistage build is only the last image. In your example there would be only shared layers if the two base images share some layers.

    – Henry
    Nov 13 '18 at 7:50











  • you mean that first image will be thrown away?

    – Yuriy Zaletskyy
    Nov 13 '18 at 7:51













  • More or less yes. It will still be in the build cache to speed up later builds but it will not show up in the result image. This is the whole idea behind this feature. Things needed to build the app are not necessary at run time.

    – Henry
    Nov 13 '18 at 7:53













  • As far as I know, when docker is building an image, it does it layer wise so that these layers could be reused. So, that should be the case with any docker build whether multistage or not.

    – scipsycho
    Nov 13 '18 at 8:03
















0















Let's say I decided to make following multistage build:



FROM node:8.6-alpine AS build1
#some other commands
FROM node:8.5-alpine AS build2
# yet another commands


definitely there are some layers which will be common between build1 and build2. Will docker duplicate layers, or append somehow reference already built layers?










share|improve this question























  • The interesting result of a multistage build is only the last image. In your example there would be only shared layers if the two base images share some layers.

    – Henry
    Nov 13 '18 at 7:50











  • you mean that first image will be thrown away?

    – Yuriy Zaletskyy
    Nov 13 '18 at 7:51













  • More or less yes. It will still be in the build cache to speed up later builds but it will not show up in the result image. This is the whole idea behind this feature. Things needed to build the app are not necessary at run time.

    – Henry
    Nov 13 '18 at 7:53













  • As far as I know, when docker is building an image, it does it layer wise so that these layers could be reused. So, that should be the case with any docker build whether multistage or not.

    – scipsycho
    Nov 13 '18 at 8:03














0












0








0


0






Let's say I decided to make following multistage build:



FROM node:8.6-alpine AS build1
#some other commands
FROM node:8.5-alpine AS build2
# yet another commands


definitely there are some layers which will be common between build1 and build2. Will docker duplicate layers, or append somehow reference already built layers?










share|improve this question














Let's say I decided to make following multistage build:



FROM node:8.6-alpine AS build1
#some other commands
FROM node:8.5-alpine AS build2
# yet another commands


definitely there are some layers which will be common between build1 and build2. Will docker duplicate layers, or append somehow reference already built layers?







docker dockerfile






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 13 '18 at 7:45









Yuriy ZaletskyyYuriy Zaletskyy

3,40732540




3,40732540













  • The interesting result of a multistage build is only the last image. In your example there would be only shared layers if the two base images share some layers.

    – Henry
    Nov 13 '18 at 7:50











  • you mean that first image will be thrown away?

    – Yuriy Zaletskyy
    Nov 13 '18 at 7:51













  • More or less yes. It will still be in the build cache to speed up later builds but it will not show up in the result image. This is the whole idea behind this feature. Things needed to build the app are not necessary at run time.

    – Henry
    Nov 13 '18 at 7:53













  • As far as I know, when docker is building an image, it does it layer wise so that these layers could be reused. So, that should be the case with any docker build whether multistage or not.

    – scipsycho
    Nov 13 '18 at 8:03



















  • The interesting result of a multistage build is only the last image. In your example there would be only shared layers if the two base images share some layers.

    – Henry
    Nov 13 '18 at 7:50











  • you mean that first image will be thrown away?

    – Yuriy Zaletskyy
    Nov 13 '18 at 7:51













  • More or less yes. It will still be in the build cache to speed up later builds but it will not show up in the result image. This is the whole idea behind this feature. Things needed to build the app are not necessary at run time.

    – Henry
    Nov 13 '18 at 7:53













  • As far as I know, when docker is building an image, it does it layer wise so that these layers could be reused. So, that should be the case with any docker build whether multistage or not.

    – scipsycho
    Nov 13 '18 at 8:03

















The interesting result of a multistage build is only the last image. In your example there would be only shared layers if the two base images share some layers.

– Henry
Nov 13 '18 at 7:50





The interesting result of a multistage build is only the last image. In your example there would be only shared layers if the two base images share some layers.

– Henry
Nov 13 '18 at 7:50













you mean that first image will be thrown away?

– Yuriy Zaletskyy
Nov 13 '18 at 7:51







you mean that first image will be thrown away?

– Yuriy Zaletskyy
Nov 13 '18 at 7:51















More or less yes. It will still be in the build cache to speed up later builds but it will not show up in the result image. This is the whole idea behind this feature. Things needed to build the app are not necessary at run time.

– Henry
Nov 13 '18 at 7:53







More or less yes. It will still be in the build cache to speed up later builds but it will not show up in the result image. This is the whole idea behind this feature. Things needed to build the app are not necessary at run time.

– Henry
Nov 13 '18 at 7:53















As far as I know, when docker is building an image, it does it layer wise so that these layers could be reused. So, that should be the case with any docker build whether multistage or not.

– scipsycho
Nov 13 '18 at 8:03





As far as I know, when docker is building an image, it does it layer wise so that these layers could be reused. So, that should be the case with any docker build whether multistage or not.

– scipsycho
Nov 13 '18 at 8:03












2 Answers
2






active

oldest

votes


















1














Next is the result of your dockerfile build on a fresh machine:



# docker build -t test:1 .
Sending build context to Docker daemon 2.048kB
Step 1/2 : FROM node:8.6-alpine AS build1
8.6-alpine: Pulling from library/node
88286f41530e: Pull complete
d0e8a23136b3: Pull complete
5ad5b12a980e: Pull complete
Digest: sha256:60cd58a7a2bd9fec161f53f8886e451f92db06b91f4f72d9188eeea040d195eb
Status: Downloaded newer image for node:8.6-alpine
---> b7e15c83cdaf
Step 2/2 : FROM node:8.5-alpine AS build2
8.5-alpine: Pulling from library/node
88286f41530e: Already exists
aa0be12c5610: Pull complete
719d346e6de2: Pull complete
Digest: sha256:945cf56668d3e58a3b045291564963ccde29a68da9c1483e19d8a0b06749db06
Status: Downloaded newer image for node:8.5-alpine
---> 7a779c246a41
Successfully built 7a779c246a41
Successfully tagged test:1


From the output you can see image id 88286f41530e was reused as Already exists.



And docker images output:



REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
node 8.6-alpine b7e15c83cdaf 13 months ago 67.2MB
node 8.5-alpine 7a779c246a41 14 months ago 67MB


So, the base image of first stage in the multibuild also reserve in cache.



And from this post:




Since Docker v1.10, generally, images and layers are no longer synonymous.
Instead, an image directly references one or more layers that eventually contribute to a derived container's filesystem.




So, as some image reused, the layers surely be reused.



Of course, this depends on the base images you used in multibuild, they need have something to reuse.



Anyway, I think multibuild just add some trick compared to traditional build, but layer reuse mechanism is the same.






share|improve this answer































    1














    I believe ordinary docker build layer caching will apply, but there are other better answers.



    FROM ubuntu:18.04 AS first
    RUN apt-get update
    && DEBIAN_FRONTEND=noninteractive
    apt-get install -y --no-install-recommends
    python3
    RUN echo first

    FROM ubuntu:18.04 AS second
    RUN apt-get update
    && DEBIAN_FRONTEND=noninteractive
    apt-get install -y --no-install-recommends
    python3
    RUN echo second


    The rules are that you must start from the exact same base image (in your example nothing is shared) and you must repeat the exact same commands (or COPY the exact same file content); as soon as you stray from this path nothing is shared, including in any later identical commands.



    You can use the AS alias in later FROM directives so if you really want to share some base layer it's better to do it explicitly



    FROM ubuntu:18.04 AS base
    RUN apt-get update
    && DEBIAN_FRONTEND=noninteractive
    apt-get install -y --no-install-recommends
    python3

    FROM base AS first
    RUN echo first

    FROM base AS second
    RUN echo second


    The more common case with a multi-stage build as to have very different "build" and "runtime" images so this doesn't often apply.



    FROM golang:1.11 AS build
    WORKDIR /go/src/github.com/me/myapp
    COPY ./ ./
    RUN go install .

    FROM alpine
    COPY --from=build /go/bin/myapp /usr/bin
    CMD ["myapp"]





    share|improve this answer























      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53276123%2fdoes-multistage-docker-images-have-the-same-layers%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      2 Answers
      2






      active

      oldest

      votes








      2 Answers
      2






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      1














      Next is the result of your dockerfile build on a fresh machine:



      # docker build -t test:1 .
      Sending build context to Docker daemon 2.048kB
      Step 1/2 : FROM node:8.6-alpine AS build1
      8.6-alpine: Pulling from library/node
      88286f41530e: Pull complete
      d0e8a23136b3: Pull complete
      5ad5b12a980e: Pull complete
      Digest: sha256:60cd58a7a2bd9fec161f53f8886e451f92db06b91f4f72d9188eeea040d195eb
      Status: Downloaded newer image for node:8.6-alpine
      ---> b7e15c83cdaf
      Step 2/2 : FROM node:8.5-alpine AS build2
      8.5-alpine: Pulling from library/node
      88286f41530e: Already exists
      aa0be12c5610: Pull complete
      719d346e6de2: Pull complete
      Digest: sha256:945cf56668d3e58a3b045291564963ccde29a68da9c1483e19d8a0b06749db06
      Status: Downloaded newer image for node:8.5-alpine
      ---> 7a779c246a41
      Successfully built 7a779c246a41
      Successfully tagged test:1


      From the output you can see image id 88286f41530e was reused as Already exists.



      And docker images output:



      REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
      node 8.6-alpine b7e15c83cdaf 13 months ago 67.2MB
      node 8.5-alpine 7a779c246a41 14 months ago 67MB


      So, the base image of first stage in the multibuild also reserve in cache.



      And from this post:




      Since Docker v1.10, generally, images and layers are no longer synonymous.
      Instead, an image directly references one or more layers that eventually contribute to a derived container's filesystem.




      So, as some image reused, the layers surely be reused.



      Of course, this depends on the base images you used in multibuild, they need have something to reuse.



      Anyway, I think multibuild just add some trick compared to traditional build, but layer reuse mechanism is the same.






      share|improve this answer




























        1














        Next is the result of your dockerfile build on a fresh machine:



        # docker build -t test:1 .
        Sending build context to Docker daemon 2.048kB
        Step 1/2 : FROM node:8.6-alpine AS build1
        8.6-alpine: Pulling from library/node
        88286f41530e: Pull complete
        d0e8a23136b3: Pull complete
        5ad5b12a980e: Pull complete
        Digest: sha256:60cd58a7a2bd9fec161f53f8886e451f92db06b91f4f72d9188eeea040d195eb
        Status: Downloaded newer image for node:8.6-alpine
        ---> b7e15c83cdaf
        Step 2/2 : FROM node:8.5-alpine AS build2
        8.5-alpine: Pulling from library/node
        88286f41530e: Already exists
        aa0be12c5610: Pull complete
        719d346e6de2: Pull complete
        Digest: sha256:945cf56668d3e58a3b045291564963ccde29a68da9c1483e19d8a0b06749db06
        Status: Downloaded newer image for node:8.5-alpine
        ---> 7a779c246a41
        Successfully built 7a779c246a41
        Successfully tagged test:1


        From the output you can see image id 88286f41530e was reused as Already exists.



        And docker images output:



        REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
        node 8.6-alpine b7e15c83cdaf 13 months ago 67.2MB
        node 8.5-alpine 7a779c246a41 14 months ago 67MB


        So, the base image of first stage in the multibuild also reserve in cache.



        And from this post:




        Since Docker v1.10, generally, images and layers are no longer synonymous.
        Instead, an image directly references one or more layers that eventually contribute to a derived container's filesystem.




        So, as some image reused, the layers surely be reused.



        Of course, this depends on the base images you used in multibuild, they need have something to reuse.



        Anyway, I think multibuild just add some trick compared to traditional build, but layer reuse mechanism is the same.






        share|improve this answer


























          1












          1








          1







          Next is the result of your dockerfile build on a fresh machine:



          # docker build -t test:1 .
          Sending build context to Docker daemon 2.048kB
          Step 1/2 : FROM node:8.6-alpine AS build1
          8.6-alpine: Pulling from library/node
          88286f41530e: Pull complete
          d0e8a23136b3: Pull complete
          5ad5b12a980e: Pull complete
          Digest: sha256:60cd58a7a2bd9fec161f53f8886e451f92db06b91f4f72d9188eeea040d195eb
          Status: Downloaded newer image for node:8.6-alpine
          ---> b7e15c83cdaf
          Step 2/2 : FROM node:8.5-alpine AS build2
          8.5-alpine: Pulling from library/node
          88286f41530e: Already exists
          aa0be12c5610: Pull complete
          719d346e6de2: Pull complete
          Digest: sha256:945cf56668d3e58a3b045291564963ccde29a68da9c1483e19d8a0b06749db06
          Status: Downloaded newer image for node:8.5-alpine
          ---> 7a779c246a41
          Successfully built 7a779c246a41
          Successfully tagged test:1


          From the output you can see image id 88286f41530e was reused as Already exists.



          And docker images output:



          REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
          node 8.6-alpine b7e15c83cdaf 13 months ago 67.2MB
          node 8.5-alpine 7a779c246a41 14 months ago 67MB


          So, the base image of first stage in the multibuild also reserve in cache.



          And from this post:




          Since Docker v1.10, generally, images and layers are no longer synonymous.
          Instead, an image directly references one or more layers that eventually contribute to a derived container's filesystem.




          So, as some image reused, the layers surely be reused.



          Of course, this depends on the base images you used in multibuild, they need have something to reuse.



          Anyway, I think multibuild just add some trick compared to traditional build, but layer reuse mechanism is the same.






          share|improve this answer













          Next is the result of your dockerfile build on a fresh machine:



          # docker build -t test:1 .
          Sending build context to Docker daemon 2.048kB
          Step 1/2 : FROM node:8.6-alpine AS build1
          8.6-alpine: Pulling from library/node
          88286f41530e: Pull complete
          d0e8a23136b3: Pull complete
          5ad5b12a980e: Pull complete
          Digest: sha256:60cd58a7a2bd9fec161f53f8886e451f92db06b91f4f72d9188eeea040d195eb
          Status: Downloaded newer image for node:8.6-alpine
          ---> b7e15c83cdaf
          Step 2/2 : FROM node:8.5-alpine AS build2
          8.5-alpine: Pulling from library/node
          88286f41530e: Already exists
          aa0be12c5610: Pull complete
          719d346e6de2: Pull complete
          Digest: sha256:945cf56668d3e58a3b045291564963ccde29a68da9c1483e19d8a0b06749db06
          Status: Downloaded newer image for node:8.5-alpine
          ---> 7a779c246a41
          Successfully built 7a779c246a41
          Successfully tagged test:1


          From the output you can see image id 88286f41530e was reused as Already exists.



          And docker images output:



          REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
          node 8.6-alpine b7e15c83cdaf 13 months ago 67.2MB
          node 8.5-alpine 7a779c246a41 14 months ago 67MB


          So, the base image of first stage in the multibuild also reserve in cache.



          And from this post:




          Since Docker v1.10, generally, images and layers are no longer synonymous.
          Instead, an image directly references one or more layers that eventually contribute to a derived container's filesystem.




          So, as some image reused, the layers surely be reused.



          Of course, this depends on the base images you used in multibuild, they need have something to reuse.



          Anyway, I think multibuild just add some trick compared to traditional build, but layer reuse mechanism is the same.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 13 '18 at 9:13









          lagomlagom

          1




          1

























              1














              I believe ordinary docker build layer caching will apply, but there are other better answers.



              FROM ubuntu:18.04 AS first
              RUN apt-get update
              && DEBIAN_FRONTEND=noninteractive
              apt-get install -y --no-install-recommends
              python3
              RUN echo first

              FROM ubuntu:18.04 AS second
              RUN apt-get update
              && DEBIAN_FRONTEND=noninteractive
              apt-get install -y --no-install-recommends
              python3
              RUN echo second


              The rules are that you must start from the exact same base image (in your example nothing is shared) and you must repeat the exact same commands (or COPY the exact same file content); as soon as you stray from this path nothing is shared, including in any later identical commands.



              You can use the AS alias in later FROM directives so if you really want to share some base layer it's better to do it explicitly



              FROM ubuntu:18.04 AS base
              RUN apt-get update
              && DEBIAN_FRONTEND=noninteractive
              apt-get install -y --no-install-recommends
              python3

              FROM base AS first
              RUN echo first

              FROM base AS second
              RUN echo second


              The more common case with a multi-stage build as to have very different "build" and "runtime" images so this doesn't often apply.



              FROM golang:1.11 AS build
              WORKDIR /go/src/github.com/me/myapp
              COPY ./ ./
              RUN go install .

              FROM alpine
              COPY --from=build /go/bin/myapp /usr/bin
              CMD ["myapp"]





              share|improve this answer




























                1














                I believe ordinary docker build layer caching will apply, but there are other better answers.



                FROM ubuntu:18.04 AS first
                RUN apt-get update
                && DEBIAN_FRONTEND=noninteractive
                apt-get install -y --no-install-recommends
                python3
                RUN echo first

                FROM ubuntu:18.04 AS second
                RUN apt-get update
                && DEBIAN_FRONTEND=noninteractive
                apt-get install -y --no-install-recommends
                python3
                RUN echo second


                The rules are that you must start from the exact same base image (in your example nothing is shared) and you must repeat the exact same commands (or COPY the exact same file content); as soon as you stray from this path nothing is shared, including in any later identical commands.



                You can use the AS alias in later FROM directives so if you really want to share some base layer it's better to do it explicitly



                FROM ubuntu:18.04 AS base
                RUN apt-get update
                && DEBIAN_FRONTEND=noninteractive
                apt-get install -y --no-install-recommends
                python3

                FROM base AS first
                RUN echo first

                FROM base AS second
                RUN echo second


                The more common case with a multi-stage build as to have very different "build" and "runtime" images so this doesn't often apply.



                FROM golang:1.11 AS build
                WORKDIR /go/src/github.com/me/myapp
                COPY ./ ./
                RUN go install .

                FROM alpine
                COPY --from=build /go/bin/myapp /usr/bin
                CMD ["myapp"]





                share|improve this answer


























                  1












                  1








                  1







                  I believe ordinary docker build layer caching will apply, but there are other better answers.



                  FROM ubuntu:18.04 AS first
                  RUN apt-get update
                  && DEBIAN_FRONTEND=noninteractive
                  apt-get install -y --no-install-recommends
                  python3
                  RUN echo first

                  FROM ubuntu:18.04 AS second
                  RUN apt-get update
                  && DEBIAN_FRONTEND=noninteractive
                  apt-get install -y --no-install-recommends
                  python3
                  RUN echo second


                  The rules are that you must start from the exact same base image (in your example nothing is shared) and you must repeat the exact same commands (or COPY the exact same file content); as soon as you stray from this path nothing is shared, including in any later identical commands.



                  You can use the AS alias in later FROM directives so if you really want to share some base layer it's better to do it explicitly



                  FROM ubuntu:18.04 AS base
                  RUN apt-get update
                  && DEBIAN_FRONTEND=noninteractive
                  apt-get install -y --no-install-recommends
                  python3

                  FROM base AS first
                  RUN echo first

                  FROM base AS second
                  RUN echo second


                  The more common case with a multi-stage build as to have very different "build" and "runtime" images so this doesn't often apply.



                  FROM golang:1.11 AS build
                  WORKDIR /go/src/github.com/me/myapp
                  COPY ./ ./
                  RUN go install .

                  FROM alpine
                  COPY --from=build /go/bin/myapp /usr/bin
                  CMD ["myapp"]





                  share|improve this answer













                  I believe ordinary docker build layer caching will apply, but there are other better answers.



                  FROM ubuntu:18.04 AS first
                  RUN apt-get update
                  && DEBIAN_FRONTEND=noninteractive
                  apt-get install -y --no-install-recommends
                  python3
                  RUN echo first

                  FROM ubuntu:18.04 AS second
                  RUN apt-get update
                  && DEBIAN_FRONTEND=noninteractive
                  apt-get install -y --no-install-recommends
                  python3
                  RUN echo second


                  The rules are that you must start from the exact same base image (in your example nothing is shared) and you must repeat the exact same commands (or COPY the exact same file content); as soon as you stray from this path nothing is shared, including in any later identical commands.



                  You can use the AS alias in later FROM directives so if you really want to share some base layer it's better to do it explicitly



                  FROM ubuntu:18.04 AS base
                  RUN apt-get update
                  && DEBIAN_FRONTEND=noninteractive
                  apt-get install -y --no-install-recommends
                  python3

                  FROM base AS first
                  RUN echo first

                  FROM base AS second
                  RUN echo second


                  The more common case with a multi-stage build as to have very different "build" and "runtime" images so this doesn't often apply.



                  FROM golang:1.11 AS build
                  WORKDIR /go/src/github.com/me/myapp
                  COPY ./ ./
                  RUN go install .

                  FROM alpine
                  COPY --from=build /go/bin/myapp /usr/bin
                  CMD ["myapp"]






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 13 '18 at 11:53









                  David MazeDavid Maze

                  12.4k31225




                  12.4k31225






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53276123%2fdoes-multistage-docker-images-have-the-same-layers%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Full-time equivalent

                      さくらももこ

                      13 indicted, 8 arrested in Calif. drug cartel investigation