it-swarm-eu.dev

Usare Git per distribuire è una cattiva pratica?

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

  1. Se qualcosa dovesse andare storto, è estremamente facile tornare a una revisione precedente, semplice come verificarlo.
  2. Se uno qualsiasi dei file del codice sorgente viene modificato, controllandolo facilmente come git status e se il repository del server è stato modificato, la prossima volta che proverò a estrarlo diventerà ovvio.
  3. Significa che esiste un'altra copia del codice sorgente, nel caso in cui succeda qualcosa di brutto.
  4. L'aggiornamento e il rollback sono facili e molto veloci.

Questo potrebbe avere alcuni problemi però:

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

  • Tutti coloro che accedono accidentalmente in lettura alla cartella ottengono anche l'accesso a tutte le versioni precedenti 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 nella produzione sia ragionevolmente sicuro e molto più semplice di rsync, ftp o semplicemente copiarlo. Cosa ne pensi?

109
Septagram

Andrei fino a considerare l'utilizzo di git per la distribuzione ottima pratica .

I due problemi che hai elencato hanno ben poco a che fare con l'uso di git per la distribuzione stessa. Sostituto .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. Questo è un problema di rafforzamento del server che devi discutere con l'amministrazione del tuo sistema.

git offre alcuni vantaggi molto interessanti in termini di sicurezza.

  1. È possibile applicare un sistema per la distribuzione in produzione. Vorrei persino configurare un post-receive hook da distribuire automaticamente alla produzione ogni volta che viene eseguito un commit a master. Presumo ovviamente, un flusso di lavoro simile a git flow .

  2. git semplifica notevolmente il rollback del codice distribuito in produzione su una versione precedente in caso di problemi di sicurezza. Questo può essere utile per bloccare l'accesso a difetti di sicurezza mission-critical che è necessario il tempo per correggere 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 alla produzione se viene rilevato un difetto di sicurezza deliberato.

77
user10211

Non c'è niente di sbagliato nel distribuire da un repository git, in realtà è una pratica abbastanza comune e come dici molto meno soggetto a errori rispetto alla copia di file su ftp o rsync.

Date le informazioni che hai fornito, vorrei notare i seguenti punti:

  • Non limitarti a inserire l'ultimo maestro. La produzione deve 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 codice in un determinato momento, è più stabile rispetto a un ramo principale che potrebbe essere aggiornato da un commit errato.

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

  • L'autenticazione git dovrebbe essere basata sulla chiave ssh, quindi non è necessario archiviare password repo sul server.

Evviva i flussi di lavoro di distribuzione git!

26
Matt Surabian

Puoi usare il --separate-git-dir=<git dir> argomento quando si chiama git clone . Ciò inserirà un collegamento simbolico nel .git directory (simbolica di Git, non credo sia un collegamento simbolico al tuo sistema operativo) e puoi specificare <git dir> da qualche parte al di fuori della radice del documento.

8
Brendon

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 si adattano molto bene.

... il che non vuol dire che non dovresti continuare a fare quello che stai facendo. Tieni a mente, man mano che la tua carriera avanza, che i progetti a cui stai lavorando probabilmente supereranno un flusso di lavoro di distribuzione basato esclusivamente su git.

Il principale cambiamento nel paradigma è smettere di pensare alla distribuzione di filiali e iniziare a pensare alla distribuzione dei risultati di compilazione e all'iniezione di dipendenze ambientali per separare l'infrastruttura dalla strategia di ramificazione.

Ad esempio, per utilizzare il paradigma sopra "distribuzione di file" e rollback. Se eravate distribuite file, potreste mantenere più versioni dell'applicazione sul server di produzione e, se avete bisogno di eseguire il rollback, potete indirizzare il vostro server web a una versione precedente ricollegando nuovamente la radice web. Due comandi Shell, microsecondi di downtime, meno spazio per errori rispetto all'utilizzo di git.

Un altro esempio: hai il ramo di sviluppo standard> ramo di gestione temporanea> flusso di lavoro principale, con un server per ciascuno. Hai cose pronte per essere sviluppate, ma alcune altre cose sulla messa in scena hanno fallito il QA. Quindi è necessario eseguire alcune brutte operazioni: eliminare i commit errati dallo stage, ridistribuire lo stage e anche eliminare o correggere i commit errati nello sviluppo e sperare che lo sviluppo e la messa in scena non finiscano in sincronia.

Invece, se si tagliasse un ramo di rilascio fuori dal master, si fondessero le cose pronte per andare in quel ramo di rilascio e si creasse il risultato, si avviava un server di test su AWS e si distribuiva il risultato su di esso, si eseguivano il QA e i test funzionali contro quel server temporaneo di gestione temporanea e quindi ha inviato lo stesso risultato al cluster di produzione e lo ha distribuito? Quindi rimuovere la casella di gestione temporanea che è stata attivata, unire il rilascio nel master e contrassegnare il master con un numero di rilascio.

Ovviamente quelli 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 necessarie modifiche al database. E se hai mod di database non idempotenti tra le versioni, beh, il rollback non sarà così facile non importa quale metodo usi, perché dovrai eseguire il rollback del db (in generale, provare a distribuire database idempotent modifiche, quindi rimuovere i bit di database obsoleti in una versione successiva, dopo aver verificato che sono fuori dal flusso dell'applicazione).

Ad ogni modo, credo a cosa sto arrivando, è che la mia risposta a "Sta usando git per distribuire cattive pratiche?" è, in generale, "Sì", allo stesso modo in cui l'uso delle ruote da allenamento è dannoso per la bicicletta. È un miglioramento rispetto a spaccarti ripetutamente il culo sul cemento, ma speriamo che alla fine lo superi.

8
siliconrockstar

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

Git ha n numero di hook che può essere usato per eseguire tutti i tipi di attività prima/durante/dopo più azioni diverse.

Crea un repository bare ovunque diverso dalla tua cartella web. Il repository nudo può quindi essere utilizzato come da remoto a Push to e un hook post-ricezione può essere attivato per eseguire il checkout del nuovo codice in una directory specificata.

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

5
russdot

Concordo con Terry Chia che è un'ottima pratica. Assicura:

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

Ma devo aggiungere che ci sono avvertimenti che ho voglia di condividere.

Di solito, in un repository git inserisci:

  • codice,
  • docs,
  • test unitari,
  • script di distribuzione,
  • strumenti di integrazione,
  • .deb archives,
  • patch sql
  • o cose del genere, e forse un sacco di altre cose

Beh, 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 con la produzione.

Con Subversion (prima della versione 1.7) è possibile effettuare il checkout solo del src/ directory e hai tutti i vantaggi. Ma con Subversion> 1.7 e con Git, non puoi farlo.

Un'alternativa sarebbe quella di utilizzare i sottomoduli git per creare quel tipo di architettura: project repo |- doc |- src -> submodule to project-src repo. \ tests Ma poi il tuo progetto/test e il codice project-src non sarebbero sincronizzati e sarebbe davvero schifo.

La soluzione sarebbe quindi quella di utilizzare il "checkout sparse", vedere: 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.

3
Thibault

Ecco lo script che uso per creare git to Push to prod.

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

Presuppone che tutto ciò che viene spinto nel ramo principale sia pronto per la produzione. Tutti gli altri rami spinti vengono ignorati. È possibile modificare questo script hook in base alle proprie esigenze.

Per quanto riguarda le tue preoccupazioni, metto la mia directory git in/var/git e i 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 nello script sopra per spostare i tuoi file dal server git al server di produzione. Questo ti permetterebbe di usare ancora git per Push per produrre mantenendo il tuo codice separato dalla tua produzione.

1
Zamicol