Come far apparire una cartella con collegamento simbolico come una normale cartella


38

Ho due applicazioni Dart che devo dockerizzare. Queste due app utilizzano una directory di origine condivisa.
Poiché Docker impedisce l'aggiunta di file da cartelle esterne alla directory di contesto ( project/app1) non posso aggiungere file ../sharedné da shared(il link simbolico all'interno projects/app1).

Sto cercando un modo per ingannare Docker per farlo comunque.

La mia struttura di progetto semplificata

- projects
  - app1
   - Dockerfile
   - shared (symlink ../shared)
   - otherSource
  - app2
   - Dockerfile
   - shared (symlink ../shared)
   - otherSource
  - shared
    - source

Potrei salire di Dockerfilelivello ed eseguire docker buildda lì, ma poi ho bisogno di due Dockerfile (per app1 e app2) nella stessa directory.

La mia idea attuale era, se potessi in qualche modo nascondere il fatto che projects/app1/sharedè un collegamento simbolico questo problema sarebbe risolto. Ho verificato se posso condividere projectsusando Samba e rimontarlo da qualche altra parte e configurare Samba per trattare i collegamenti simbolici come normali cartelle, ma non ho trovato se questo è supportato (non ho molta esperienza con Samba e non l'ho ancora provato, ho solo cercato un po ') .

C'è qualche altro strumento o trucco che lo consentirebbe?

Preferirei non cambiare la struttura delle directory perché ciò causerebbe altri problemi e piuttosto non copiare i file in giro.

Risposte:


35

Non ho molta esperienza con dockerquindi non posso promettere che funzionerà, ma una scelta sarebbe quella di montare la directory invece di collegarla ad essa:

$ cd projects/app1
$ mkdir shared
$ sudo mount -o bind ../shared shared/

Che attribuirà ../sharedad ./sharede dovrebbe essere completamente trasparente per il sistema. Come spiegato in man mount:

Il legame si monta.

Da Linux 2.4.0 è possibile rimontare parte della gerarchia dei file da qualche altra parte. La chiamata è:

mount --bind olddir newdir

o usando questa voce fstab:

/olddir /newdir none bind

Dopo questa chiamata, gli stessi contenuti sono accessibili in due punti.


1
@zoechi questo è perfettamente in tema su entrambi i siti. Come regola generale, pubblicherei domande più tecniche come questa su U&L e più domande sullo spazio utente qui. La scelta dipende completamente da te però. Da un lato, ci sono più utenti qui, quindi più bulbi oculari, dall'altro c'è una concentrazione molto più elevata di professionisti * nix su U&L. Assicurati di non pubblicare la stessa domanda su entrambi i siti. Se vuoi spostarlo, elimina questo o contrassegna l'attenzione del mod e chiedi loro di migrare.
terdon,

2
Per me è stato obbligatorio riavviare il demone docker! Altrimenti la directory montata non era visibile nel contenitore.
dim

@dim yes! Ho provato a farlo funzionare con Capistrano e non ha funzionato - risulta che ho montato le directory condivise dopo aver avviato il contenitore
csch

Purtroppo questo non funzionerà per gli utenti di Windows o OS X. Il dibattito su questo tema è stato ... vivace.
Jason,

il montaggio è "commesso" al controllo del codice sorgente, ad esempio github? o dovrei farlo ogni volta?
pie6k

23

Questo problema è emerso ripetutamente nella comunità Docker. Fondamentalmente viola il requisito che Dockerfilesia ripetibile se lo esegui o lo eseguo. Quindi non mi aspetto questa capacità, come descritto in questo ticket: il comando ADD Dockerfile non segue i collegamenti simbolici sull'host # 1676 .

Quindi devi concepire un approccio diverso. Se si osserva questo problema: AGGIUNGI per supportare i collegamenti simbolici nell'argomento # 6094 , un nostro amico di U&L ( @Patrick aka. Phemmer) fornisce una soluzione intelligente.

$ tar -czh . | docker build -

Questo dice tara dereferenziare i collegamenti simbolici dalla directory corrente e quindi reindirizzarli tutti al docker build -comando.

estratto dalla pagina man tar
-c, --create
       create a new archive

-h, --dereference
       follow symlinks; archive and dump the files they point to

-z, --gzip, --gunzip --ungzip

3
Questa è una soluzione ECCELLENTE! Capisco perché Docker afferma di voler omettere questa funzione. Tuttavia, c'è una notevole differenza nel flusso di lavoro che utilizzo durante lo sviluppo del mio progetto containerize e nel modo in cui mi aspetto che sia costruito per la produzione. Sul mio computer locale voglio un circuito di feedback super stretto. La mia app ha 1 repository git e l'ambiente di build per i contenitori ha un 2o repository. Devo essere in grado di apportare modifiche e creare test localmente prima di poter decidere se voglio impegnarmi e spingere. Non avrò collegamenti simbolici o istruzioni ADD nel mio progetto finale.
Bruno Bronosky,

6
I file Docker non sono ripetibili. I file docker non possono essere resi ripetibili, poiché quasi tutti hanno apt-get o qualcosa di equivalente al 2o o 3o strato e apt-get non è ripetibile. Legare la strategia di sviluppo di Docker a un tentativo fuorviante di realizzare l'impossibile realtà, sosterrà Docker con una serie di cattive astrazioni che non aiutano nessuno. nathanleclaire.com/blog/2014/09/29/…
Jason

1
Ok, quindi non vedo davvero perché sia ​​meglio di un cpcomando, puoi spiegare perché è meglio? Penso anche che la pipa sia confusa / eccessivamente contorta. Perché non mettere semplicemente il comando tar sopra il comando build. Immagino perché allora sovrascriveresti la directory con link simbolico con la directory reale.
Alexander Mills,

1
@AlexanderMills - il modo migliore per vedere cosa succede è provarlo e vedere la differenza. Anche quanto sopra è un edificio di un container non in esecuzione, quindi non c'è montaggio. stackoverflow.com/questions/37328370/… . Consiglio vivamente di provare tutte queste cose, avrà molto più senso.
slm,

1
Ho appena aggiunto /bin/cp ../requirements.txt . && docker build ...un Makefile per costruire la Docker, è stato più facile
user5359531
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.