Dela via


Självstudie: Spara data i en containerapp med hjälp av volymer i VS Code

I den här handledningen lär du dig att lagra data i en containerapplikation. När du kör den eller uppdaterar den är data fortfarande tillgängliga. Det finns två huvudsakliga typer av volymer som används för att bevara data. Den här handledningen fokuserar på namngivna volymer.

Du får också lära dig mer om bind-monteringar, som styr den exakta monteringspunkten på värddatorn. Du kan använda bind mounts för att spara data, men det kan dock även lägga till mer data i containrar. När du arbetar med ett program kan du använda en bindningsmontering för att montera källkoden i containern så att den kan se kodändringar, svara och låta dig se ändringarna direkt.

I den här självstudien introduceras även bildskiktning, cachelagring av lager och flerstegsbyggen.

I den här handledningen får du lära dig hur du:

  • Förstå data över olika containrar.
  • Spara data med hjälp av namngivna volymer.
  • Använd bindningsfästen.
  • Visa bildskikt.
  • Cache-beroenden.
  • Förstå flerstegsbyggen.

Förutsättningar

Den här självstudien fortsätter den tidigare självstudien Skapa och dela en containerapp med Visual Studio Code. Börja med den, som innehåller krav.

Förstå data mellan containrar

I det här avsnittet startar du två containrar och skapar en fil i var och en. Filerna som skapas i en container är inte tillgängliga i en annan.

  1. Starta en ubuntu container med hjälp av det här kommandot:

    docker run -d ubuntu bash -c "shuf -i 1-10000 -n 1 -o /data.txt && tail -f /dev/null"
    

    Det här kommandot anropar två kommandon med hjälp av &&. Den första delen väljer ett enskilt slumptal och skriver det till /data.txt. Det andra kommandot övervakar en fil för att hålla containern igång.

  2. I VS Code högerklickar du på ubuntu-containern i Container Explorer och väljer Bifoga gränssnitt.

    Skärmbild som visar containerverktygstillägget med en container markerad och en snabbmeny med Attach Shell valt.

    En terminal öppnas som kör ett gränssnitt i Ubuntu-containern.

  3. Kör följande kommando för att se innehållet i /data.txt-filen.

    cat /data.txt
    

    Terminalen visar ett tal mellan 1 och 10000.

    Om du vill använda kommandoraden för att se det här resultatet hämtar du container-ID:t med hjälp av kommandot docker ps och kör följande kommando.

    docker exec <container-id> cat /data.txt
    
  4. Starta en annan ubuntu container.

    docker run -d ubuntu bash -c "shuf -i 1-10000 -n 1 -o /data.txt && tail -f /dev/null"
    
  5. Använd det här kommandot för att titta på mappinnehållet.

    docker run -it ubuntu ls /
    

    Det ska inte finnas någon data.txt fil där eftersom den skrevs till scratch-utrymmet för endast den första containern.

  6. Välj dessa två Ubuntu-containrar. Högerklicka och välj Ta bort. Från kommandoraden kan du ta bort dem med hjälp av kommandot docker rm -f.

Spara dina att göra-data med hjälp av namngivna volymer

Som standard lagrar todo-appen sina data i en SQLite Database-/etc/todos/todo.db. SQLite Database är en relationsdatabas som lagrar data en enda fil. Den här metoden fungerar för små projekt.

Du kan spara den enskilda filen på värddatorn. När du gör den tillgänglig för nästa container kan programmet fortsätta där det slutade. Genom att skapa en volym och koppla eller monteraden till mappen där data lagras kan du bevara data. Containern skriver till todo.db-filen och den datan kvarstår på värden i volymen.

I det här avsnittet använder du en med namnet volume. Docker underhåller den fysiska platsen för volymen på disken. Se namnet på volymen och Docker tillhandahåller rätt data.

  1. Skapa en volym med hjälp av kommandot docker volume create.

    docker volume create todo-db
    
  2. Under CONTAINERS, välj komma igång och högerklicka. Välj Stoppa för att stoppa appcontainern.

    Om du vill stoppa containern från kommandoraden använder du kommandot docker stop.

  3. Starta komma-igång-containern med följande kommando.

    docker run -dp 3000:3000 -v todo-db:/etc/todos getting-started
    

    Volymparametern anger volymen som ska monteras och platsen /etc/todos.

  4. Uppdatera webbläsaren för att läsa in appen igen. Om du har stängt webbläsarfönstret går du till http://localhost:3000/. Lägg till några objekt i din att göra-lista.

    Skärmbild som visar exempelappen med flera objekt som har lagts till i listan.

  5. Ta bort introduktion containern för göraappen. Högerklicka antingen på containern i Container Explorer och välj Ta bort eller använd kommandona docker stop och docker rm .

  6. Starta en ny container med samma kommando:

    docker run -dp 3000:3000 -v todo-db:/etc/todos getting-started
    

    Kommandot monterar samma enhet som tidigare. Uppdatera webbläsaren. Objekten som du har lagt till finns fortfarande i listan.

  7. Ta bort kom-igång--container igen.

Namngivna volymer och bindningsmonteringar, som beskrivs nedan, är de viktigaste typerna av volymer som stöds av en standardinstallation av Docker-motorn.

Egenskap Namngivna volymer Bind monteringar
Värdplats Docker väljer Du styr
Monteringsexempel (med användning av -v) my-volume:/usr/local/data /path/to/data:/usr/local/data
Fyller i ny volym med containerinnehåll Ja Nej
Stödjer volymdrivrutiner Ja Nej

Det finns många plugin-program för volymdrivrutiner som stöder NFS, SFTP, NetApp med mera. Dessa plugin-program är särskilt viktiga för att köra containrar på flera värdar i en klustrad miljö, till exempel Swarm eller Kubernetes.

Om du undrar var Docker faktiskt lagrar dina data kör du följande kommando.

docker volume inspect todo-db

Titta på utdata som liknar det här resultatet.

[
    {
        "CreatedAt": "2019-09-26T02:18:36Z",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/todo-db/_data",
        "Name": "todo-db",
        "Options": {},
        "Scope": "local"
    }
]

Mountpoint är den faktiska platsen där data lagras. På de flesta datorer behöver du root-åtkomst för att få åtkomst till den här katalogen från värden.

Använd bindmonteringar

Med bind mountskan du exakt kontrollera monteringspunkten på värden. Den här metoden bevarar data, men används ofta för att tillhandahålla mer data i containrar. Du kan använda en bindningsmontering för att montera källkoden i containern så att den kan se kodändringar, svara och låta dig se ändringarna direkt.

Om du vill köra containern för att stödja ett utvecklingsarbetsflöde utför du följande steg:

  1. Ta bort alla getting-started-behållare.

  2. Kör följande kommando i mappen app.

    docker run -dp 3000:3000 -w /app -v ${PWD}:/app node:lts-alpine sh -c "yarn install && yarn run dev"
    

    Det här kommandot innehåller följande parametrar.

    • -dp 3000:3000 Samma som tidigare. Kör i frånkopplat läge och skapa en portmappning.
    • -w /app Arbetskatalog inuti containern.
    • -v ${PWD}:/app" Bind montera den aktuella katalogen från värden i containern till katalogen /app.
    • node:lts-alpine Den avbildning som ska användas. Den här avbildningen är basavbildningen för din app från Dockerfile.
    • sh -c "yarn install && yarn run dev" Ett kommando. Det startar ett gränssnitt med hjälp av sh och kör yarn install för att installera alla beroenden. Sedan körs den yarn run dev. Om du tittar i package.json, så startar dev-skriptet nodemon.
  3. Du kan titta på loggarna med hjälp av docker logs.

    docker logs -f <container-id>
    
    $ nodemon src/index.js
    [nodemon] 2.0.20
    [nodemon] to restart at any time, enter `rs`
    [nodemon] watching path(s): *.*
    [nodemon] watching extensions: js,mjs,json
    [nodemon] starting `node src/index.js`
    Using sqlite database at /etc/todos/todo.db
    Listening on port 3000
    

    När du ser den sista posten i den här listan körs appen.

    När du är klar med att titta på loggarna väljer du valfri nyckel i terminalfönstret eller väljer Ctrl+C- i ett externt fönster.

  4. Öppna src/static/js/app.jsi VS Code. Ändra texten i knappen Lägg till objekt på rad 109.

    - {submitting ? 'Adding...' : 'Add Item'}
    + {submitting ? 'Adding...' : 'Add'}
    

    Spara ändringen.

  5. Uppdatera webbläsaren. Du bör se ändringen.

    Skärmbild som visar exempelappen med den nya texten på knappen.

  6. Ta bort containern node:lts-alpine .

  7. I mappen app kör du följande kommando för att ta bort mappen node_modules som skapades i föregående steg.

    rm -r node_modules
    

Visa bildlager

Du kan titta på de lager som utgör en bild. Kör kommandot docker image history för att se kommandot som användes för att skapa varje lager i en avbildning.

  1. Använd docker image history för att se lagren i bilden för att komma igång, som du skapade tidigare i handledningen.

    docker image history getting-started
    

    Resultatet bör likna dessa utdata.

    IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
    a78a40cbf866        18 seconds ago      /bin/sh -c #(nop)  CMD ["node" "/app/src/ind…   0B                  
    f1d1808565d6        19 seconds ago      /bin/sh -c yarn install --production            85.4MB              
    a2c054d14948        36 seconds ago      /bin/sh -c #(nop) COPY dir:5dc710ad87c789593…   198kB               
    9577ae713121        37 seconds ago      /bin/sh -c #(nop) WORKDIR /app                  0B                  
    b95baba1cfdb        13 days ago         /bin/sh -c #(nop)  CMD ["node"]                 0B                  
    <missing>           13 days ago         /bin/sh -c #(nop)  ENTRYPOINT ["docker-entry…   0B                  
    <missing>           13 days ago         /bin/sh -c #(nop) COPY file:238737301d473041…   116B                
    <missing>           13 days ago         /bin/sh -c apk add --no-cache --virtual .bui…   5.35MB              
    <missing>           13 days ago         /bin/sh -c #(nop)  ENV YARN_VERSION=1.21.1      0B                  
    <missing>           13 days ago         /bin/sh -c addgroup -g 1000 node     && addu…   74.3MB              
    <missing>           13 days ago         /bin/sh -c #(nop)  ENV NODE_VERSION=12.14.1     0B                  
    <missing>           13 days ago         /bin/sh -c #(nop)  CMD ["/bin/sh"]              0B                  
    <missing>           13 days ago         /bin/sh -c #(nop) ADD file:e69d441d729412d24…   5.59MB   
    

    Var och en av linjerna representerar ett lager i bilden. Utdata visar basen längst ned med det senaste lagret överst. Med hjälp av den här informationen kan du se storleken på varje lager, vilket hjälper dig att diagnostisera stora bilder.

  2. Flera av linjerna är avkortade. Om du lägger till parametern --no-trunc får du fullständiga utdata.

    docker image history --no-trunc getting-started
    

Cacheberoenden

När ett lager ändras måste även alla underordnade lager återskapas. Här är Dockerfile igen:

FROM node:lts-alpine
WORKDIR /app
COPY . .
RUN yarn install --production
CMD ["node", "/app/src/index.js"]

Varje kommando i Dockerfile blir ett nytt lager i avbildningen. För att minimera antalet lager kan du omstrukturera Dockerfile- för att stödja cachelagring av beroenden. För nodbaserade program definieras dessa beroenden i filen package.json.

Metoden är att kopiera endast filen först, installera beroendena och sedan kopiera allt annat. Processen återskapar bara garnberoendena om det skedde en ändring av package.json.

  1. Uppdatera Dockerfile- för att först kopiera in package.json, installera beroenden och sedan kopiera allt annat. Här är den nya filen:

    FROM node:lts-alpine
    WORKDIR /app
    COPY package.json yarn.lock ./
    RUN yarn install --production
    COPY . .
    CMD ["node", "/app/src/index.js"]
    
  2. Skapa en ny avbildning med docker build.

    docker build -t getting-started .
    

    Du bör se utdata liknande följande resultat.

    Sending build context to Docker daemon  219.1kB
    Step 1/6 : FROM node:lts-alpine
    ---> b0dc3a5e5e9e
    Step 2/6 : WORKDIR /app
    ---> Using cache
    ---> 9577ae713121
    Step 3/6 : COPY package* yarn.lock ./
    ---> bd5306f49fc8
    Step 4/6 : RUN yarn install --production
    ---> Running in d53a06c9e4c2
    yarn install v1.17.3
    [1/4] Resolving packages...
    [2/4] Fetching packages...
    info fsevents@1.2.9: The platform "linux" is incompatible with this module.
    info "fsevents@1.2.9" is an optional dependency and failed compatibility check. Excluding it from installation.
    [3/4] Linking dependencies...
    [4/4] Building fresh packages...
    Done in 10.89s.
    Removing intermediate container d53a06c9e4c2
    ---> 4e68fbc2d704
    Step 5/6 : COPY . .
    ---> a239a11f68d8
    Step 6/6 : CMD ["node", "/app/src/index.js"]
    ---> Running in 49999f68df8f
    Removing intermediate container 49999f68df8f
    ---> e709c03bc597
    Successfully built e709c03bc597
    Successfully tagged getting-started:latest
    

    Alla lager återskapades. Det här resultatet förväntas eftersom du har ändrat Dockerfile-.

  3. Gör en ändring i src/static/index.html. Ändra till exempel rubriken till "The Awesome Todo App".

  4. Skapa Docker-avbildningen nu med docker build igen. Den här gången bör dina utdata se lite annorlunda ut.

    Sending build context to Docker daemon  219.1kB
    Step 1/6 : FROM node:lts-alpine
    ---> b0dc3a5e5e9e
    Step 2/6 : WORKDIR /app
    ---> Using cache
    ---> 9577ae713121
    Step 3/6 : COPY package* yarn.lock ./
    ---> Using cache
    ---> bd5306f49fc8
    Step 4/6 : RUN yarn install --production
    ---> Using cache
    ---> 4e68fbc2d704
    Step 5/6 : COPY . .
    ---> cccde25a3d9a
    Step 6/6 : CMD ["node", "/app/src/index.js"]
    ---> Running in 2be75662c150
    Removing intermediate container 2be75662c150
    ---> 458e5c6f080c
    Successfully built 458e5c6f080c
    Successfully tagged getting-started:latest
    

    Eftersom du använder byggcachen bör den gå mycket snabbare.

Flerstegsversioner

Flerstegsversioner är ett otroligt kraftfullt verktyg som hjälper dig att använda flera steg för att skapa en avbildning. Det finns flera fördelar för dem:

  • Separera beroenden för byggtid från beroenden för körtid
  • Minska den totala avbildningsstorleken genom att endast skicka det som din app behöver köra

Det här avsnittet innehåller korta exempel.

Maven/Tomcat-exempel

När du skapar Java-baserade program behövs en JDK för att kompilera källkoden till Java-bytekod. JDK:t behövs inte i produktion. Du kanske använder verktyg som Maven eller Gradle för att skapa appen. Dessa verktyg behövs inte heller i den slutliga avbildningen.

FROM maven AS build
WORKDIR /app
COPY . .
RUN mvn package

FROM tomcat
COPY --from=build /app/target/file.war /usr/local/tomcat/webapps 

I det här exemplet används en fas, build, för att utföra den faktiska Java-versionen med hjälp av Maven. Det andra steget, som börjar med "FROM tomcat", kopierar in filer från build-stadiet. Den sista avbildningen är bara den sista fasen som skapas, som kan åsidosättas med hjälp av parametern --target.

React-exempel

När du skapar React-program behöver du en Node-miljö för att kompilera JavaScript-koden, Sass-formatmallarna med mera till statisk HTML, JavaScript och CSS. Om du inte gör rendering på serversidan behöver du inte ens en Node-miljö för produktionsversionen.

FROM node:lts-alpine AS build
WORKDIR /app
COPY package* yarn.lock ./
RUN yarn install
COPY public ./public
COPY src ./src
RUN yarn run build

FROM nginx:alpine
COPY --from=build /app/build /usr/share/nginx/html

I det här exemplet används en node:lts-alpine-avbildning för att utföra bygget, vilket maximerar cachelagringen av lager, och utdata kopieras sedan till en nginx--behållare.

Rensa resurser

Behåll allt du har gjort hittills för att fortsätta den här serien med självstudier.

Nästa steg

Du har lärt dig om alternativ för att spara data för containerappar.

Vad vill du göra härnäst?