Keskitaso
Hyvä tuntemus Docker-ohjelmasta on tarpeen
Monivaiheiset käännökset
Monivaiheisten käännösten idea on helpottaa pienempien konttikuvien rakentamista mahdollistamalla välivaiheiden rakennetiedostojen poisjättäminen lopputuotteesta.
Pienemmät konttikuvat vievät vähemmän tilaa levyllä, mikä tarkoittaa, että niiden lataamiseen ja käyttöönottoon kuluu vähemmän aikaa. Ohjelmiston kokoamisen aikana on tavallista tarvita kääntäjä, useita kirjasto-riippuvuuksia ja väliaikaisia objekteja, joita ei tarvita ohjelman suorittamisen aikana. Monivaiheiset käännökset mahdollistavat kahden tai useamman docker-käännösvaiheen määrittämisen samassa Dockerfile
-tiedostossa. Ne suoritetaan peräkkäin, ja jokainen "vaihe" voi kopioida tiedostoja edellisistä vaiheista. Tällä tavalla voimme helposti ja samassa rakennusprosessissa kääntää ohjelmiston ja säilyttää sitten vain ne tiedostot, joita oikeasti tarvitsemme suorittamiseen.
Käyttö
Luo ensin uusi Go-projekti tai käytä olemassa olevaa Go-alustettua projektia.
- Esimerkkinä uuden Go-projektin alustaminen:
Katso tämä Dockerfile
:
Dockerfile
:
FROM golang:1.18.3-stretch as builder
RUN mkdir -p /go/src/server
WORKDIR /go/src/server
COPY go.mod go.sum ./
RUN go mod download && go mod verify
COPY . .
RUN CGO_ENABLED=0 go build server.go
FROM alpine:edge
RUN mkdir /app
COPY --from=builder /go/src/server/server /app/server
CMD ["/app/server"]
ja tämä koodi (golang):
server.go
:
package main
import (
"fmt"
"strings"
"net/http"
"github.com/pborman/uuid"
)
func main() {
http.HandleFunc("/", func (w http.ResponseWriter, r *http.Request) {
uuidWithHyphen := uuid.NewRandom()
uuid := strings.Replace(uuidWithHyphen.String(), "-", "", -1)
fmt.Fprintf(w, "Welcome to my website!\n")
fmt.Fprintf(w, uuid)
})
fmt.Print("Starting server in port 8080...\n")
http.ListenAndServe(":8080", nil)
}
Suorita sitten komento go mod tidy
, mikä lataa kaikki riippuvuudet, joita lähdetiedostosi vaativat, ja päivittää go.mod
-tiedoston näillä riippuvuuksilla. Tässä tapauksessa se lataa github.com/pborman/uuid
.
Dockerfile
voidaan jakaa kahteen osaan (tai vaiheeseen), joista kumpikin alkaa FROM
-komennolla:
FROM golang:1.18.3-stretch as builder
, käyttää virallista golang-kuvaa, joka sisältää kaiken mitä koodin kääntämiseen tarvitaan. Sitä merkitäänbuilder
:ksi. Kopioimmego.mod
jago.sum
ja lataamme pakettiriippuvuudet "työhakemistoon". Kopioimme koko "työhakemistoon", mukaan lukien koodi komennollaCOPY . .
, ja lopuksi käännämme koodin komennollaRUN CGO_ENABLED=0 go build server.go
.FROM alpine:edge
, käyttää vähimmäisjakoaalpine
. RivilläCOPY --from=builder /go/src/server/server /app/server
käännetty ohjelma ja vain käännetty ohjelma kopioidaan edellisestä vaiheesta (build
).
Testataksesi tätä käännösprosessia, laita molemmat tiedostot samaan hakemistoon ja nimeä ne Dockerfile
ja server.go
. Suorita sitten komento:
Tämä tuottaa kuvan nimeltä go-server:latest
. Tarkista kuvan koko suorittamalla:
$ docker images go-server
REPOSITORY TAG IMAGE ID CREATED SIZE
go-server latest 173c922261a3 16 minutes ago 12.1MB
sen tulisi olla noin 12MB, josta yli puolet (~7MB) on käännetty koodi.
Jos lataat kuvan golang:1.18.3-stretch
(jota käytimme koodin rakentamiseen) ja tarkistat sen koon, näet, että se on noin 890 MB
.
$ docker images golang:1.18.3-stretch
REPOSITORY TAG IMAGE ID CREATED SIZE
golang 1.18.3-stretch 6ee1deda35bd 12 days ago 890 MB
Tämä pieni kuva (go-server:latest
) on tietenkin mahdollista saavuttaa muillakin menetelmillä. Voit kääntää koodin dockerin ulkopuolella ja kopioida sen sitten alpine
-kuvaan. Voit liittää koodihakemiston käännöskuvaan, kääntää sen ja sitten taas kopioida käännetyn tuotteen alpine
-kuvaan. Mutta mikään näistä menetelmistä ei ole niin helppo ja tiivis kuin tämä.
Käyttö Rahtissa
Testataksesi tämän Rahtissa, sinun tarvitsee vain kirjautua sisään Rahtiin, valita oikea projekti ja suorittaa:
HUOMAA: Koodin on oltava git-repossa ja Rahtin on pystyttävä kloonaamaan se.
Lopputulos on kuva nimeltä multi-stage-build
, joka tallennetaan valitsemasi projektin Rahti-sisäiseen rekisteriin. Tätä kuvaa voidaan käyttää Rahti-ympäristössä käyttämällä kuva stream -vaihtoehtoa kuvaa käynnistettäessä.