Domanda:
Usare Git per la distribuzione è una cattiva pratica?
Septagram
2013-11-14 13:37:19 UTC
view on stackexchange narkive permalink

Tendo a usare Git per distribuire il codice di produzione al server web. Ciò di solito significa che da qualche parte un repository Git principale è ospitato da qualche parte accessibile tramite ssh e il server di produzione serve quel repository clonato, limitando l'accesso a .git / e .gitignore . Quando ho bisogno di aggiornarlo, eseguo semplicemente il pull nel repository del server dal repository principale. Questo ha diversi vantaggi:

  1. Se qualcosa va storto, è estremamente facile tornare a una revisione precedente, semplice come controllarla.
  2. Se uno dei sorgenti i file di codice vengono modificati, controllandolo facilmente come git status , e se il repository del server è stato modificato, sarà ovvio la prossima volta che proverò a eseguire il pull.
  3. significa che esiste un'altra copia del codice sorgente, nel caso in cui accadano cose brutte.
  4. L'aggiornamento e il rollback sono facili e molto veloci.

Questo potrebbe avere alcuni problemi però:

  • Se per qualsiasi motivo il server web decide che dovrebbe servire la directory .git / , tutto il codice sorgente che c'era e diventa leggibile per tutti . Storicamente, c'erano alcune (grandi) aziende che hanno commesso questo errore. Sto usando il file .htaccess per limitare l'accesso, quindi non credo che al momento ci sia alcun pericolo. Forse è necessario un test di integrazione che assicuri che nessuno possa leggere la cartella .git / ?

  • Tutti quelli che accidentalmente ottengono l'accesso in lettura alla cartella ottengono anche accesso a ogni revisione passata del codice sorgente che esisteva. Ma non dovrebbe essere molto peggio che avere accesso alla versione attuale. Dopotutto, quelle revisioni sono obsolete per definizione.

Detto questo, credo che usare Git per distribuire il codice in produzione sia ragionevolmente sicuro e molto più facile di rsync , ftp o semplicemente copiandolo. Cosa ne pensi?

La pratica standard non prevede che il tuo repository git esista a un livello superiore dalla tua cartella htdoc in modo che non sia pubblicato accidentalmente?
Questo è un buon suggerimento, e lo sto facendo per un ultimo progetto personale. Ma su un altro progetto il repository dei miei clienti è organizzato in modo diverso (con htdoc che è alla radice del repository), quindi la domanda è ancora valida.
Come si garantisce che le modifiche apportate dopo la distribuzione per il test non vengano distribuite alla produzione?
Finora non ho avuto la possibilità di lavorare in un team con server di test dedicato e QA (probabilmente cattivo). Provo accuratamente sulla macchina di sviluppo e distribuisco nuove funzionalità solo in iterazioni specifiche. Quindi se è necessario correggere un bug fino alla successiva iterazione, vengono eseguite su un ramo separato. Ad esempio, viene rilasciata la versione 0.6, i lavori sono iniziati sulla 0.7. Bug trovato su 0.6, correzione applicata in un ramo 0.6 e fusa in un ramo principale. La produzione quindi tira il ramo 0.6. E fino al rilascio della 0.7, tutte le correzioni vanno prima nel ramo 0.6. A volte (non sempre) creo un ramo separato per la versione di produzione successiva
In un ambiente aziendale tradizionale questa pratica sarebbe trattata con disprezzo. Tuttavia, come dici tu, ci sono pochi problemi tecnici con esso. In effetti, l'approccio più generale di implementazione rapida e spesso sta guadagnando terreno. Ha anche una sua parola d'ordine: distribuzione continua
Questa è * davvero * una domanda di sicurezza?
Puoi sempre utilizzare una suite di Package Manager come Gradle, Maven, Etc per distribuire i tuoi file nella cartella HTDOCS in modo da ignorare in modo specifico ./git, ecc. Aggiorna il tuo GIT sul server in una cartella separata, quindi esegui PM per distribuirlonella posizione corretta.È per questo che esistono.
Sono sorpreso che il problema di sicurezza che ti preoccupa sia la cartella .git, mentre in realtà avrei più paura che tale processo significhi che le tue credenziali git siano archiviate sul server web e quindi, se esiste una violazione nel tuo sito web,quindi chiunque può accedere al repository Git (speriamo che queste credenziali siano di sola lettura)
Sette risposte:
user10211
2013-11-14 18:21:13 UTC
view on stackexchange narkive permalink

Vorrei arrivare al punto di considerare l'utilizzo di git per la distribuzione ottima pratica .

I due problemi che hai elencato hanno poco a che fare con l'utilizzo di git per la distribuzione stessa. Sostituisci .git / per il file di configurazione contenente le password del database e hai lo stesso problema. Se ho accesso in lettura alla tua radice web, ho accesso in lettura a tutto ciò che è contenuto in esso. Questo è un problema di protezione avanzata del server che devi discutere con l'amministrazione del sistema.

git offre alcuni vantaggi molto interessanti quando si tratta di sicurezza.

  1. Puoi applicare un sistema per la distribuzione in produzione. Configurerei anche un hook post-receive per distribuire automaticamente alla produzione ogni volta che viene effettuato un commit su master . Presumo, ovviamente, un flusso di lavoro simile a git flow.

  2. git semplifica estremamente il rollback del codice distribuito in produzione a una versione precedente se viene sollevato un problema di sicurezza. Questo può essere utile per bloccare l'accesso a falle di sicurezza mission-critical che è necessario tempo per risolvere correttamente.

  3. Puoi applicare un sistema in cui i tuoi sviluppatori devono firmare i commit che fanno. Questo può aiutare a rintracciare chi ha distribuito cosa in produzione se viene rilevata una falla di sicurezza intenzionale.

Bella risposta, non vedo l'ora di usare git nei miei server di produzione! Tuttavia, sono riluttante a utilizzare la spinta automatica come suggerito da te (e molti altri che ho letto). Il push automatico può cambiare il tuo server di produzione quando non lo desideri e potresti accidentalmente lasciare il tuo server offline. Forse mi manca qualcosa e le cose complicano eccessivamente, ma preferisco l'approccio paranoico di ssh'ing nel server di produzione, fare un `git fetch origin master`, quindi` git diff master origin / master`. Solo allora dovrei fare `git merge origin / master --ff-only`. Hai qualche idea su questo argomento?
@pedromanoel Mi iscrivo alla scuola di pensiero dove tutto ciò che spingi per padroneggiarlo dovrebbe essere pronto per la produzione, quindi non dovrebbe essere davvero un problema. Anche quello che stai suggerendo funziona.
Il nostro ramo principale si impegna a distribuire al server Web Dev. Abbiamo un ramo QA, Staging e Produzione che mappano i rispettivi ambienti. Quando vogliamo rilasciare in produzione, dobbiamo semplicemente unire il codice testato nel ramo di produzione. Questo ha funzionato bene per noi. Usiamo KUDU per questo. Non sono sicuro di quali altri strumenti siano disponibili.
@TerryChia Potete suggerire qualche tutorial / strumento per impostare i vostri hook post-ricezione per le distribuzioni automatiche? Usiamo Kudu ma ho trovato complicato configurare per siti non sicuri (abbiamo i nostri server IIS in sede).
Matt Surabian
2013-11-19 19:27:38 UTC
view on stackexchange narkive permalink

Non c'è niente di sbagliato nel distribuire da un repository git, infatti è una pratica abbastanza comune e, come dici tu, molto meno incline agli errori che copiare file su ftp o rsync.

Date le informazioni che hai fornito, prenderei nota dei seguenti punti:

  • Non limitarti a inserire l'ultimo master. La produzione dovrebbe essere distribuita da un tag di rilascio. Usa git flow o simile per ottenere un po 'più di processo intorno alla distribuzione del codice e alla creazione dei tag. Poiché i tag sono un riferimento immutabile al tuo codice in un dato momento, è più stabile che puntare a un ramo principale che potrebbe essere aggiornato da un commit errato.

  • Per quanto riguarda il servizio di. git directory questo non dovrebbe essere un grosso problema. Basta reindirizzare qualsiasi cosa con prefisso .git a un 404 in .htaccess.

  • La tua autenticazione git dovrebbe essere basata su chiave ssh, quindi nessuna password repo deve essere memorizzata sul server.

Evviva per i flussi di lavoro di distribuzione git!

siliconrockstar
2018-08-24 21:29:13 UTC
view on stackexchange narkive permalink

Non sono d'accordo con l'opinione popolare qui. Git è per il controllo della versione, non per la distribuzione / CI.

I metodi che le persone sostengono qui vanno bene per i piccoli progetti, ma in generale, non scalano molto bene.

... il che non vuol dire che non dovresti continuare a fare quello che stai facendo. Tieni solo presente, con il progredire della tua carriera, che i progetti su cui stai lavorando probabilmente supereranno un flusso di lavoro di distribuzione puramente basato su git.

Il principale cambiamento di paradigma è smettere di pensare alla distribuzione di filiali e inizia a pensare alla distribuzione dei risultati della compilazione e all'inserimento delle dipendenze dall'ambiente per disaccoppiare la tua infrastruttura dalla tua strategia di ramificazione.

Ad esempio, per utilizzare il paradigma sopra relativo alla "distribuzione dei file" e al rollback. Se stavi distribuendo file, potresti mantenere più versioni dell'applicazione sul server di produzione e, se devi eseguire il rollback, puoi indirizzare il tuo server web a una versione precedente ricollegando la radice web. Due comandi della shell, microsecondi di inattività, meno spazio per errori rispetto all'utilizzo di git.

Un altro esempio: hai il flusso di lavoro principale standard dev branch> staging branch> master, con un server per ciascuno. Hai delle cose pronte per andare in dev, ma alcune altre cose sullo staging non hanno superato il QA. Quindi è necessario eseguire alcune operazioni orribili: rimuovere i commit errati dallo stage, ridistribuire lo stadio e anche rimuovere o correggere i commit errati nello sviluppo e sperare che lo sviluppo e lo staging non finiscano per non essere sincronizzati.

Invece, cosa succede se si taglia un ramo di rilascio master, si uniscono le cose che sono pronte per entrare in quel ramo di rilascio e si crea il risultato, si avvia un server di test su AWS e si distribuisce il risultato su di esso, si esegue il controllo di qualità e si funziona test su quel server di staging temporaneo, quindi ha inviato lo stesso risultato al cluster di produzione e lo ha distribuito? Quindi disattiva la scatola di staging temporanea che hai attivato, unisci la versione in master e tagga master con un numero di versione.

Ovviamente questi sono esempi estremi. Di solito, non è così pulito, anche se vogliamo che lo sia: probabilmente è necessario eseguire alcuni processi di compilazione nell'ambiente di destinazione perché sono presenti modifiche al database che devono essere eseguite. E se hai mod di database non idempotenti tra le versioni, beh, il rollback non sarà così facile indipendentemente dal metodo che usi, perché dovrai eseguire il rollback del db (in generale, prova a distribuire il database idempotente modifiche, quindi rimuovere i bit di database obsoleti in una versione successiva, dopo essere sicuri che siano fuori dal flusso dell'applicazione).

Ad ogni modo, immagino che quello che sto cercando è che la mia risposta a "Usare git per la distribuzione è una cattiva pratica?" è, in generale, "Sì", nello stesso modo in cui l'uso delle ruote da allenamento è dannoso per la bicicletta. È un miglioramento rispetto a rompere ripetutamente il culo sul cemento, ma si spera che alla fine lo supererai.

Sono anche d'accordo con questo.Non penso necessariamente che sia un male, ma ci sono alcuni ulteriori elementi di preoccupazione. 1. Mette * tutto * in produzione 2. "git checkout" non è transazionale.Ciò significa che durante la distribuzione il sistema può trovarsi in uno stato incoerente durante la scrittura dei singoli file Come notato da @siliconrockstar, git è un sistema SCM, non un sistema di distribuzione.Risolvono due diversi problemi.
@siliconrickstar hai ulteriori letture o risorse su questo?Ho già utilizzato questo processo in passato, ma mi piacerebbe vedere alcune guide di best practice.Esempio, utilizzando Gitlab, la tua pipeline CI raggrupperebbe l'applicazione _intera_ in uno zip e la sincronizzerebbe in produzione?Dipendenze e tutto il resto (come vendor, node_modules, ecc.) O si risolverebbero sul server (presumo il primo, poiché hai quindi un'istantanea _intera_ dell'applicazione in una directory e il server prod non sta facendo alcun "lavoro"tranne uno scambio di collegamento simbolico)
@Chris Vorrei avere alcune risorse "autorevoli" per te, ma i dettagli effettivi variano drasticamente a seconda del progetto e dello stack.In questi giorni lavoro principalmente con Magento e anche il loro flusso di distribuzione "ufficiale" che utilizza Magento Cloud fa alcune cose strane che probabilmente non sono le migliori pratiche (viene subito in mente l'accoppiamento di rami e ambienti).In Magentoland, per quanto riguarda le dipendenze, l'attuale Magento utilizza compositore e npm, e IMO è generalmente sicuro lasciare che questi strumenti facciano le loro cose sulle destinazioni di distribuzione, invece di copiare tutto il fornitore / ogni distribuzione.
Fantastico, grazie @siliconrockstar!
Brendon
2013-11-21 00:56:15 UTC
view on stackexchange narkive permalink

Puoi utilizzare l'argomento --separate-git-dir = <git dir> quando chiami git clone. Questo inserirà un collegamento simbolico nella directory .git (simbolico a Git, non penso che sia un collegamento simbolico al tuo sistema operativo), e puoi specificare <git dir> da qualche parte al di fuori della radice del documento.

russdot
2016-03-29 20:02:23 UTC
view on stackexchange narkive permalink

Un approccio alternativo che ho adottato prima è qualcosa di simile al commento di Terry Chia riguardo agli hook post-ricezione.

Git ha un certo numero di hook che possono essere usati per eseguire tutti i tipi di attività prima / durante / dopo più azioni diverse.

Crea un repository nudo in qualsiasi punto diverso dalla tua cartella web. Il repository nudo può quindi essere utilizzato come remoto per eseguire il push a e un hook post-ricezione può essere attivato per estrarre il nuovo codice in una directory specificata.

Questo approccio ha alcuni vantaggi: la posizione di distribuzione funge da strada "a senso unico" in cui il codice deve passare attraverso il controllo del codice sorgente per finire in produzione. È possibile distribuire diversi rami / versioni in posizioni diverse (tutti dallo stesso repository nudo). Fornisce anche un bel modo semplice per eseguire il rollback utilizzando git checkout standard.Tuttavia, un avvertimento / conseguenza di ciò è che le modifiche al codice sul server non si rifletteranno in git (i repository spogli non hanno directory funzionanti), quindi avresti per eseguire manualmente git --work-tree = / path / to / code status per vedere eventuali modifiche (ma non dovresti comunque cambiare il codice di produzione, giusto?)

Non credo che tu abbia bisogno di quel paragrafo introduttivo.Si tenta solo di contrassegnare il tuo post per l'eliminazione.Meglio lavorare su una buona risposta.
Come lettore, quando vedo risposte di tipo "pensato per essere un commento", normalmente le scarto come non utili e salto la lettura.Hai alcuni contenuti utili in questo post.Vorrei costruire su quello.Lavare, sciacquare e ripetere finché non si ha una reputazione sufficiente per lasciare commenti.
Grazie per il feedback!Ho rimosso la prima frase e ho ampliato la mia risposta.Finì comunque per essere troppo lungo per un commento.
Thibault
2016-09-16 18:04:23 UTC
view on stackexchange narkive permalink

Concordo con Terry Chia sul fatto che sia un'ottima pratica. Assicura:

  • che la revisione in atto sia quella giusta,
  • con tutti i file necessari e controlla la completezza della versione,
  • rendere la procedura di distribuzione rapida e semplice

Ma, devo aggiungere che ci sono avvertenze che mi sento di condividere.

Di solito, in un repository git metti:

  • codice,
  • docs,
  • unit test,
  • script di distribuzione,
  • strumenti di integrazione,
  • .deb archivi,
  • patch sql
  • o cose del genere, e forse un mucchio di altre cose

Bene, in produzione vuoi solo il codice!

Perché documenti, unit test, strumenti o archivi .deb potrebbero occupare molto spazio su disco e non hanno nulla a che fare in produzione .

Con Subversion (prima della versione 1.7) potevi controllare solo la directory src / e hai tutti i vantaggi, ma con Subversion> 1.7 e con Git non puoi farlo.

Un'alternativa sarebbe usare i sottomoduli git per realizzare quel tipo di architettura: repository del progetto | - doc | - src -> sottomodulo al repository project-src. \ tests Ma allora il tuo progetto / test e il codice project-src non sarebbero sincronizzati e questo farebbe davvero schifo.

La soluzione sarebbe quindi usare "sparse checkout", vedi: https://stackoverflow.com/questions/600079/how-do-i-clone-a-subdirectory-only-of-a-git-repository

Quindi puoi usare git , ma fai attenzione a questi inconvenienti.

Direi che l'introduzione di sottomoduli \ casse speciali \ altre cose strane dovrebbe essere esaminata molto attentamente prima di prendere decisioni.Di solito le tue "altre cose" non sono così grandi, quindi potrebbe essere un problema.Molto meglio quando lo sviluppatore può semplicemente clonare l'intero repository e iniziare immediatamente a lavorarci senza fare danze magiche durante la configurazione di tutto. P.S.E ovviamente non dovresti affatto archiviare BLOB binari nel tuo repository.
Zamicol
2014-11-15 04:18:37 UTC
view on stackexchange narkive permalink

Ecco lo script che uso per fare in modo che git venga inviato a prod.

https://gist.github.com/Zamicol/f160d05dd22c9eb25031

Si presume che qualsiasi cosa inviata al ramo master sia pronta per la produzione. Tutti gli altri rami spinti vengono ignorati. Puoi modificare questo hook script in base alle tue esigenze.

Per quanto riguarda le tue preoccupazioni, metto la mia directory git in / var / git ei miei file di produzione da qualche altra parte (come / var / www) e limito l'accesso a queste directory.

Potresti anche avere il tuo repository git su un server separato dal tuo server di produzione e quindi usare qualcosa come scp e ssh nel script sopra per spostare i file dal server git al server di produzione. Ciò ti consentirebbe di utilizzare ancora git per eseguire il push to prod mantenendo il codice separato dalla produzione.



Questa domanda e risposta è stata tradotta automaticamente dalla lingua inglese. Il contenuto originale è disponibile su stackexchange, che ringraziamo per la licenza cc by-sa 3.0 con cui è distribuito.
Loading...