Igaüks, kes arendab veebirakendusi ja üritab neid oma haldamata serverites käitada, on teadlik oma rakenduse juurutamise ja tulevaste värskenduste pakkimisega seotud tüütust protsessist. Platvormi kui teenuse (PaaS) pakkujad on lihtsustanud veebirakenduste juurutamist, ilma et peaks läbima üksikute serverite ettevalmistamise ja konfigureerimise protsessi, vastutasuks kulude väikese kasvu ja paindlikkuse vähenemise eest. PaaS on võib-olla asja lihtsustanud, kuid mõnikord on meil siiski vaja või tahame rakendusi juurutada omaenda haldamata serverites. Selle veebirakenduste serverisse juurutamise protsessi automatiseerimine võib esialgu kõlada tohutult, kuid tegelikult võib lihtsa tööriista väljatöötamine selle automatiseerimiseks olla lihtsam kui arvate. Kui lihtne on selle tööriista juurutamine, sõltub palju sellest, kui lihtsad teie vajadused on, kuid seda pole kindlasti keeruline saavutada ja see võib tõenäoliselt aidata säästa palju aega ja vaeva, tehes tüütuid korduvaid veebirakendusi kasutuselevõtt.
kuidas määrata tarkvaratoote hinda
Palju arendajad on välja mõelnud oma viisid oma veebirakenduste juurutusprotsesside automatiseerimiseks. Kuna veebirakenduste juurutamine sõltub palju kasutatava tehnoloogia virnast, erinevad need automaatikalahendused üksteisest. Näiteks toimingud, mis on seotud automaatselt PHP veebisaidi juurutamine on erinev Node.js veebirakenduse juurutamine . On ka muid lahendusi, näiteks Dokku , mis on üsna üldised ja need asjad (nn buildpackid) töötavad hästi koos laiema tehnoloogiakogumiga.
Selles õpetuses heidame pilgu lihtsa tööriista taga olevatele ideedele, mille saate veebirakenduste juurutamise automatiseerimiseks GitHubi veebihookide, pakettide ja Procfileesi abil automatiseerida. Selles artiklis uuritava prototüüpprogrammi lähtekood on saadaval GitHubis .
Veebirakenduse juurutamise automatiseerimiseks kirjutame lihtsa Go programmi. Kui te pole Go-ga tuttav, ärge kartke kaasa minna, kuna kogu selles artiklis kasutatud koodikonstruktsioonid on üsna lihtsad ja neid peaks olema lihtne mõista. Kui soovite, võite tõenäoliselt kogu programmi oma valitud keelde portida üsna lihtsalt.
Enne alustamist veenduge, et teie jaotisse Go oleks installitud. Go installimiseks võite järgida ametlikes dokumentides kirjeldatud toimingud .
Järgmisena saate selle tööriista lähtekoodi alla laadida kloonides GitHubi hoidla . See peaks hõlbustama teie jälgimist, kuna selle artikli koodilõigud on varustatud vastavate failinimedega. Kui soovite, saate proovi kohe.
Go jaoks selle programmi jaoks on üks suur eelis see, et saame selle üles ehitada nii, et väliseid sõltuvusi oleks minimaalselt. Meie puhul peame selle programmi käivitamiseks serveris lihtsalt tagama, et meil on Git ja Bash installitud. Kuna Go programmid on kokku pandud staatiliselt lingitud kahendfailidesse, saate programmi oma arvutisse kompileerida, serverisse üles laadida ja peaaegu ilma pingutuseta käivitada. Enamiku teiste tänapäevaste populaarsete keelte jaoks vajaks see teie juurutusautomaadi käitamiseks serverisse mõnda mammut-käituskeskkonda või tõlki. Mine programmid, kui need on õigesti tehtud, võivad protsessori ja RAM - mida soovite sellistest programmidest.
GitHubi veebihookide abil on võimalik oma GitHubi hoidla konfigureerida nii, et see emiteeriks sündmusi iga kord, kui hoidlas midagi muutub või mõni kasutaja hostihoidlas konkreetseid toiminguid teeb. See võimaldab kasutajatel neid sündmusi tellida ja saada URL-i kutsete kaudu teada teie hoidla ümbruses toimuvatest erinevatest sündmustest.
Veebikonksu loomine on väga lihtne:
GitHub pakub ulatuslik dokumentatsioon veebihookide kohta ja kuidas need täpselt toimivad, milline teave edastatakse kasulikus koormuses vastuseks erinevatele sündmustele jne. Selle artikli eesmärgil oleme eriti huvitatud “Push” sündmus mis eraldub iga kord, kui keegi suvalisse hoidla harusse trügib.
Ehitised on tänapäeval üsna tavalised. Paljude PaaS-i pakkujate poolt kasutatavad paketid võimaldavad teil enne rakenduse juurutamist määrata, kuidas pinu konfigureeritakse. Veebirakenduse jaoks pakkepakettide kirjutamine on tõesti lihtne, kuid enamasti leiab kiire veebiotsing teile buildpacki, mida saate oma veebirakenduse jaoks ilma muudatusteta kasutada.
Kui olete rakenduse PaaS-i juurutanud nagu Heroku, võite juba teada, millised on paketid ja kust neid leida. Herokul on mõned kõikehõlmavad ehituskomplektide struktuuri käsitlev dokumentatsioon ja a loetelu mõnest hästi ehitatud populaarsest ehituskomplektist .
Meie automaatikaprogramm kasutab rakenduse ettevalmistamiseks enne käivitamist kompileerimisskripti. Näiteks sõelub Heroku loodud Node.js-fail faili package.json, laadib alla Node.js-i sobiva versiooni ja laadib alla rakenduse NPM-sõltuvused. Väärib märkimist, et asjade lihtsuse huvides ei ole meil prototüüpiprogrammis tugevat tugipakette. Praegu eeldame, et buildpacki skriptid on kirjutatud Bashiga käitamiseks ja et need töötavad värske Ubuntu installiga, nagu see on. Vajadusel saate seda tulevikus hõlpsalt laiendada esoteerilisemate vajaduste rahuldamiseks.
Procfile-failid on lihtsad tekstifailid, mis võimaldavad teil määratleda teie protsessis erinevat tüüpi protsessid. Enamiku lihtsate rakenduste jaoks oleks ideaalis üks veebiprotsess, mis oleks protsess, mis haldab HTTP-päringuid.
Procfile'i kirjutamine on lihtne. Määratlege üks protsessi tüüp rea kohta, tippides selle nime, millele järgneb koolon, millele järgneb käsu, mis protsessi sünnitab:
:
Näiteks kui töötate Node.js-põhise veebirakendusega, täidate veebiserveri käivitamiseks käsu „sõlm index.js”. Võite lihtsalt luua koodi baaskataloogis Procfile'i ja nimetada sellele 'Procfile' järgmiselt:
web: node index.js
Nõuame, et rakendused määraksid Procfilesis protsessitüübid, et saaksime neid pärast koodi sisestamist automaatselt käivitada.
Oma programmis peame lisama HTTP-serveri, mis võimaldab meil vastu võtta GitHubi sissetulevaid POST-taotlusi. Nende GitHubi taotluste käsitlemiseks peame eraldama URL-i tee. Funktsioon, mis neid sissetulevaid koormusi haldab, näeb välja umbes selline:
// hook.go type HookOptions struct { App *App Secret string } func NewHookHandler(o *HookOptions) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { evName := r.Header.Get('X-Github-Event') if evName != 'push' { log.Printf('Ignoring '%s' event', evName) return } body, err := ioutil.ReadAll(r.Body) if err != nil { http.Error(w, 'Internal Server Error', http.StatusInternalServerError) return } if o.Secret != '' { ok := false for _, sig := range strings.Fields(r.Header.Get('X-Hub-Signature')) { if !strings.HasPrefix(sig, 'sha1=') { continue } sig = strings.TrimPrefix(sig, 'sha1=') mac := hmac.New(sha1.New, []byte(o.Secret)) mac.Write(body) if sig == hex.EncodeToString(mac.Sum(nil)) { ok = true break } } if !ok { log.Printf('Ignoring '%s' event with incorrect signature', evName) return } } ev := github.PushEvent{} err = json.Unmarshal(body, &ev) if err != nil { log.Printf('Ignoring '%s' event with invalid payload', evName) http.Error(w, 'Bad Request', http.StatusBadRequest) return } if ev.Repo.FullName == nil || *ev.Repo.FullName != o.App.Repo { log.Printf('Ignoring '%s' event with incorrect repository name', evName) http.Error(w, 'Bad Request', http.StatusBadRequest) return } log.Printf('Handling '%s' event for %s', evName, o.App.Repo) err = o.App.Update() if err != nil { return } }) }
Alustame selle kasuliku koormuse genereerinud sündmuse tüübi kontrollimisega. Kuna meid huvitab ainult tõukesündmus, võime kõiki muid sündmusi ignoreerida. Isegi kui konfigureerite veebihaagi nii, et see väljastaks ainult tõukesündmusi, on ikkagi olemas vähemalt üks muud tüüpi sündmus, mille võite oodata oma konksu lõpp-punktis: „ping”. Selle sündmuse eesmärk on teha kindlaks, kas veebihook on GitHubis edukalt konfigureeritud.
Järgmisena loeme läbi kogu sissetuleva päringu keha, arvutame selle HMAC-SHA1 sama saladuse abil, mida kasutame oma veebihooki seadistamiseks, ja määrame sissetuleva kasuliku koormuse kehtivuse, võrreldes seda päise päises sisalduva allkirjaga taotlus. Kui saladus pole seadistatud, eirame oma programmis seda valideerimisetappi. Vahemärkusena võib öelda, et see ei pruugi olla mõistlik mõte lugeda kogu keha, ilma et oleks vähemalt mingisugune ülempiir, kui palju andmeid me siin tahame käsitleda, kuid olgem asjad lihtsad, et keskenduda kriitilistele aspektidele selle tööriista.
Seejärel kasutame Go jaoks GitHubi kliendikogu sissetuleva kasuliku koormuse malaarseks muutmiseks. Kuna me teame, et see on tõukesündmus, saame seda kasutada PushEventi struktuur . Seejärel kasutame standardset jsoni kodeerimisraamatukogu, et tühistada kasulikku koormust struktuuri eksemplaris. Teostame paar mõistlikkuse kontrolli ja kui kõik on korras, siis kutsume üles funktsiooni, mis alustab meie rakenduse värskendamist.
Kui oleme oma veebihooki lõpp-punktis sündmusteate kätte saanud, saame hakata oma rakendust värskendama. Selles artiklis heidame pilgu selle mehhanismi üsna lihtsale rakendamisele ja kindlasti on arenguruumi. Kuid see peaks olema midagi, mis aitab meil alustada mõnda põhilist automatiseeritud juurutusprotsessi.
See protsess algab lihtsa kontrolliga, et teha kindlaks, kas see on esimene kord, kui proovime rakendust juurutada. Teeme seda, kontrollides, kas kohalik hoidla kataloog on olemas. Kui seda pole, lähtestame kõigepealt oma kohaliku hoidla:
// app.go func (a *App) initRepo() error { log.Print('Initializing repository') err := os.MkdirAll(a.repoDir, 0755) // Check err cmd := exec.Command('git', '--git-dir='+a.repoDir, 'init') cmd.Stderr = os.Stderr err = cmd.Run() // Check err cmd = exec.Command('git', '--git-dir='+a.repoDir, 'remote', 'add', 'origin', fmt.Sprintf(' [email protected] :%s.git', a.Repo)) cmd.Stderr = os.Stderr err = cmd.Run() // Check err return nil }
Seda rakenduse struktuuri meetodit saab kasutada kohaliku hoidla initsialiseerimiseks ja selle mehhanismid on äärmiselt lihtsad:
Kui meil on initsialiseeritud hoidla, peaks muudatuste toomine olema lihtne.
Muudatuste toomiseks kaughoidlast peame lihtsalt kutsuma ühe käsu:
// app.go func (a *App) fetchChanges() error { log.Print('Fetching changes') cmd := exec.Command('git', '--git-dir='+a.repoDir, 'fetch', '-f', 'origin', 'master:master') cmd.Stderr = os.Stderr return cmd.Run() }
Sel viisil oma kohaliku andmehoidla jaoks „gitfetchi“ tehes saame vältida probleeme, kus Git ei saa teatud stsenaariumides kiiresti edasi liikuda. Mitte nii, et sunnitud tõmbed peaksid midagi, millele peaksite tuginema, kuid kui peate oma kaughoidlasse jõudma, peab see seda armu.
Kuna kasutame juurutatavate rakenduste kompileerimiseks buildpackide skripte, on meie ülesanne siin suhteliselt lihtne:
// app.go func (a *App) compileApp() error { log.Print('Compiling application') _, err := os.Stat(a.appDir) if !os.IsNotExist(err) { err = os.RemoveAll(a.appDir) // Check err } err = os.MkdirAll(a.appDir, 0755) // Check err cmd := exec.Command('git', '--git-dir='+a.repoDir, '--work-tree='+a.appDir, 'checkout', '-f', 'master') cmd.Dir = a.appDir cmd.Stderr = os.Stderr err = cmd.Run() // Check err buildpackDir, err := filepath.Abs('buildpack') // Check err cmd = exec.Command('bash', filepath.Join(buildpackDir, 'bin', 'detect'), a.appDir) cmd.Dir = buildpackDir cmd.Stderr = os.Stderr err = cmd.Run() // Check err cacheDir, err := filepath.Abs('cache') // Check err err = os.MkdirAll(cacheDir, 0755) // Check err cmd = exec.Command('bash', filepath.Join(buildpackDir, 'bin', 'compile'), a.appDir, cacheDir) cmd.Dir = a.appDir cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr return cmd.Run() }
Alustuseks eemaldame oma eelmise rakenduste kataloogi (kui see on olemas). Järgmisena loome uue ja kontrollime selle juurde haruharu sisu. Seejärel kasutame konfigureeritud buildpacki skripti „detekteeri“, et teha kindlaks, kas rakendus on midagi, millega hakkama saame. Seejärel loome vajadusel buildpacki kompileerimisprotsessi jaoks vahemälu. Kuna see kataloog püsib kogu järgu ajal, võib juhtuda, et me ei pea uut kataloogi looma, kuna see on juba olemas mõnest varasemast kompileerimisprotsessist. Siinkohal saame buildpackist välja kutsuda skripti “compile” ja lasta sellel enne käivitamist kõik rakenduse jaoks vajalikud asjad ette valmistada. Kui pakkepakette õigesti käitatakse, saavad nad varem puhverdatud ressursside vahemällu salvestamise ja taaskasutusega ise hakkama.
Selle automatiseeritud juurutusprotsessi juurutamisel peatame vanad protsessid enne kompileerimisprotsessi alustamist ja seejärel käivitame uued protsessid, kui kompileerimisfaas on lõpule jõudnud. Kuigi see muudab tööriista rakendamise lihtsaks, jätab see potentsiaalselt hämmastavaid viise automatiseeritud juurutusprotsessi täiustamiseks. Selle prototüübi paremaks muutmiseks võite tõenäoliselt alustada värskenduste ajal seisakuid nullist. Praegu jätkame lihtsama lähenemisviisiga:
// app.go func (a *App) stopProcs() error { log.Print('.. stopping processes') for _, n := range a.nodes { err := n.Stop() if err != nil { return err } } return nil } func (a *App) startProcs() error { log.Print('Starting processes') err := a.readProcfile() if err != nil { return err } for _, n := range a.nodes { err = n.Start() if err != nil { return err } } return nil }
Meie prototüübis peatame ja alustame erinevaid protsesse itereerides sõlmede massiivi kohal, kus iga sõlm on protsess, mis vastab rakenduse ühele eksemplarile (mis on konfigureeritud enne selle tööriista käivitamist serveris). Meie tööriistas jälgime iga sõlme protsessi hetkeseisundit. Samuti haldame nende jaoks üksikuid logifaile. Enne kõigi sõlmede käivitamist määratakse igale unikaalne port, mis algab antud pordi numbrist:
// node.go func NewNode(app *App, name string, no int, port int) (*Node, error) { logFile, err := os.OpenFile(filepath.Join(app.logsDir, fmt.Sprintf('%s.%d.txt', name, no)), os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) if err != nil { return nil, err } n := &Node{ App: app, Name: name, No: no, Port: port, stateCh: make(chan NextState), logFile: logFile, } go func() { for { next := <-n.stateCh if n.State == next.State { if next.doneCh != nil { close(next.doneCh) } continue } switch next.State { case StateUp: log.Printf('Starting process %s.%d', n.Name, n.No) cmd := exec.Command('bash', '-c', 'for f in .profile.d/*; do source $f; done; '+n.Cmd) cmd.Env = append(cmd.Env, fmt.Sprintf('HOME=%s', n.App.appDir)) cmd.Env = append(cmd.Env, fmt.Sprintf('PORT=%d', n.Port)) cmd.Env = append(cmd.Env, n.App.Env...) cmd.Dir = n.App.appDir cmd.Stdout = n.logFile cmd.Stderr = n.logFile err := cmd.Start() if err != nil { log.Printf('Process %s.%d exited', n.Name, n.No) n.State = StateUp } else { n.Process = cmd.Process n.State = StateUp } if next.doneCh != nil { close(next.doneCh) } go func() { err := cmd.Wait() if err != nil { log.Printf('Process %s.%d exited', n.Name, n.No) n.stateCh <- NextState{ State: StateDown, } } }() case StateDown: log.Printf('Stopping process %s.%d', n.Name, n.No) if n.Process != nil { n.Process.Kill() n.Process = nil } n.State = StateDown if next.doneCh != nil { close(next.doneCh) } } } }() return n, nil } func (n *Node) Start() error { n.stateCh <- NextState{ State: StateUp, } return nil } func (n *Node) Stop() error { doneCh := make(chan int) n.stateCh <- NextState{ State: StateDown, doneCh: doneCh, } <-doneCh return nil }
Esmapilgul võib see tunduda veidi keerulisem kui see, mida oleme seni teinud. Et asjad oleksid hõlpsasti mõistetavad, jagagem ülaltoodud kood neljaks osaks. Kaks esimest asuvad funktsioonis „NewNode”. Kui see kutsutakse, täidab see „Node” struktuuri eksemplari ja sünnitab Go-rutiini, mis aitab sellele sõlmele vastavat protsessi käivitada ja peatada. Kaks ülejäänud on kaks sõlme struktureerimise meetodit: „Start“ ja „Stop“. Protsessi alustatakse või peatatakse, edastades konkreetse kanali kaudu sõnumi, mida see sõlmeülene Go-rutiin jälgib. Protsessi alustamiseks võite edastada sõnumi või selle peatamiseks teise sõnumi. Kuna protsessi alustamise või peatamise tegelikud sammud toimuvad ühe Go-rutiiniga, pole mingit võimalust võistlustingimuste saamiseks.
Go rutiin alustab lõpmatut tsüklit, kus ta ootab „stateCh” kanali kaudu sõnumit. Kui sellele kanalile edastatud sõnum nõuab sõlmilt protsessi alustamist („case StateUp” sees), kasutab see käsu Bashi. Seejuures konfigureerib see käsu kasutama kasutaja määratud keskkonnamuutujaid. Samuti suunab see standardväljundi- ja tõrkevood eelnevalt määratletud logifaili.
Teisest küljest tapab see protsessi peatamiseks (juhtumi StateDown sees) selle lihtsalt ära. See on koht, kus võiksite tõenäoliselt olla loov ja selle asemel, et protsess tappa, saatke see kohe SIGTERM ja oodake mõni sekund enne selle tapmist, andes protsessile võimaluse graatsiliselt peatuda.
'Start' ja 'Stop' meetodid muudavad kanalile vastava teate edastamise lihtsaks. Erinevalt meetodist “Start” ootab “Stop” meetod enne tagasipöördumist tegelikult protsesside tapmist. „Start” edastab kanalile lihtsalt teate, et protsess käivitatakse, ja naaseb.
Lõpuks, kõik, mida me peame tegema, on juhtme kõik üles lülitada programmi põhifunktsiooni raames. Siit laadime ja sõelume konfiguratsioonifaili, värskendame buildpacki, proovime oma rakendust üks kord värskendada ja käivitame veebiserveri, et kuulata GitHubist saabuvaid 'push' sündmuste kasulikke koormusi:
// main.go func main() { cfg, err := toml.LoadFile('config.tml') catch(err) url, ok := cfg.Get('buildpack.url').(string) if !ok { log.Fatal('buildpack.url not defined') } err = UpdateBuildpack(url) catch(err) // Read configuration options into variables repo (string), env ([]string) and procs (map[string]int) // ... app, err := NewApp(repo, env, procs) catch(err) err = app.Update() catch(err) secret, _ := cfg.Get('hook.secret').(string) http.Handle('/hook', NewHookHandler(&HookOptions{ App: app, Secret: secret, })) addr, ok := cfg.Get('core.addr').(string) if !ok { log.Fatal('core.addr not defined') } err = http.ListenAndServe(addr, nil) catch(err) }
Kuna me eeldame, et pakkepaketid peavad olema lihtsad Giti hoidlad, tuleb 'UpdateBuildpack' (rakendatud 2007) buildpack.go ) teostab lihtsalt komplekti kohaliku koopia värskendamiseks 'git klooni' ja 'git pull' koos hoidla URL-iga.
Juhul kui te pole klooninud hoidla veel, saate seda teha kohe. Kui teil on installitud Go levitamine, peaks olema võimalik programm kohe kompileerida.
mkdir hopper cd hopper export GOPATH=`pwd` go get github.com/hjr265/toptal-hopper go install github.com/hjr265/toptal-hopper
Selle käskude jadaga luuakse kataloog nimega punker, määratakse see nimeks GOPATH, tõmmatakse kood koos vajalike Go teekidega GitHubist ja kompileeritakse programm binaarsesse kausta, mille leiate kataloogist $ GOPATH / bin. Enne kui saame seda serveris kasutada, peame selle testimiseks looma lihtsa veebirakenduse. Mugavuse huvides olen loonud lihtsa “Tere, maailm” laadse Node.js veebirakenduse ja selle üles laadinud veel üks GitHubi hoidla mida saate selle testi jaoks kahvli abil uuesti kasutada. Järgmisena peame kompileeritud binaarkaardi serverisse üles laadima ja looma konfiguratsioonifaili samasse kataloogi:
# config.tml [core] addr = ':26590' [buildpack] url = 'https://github.com/heroku/heroku-buildpack-nodejs.git' [app] repo = 'hjr265/hopper-hello.js' [app.env] GREETING = 'Hello' [app.procs] web = 1 [hook] secret = ''
Meie konfiguratsioonifaili esimene valik „core.addr“ on see, mis võimaldab meil konfigureerida meie programmi sisemise veebiserveri HTTP-porti. Ülaltoodud näites oleme määranud selle väärtuseks “: 26590”, mis paneb programmi kuulama “push” sündmuste kasulikke koormusi aadressil “http: // {host}: 26590 / hook”. GitHubi veebihaagi seadistamisel asendage lihtsalt „{host}” domeeninime või IP-aadressiga, mis osutab teie serverile. Veenduge, et port oleks avatud juhul, kui kasutate mingisugust tulemüüri.
Järgmisena valime buildpacki, määrates selle Giti URL-i. Siin me kasutame Heroku’s Node.js buildpack .
Jaotises „rakendus” määrasime „repo” teie rakenduse koodi majutava GitHubi hoidla täisnimeks. Kuna ma majutan näiderakendust aadressil “https://github.com/hjr265/hopper-hello.js”, on hoidla täielik nimi “hjr265 / hopper-hello.js”.
Seejärel määrasime rakendusele mõned keskkonnamuutujad ja nende arvu protsesside tüüp me vajame. Ja lõpuks valime saladuse, et saaksime kontrollida sissetulevate „tõukesündmuste“ kasulikke koormusi.
Nüüd saame oma automaatikaprogrammi käivitada serveris. Kui kõik on õigesti konfigureeritud (kaasa arvatud SSH-võtmete juurutamine, nii et hoidla on serverist juurdepääsetav), peaks programm tooma koodi, ehitama paketi abil keskkonna ette ja käivitama rakenduse. Nüüd peame vaid seadistama veebihook GitHubi hoidlasse tõukesündmuste väljastamiseks ja suunama sellele aadressile “http: // {host}: 26590 / hook”. Asendage „{host}” kindlasti domeeni nime või IP-aadressiga, mis osutab teie serverile.
Lõpuks test see, tehke näidisrakenduses mõned muudatused ja lükake need GitHubi. Märkate, et automatiseerimistööriist hakkab kohe tegutsema ja värskendab serveris asuvat hoidlat, kompileerib rakenduse ja taaskäivitab selle.
Enamiku oma kogemuste põhjal võime öelda, et see on midagi üsna kasulikku. Selles artiklis koostatud prototüüprakendus ei pruugi olla midagi, mida soovite sellises tootmissüsteemis kasutada. Arenguruumi on palju. Sellisel tööriistal peaks olema parem veakäsitlus, see toetab graatsilisi väljalülitamisi / taaskäivitusi ning protsesside ohjeldamiseks võiksite kasutada midagi näiteks Dockerit, mitte neid otse käivitada. Võib-olla on targem välja mõelda, mida täpselt oma konkreetse juhtumi jaoks vaja on, ja mõelda selle jaoks välja automaatikaprogramm. Või võib-olla kasutada mõnda muud, palju stabiilsemat, aja jooksul testitud lahendust, mis on saadaval kogu Internetis. Kuid kui soovite midagi väga kohandatud kasutusele võtta, loodan, et see artikkel aitab teil seda teha ja näitab, kui palju aega ja vaeva võiksite pikemas perspektiivis säästa veebirakenduste juurutamise protsessi automatiseerimisega.
Seotud: Tõhustatud Git Flow selgitatud