Como fazer uma pasta com link simbólico aparecer como uma pasta normal

38

Eu tenho dois aplicativos Dart que eu preciso dockerize. Esses dois aplicativos usam um diretório de origem compartilhado.
Como o Docker impede a adição de arquivos de pastas fora do diretório de contexto ( project/app1), não consigo adicionar arquivos de ../sharednem de shared(o link simbólico interno projects/app1).

Estou procurando uma maneira de enganar o Docker a fazê-lo de qualquer maneira.

Minha estrutura de projeto simplificada

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

Eu poderia subir Dockerfileum nível e executar a docker buildpartir daí, mas preciso de dois Dockerfiles (para app1 e app2) no mesmo diretório.

Minha idéia atual era: se eu pudesse, de alguma maneira, esconder o fato de projects/app1/sharedser um link simbólico, esse problema seria resolvido. Eu verifiquei se posso compartilhar projectsusando o Samba e remontá-lo em outro lugar e configurar o Samba para tratar links simbólicos como pastas normais, mas não descobri se isso é suportado (eu não tenho muita experiência com o Samba e ainda não tentei, apenas procurei um pouco) .

Existe alguma outra ferramenta ou truque que permita isso?

Prefiro não alterar a estrutura de diretórios, pois isso causaria outros problemas e também não copiaria os arquivos.

zoechi
fonte

Respostas:

35

Como não tenho muita experiência, dockernão posso prometer que isso funcionará, mas uma opção seria montar o diretório em vez de vincular a ele:

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

Que irá anexar ../sharedao ./sharede deve ser completamente transparente para o sistema. Como explicado em man mount:

A ligação é montada.

Desde o Linux 2.4.0, é possível remontar parte da hierarquia de arquivos em outro lugar. A chamada é:

mount --bind olddir newdir

ou usando esta entrada fstab:

/olddir /newdir none bind

Após esta chamada, o mesmo conteúdo é acessível em dois locais.

Terdon
fonte
1
@zoechi isso está perfeitamente no tópico em ambos os sites. Como regra geral, eu colocaria mais perguntas técnicas como esta no U&L e mais questões sobre o espaço do usuário aqui. A escolha é totalmente sua, no entanto. Por um lado, há mais usuários aqui; portanto, mais olhos; por outro, há uma concentração muito maior de profissionais * nix em U&L. Apenas certifique-se de não postar a mesma pergunta nos dois sites. Se você deseja movê-lo, exclua isso ou sinalize para obter uma atenção modesta e peça que eles migrem.
terdon
2
Era obrigatório reiniciar o daemon do docker! Caso contrário, o dir montado não estava visível no contêiner.
dim
@dim yes! Tentei fazê-lo funcionar com Capistrano e não funcionou - Acontece que eu subia os diretórios compartilhados depois eu comecei o recipiente
csch
Infelizmente, isso não funcionará para usuários do Windows ou OS X. O debate sobre esta questão foi ... animado.
24417 Jason
está montando 'comprometido' com o controle de origem, por exemplo, github? ou eu teria que fazer isso toda vez?
pie6k 14/03
23

Esse problema surgiu várias vezes na comunidade do Docker. Basicamente, viola o requisito de que Dockerfileseja repetível se você o executar ou eu o executar. Portanto, eu não esperaria essa capacidade, conforme descrito neste tíquete: O comando Dockerfile ADD não segue links simbólicos no host # 1676 .

Então você tem que conceber uma abordagem diferente. Se você observar este problema: ADICIONE para oferecer suporte a links simbólicos no argumento # 6094 , um amigo nosso da U&L ( @Patrick aka. Phemmer) fornece uma solução inteligente.

$ tar -czh . | docker build -

Isso indica tarpara desreferenciar os links simbólicos do diretório atual e direcioná-los todos para o docker build -comando

trecho da página do man tar
-c, --create
       create a new archive

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

-z, --gzip, --gunzip --ungzip
slm
fonte
3
Esta é uma solução EXCELENTE! Entendo por que o Docker afirma que deseja omitir esse recurso. No entanto, há uma diferença considerável no fluxo de trabalho que eu uso durante o desenvolvimento do meu projeto containerize e como espero que ele seja construído para produção. Na minha máquina local, quero um loop de feedback super apertado. Meu aplicativo tem 1 repositório Git e o ambiente de compilação dos contêineres possui um 2º repositório. Preciso fazer edições e criar testes localmente antes de poder decidir se quero confirmar e enviar por push. Não terei links simbólicos ou instruções ADD no meu projeto final.
117815 Bruno Bronosky #
6
Os arquivos de encaixe não são repetíveis. Os arquivos de encaixe não podem ser repetidos, porque quase todos têm o apt-get ou algo equivalente na 2ª ou 3ª camada e o apt-get não é repetível. Amarrar a estratégia de desenvolvimento do Docker a uma tentativa equivocada de tornar o impossível impossível encobrirá o Docker com uma série de abstrações ruins que não ajudam ninguém. nathanleclaire.com/blog/2014/09/29/…
Jason
1
Ok, então eu realmente não vejo por que isso é melhor do que um cpcomando, você pode explicar por que é melhor? Eu também acho que o tubo é confuso / excessivamente complicado. Por que não colocar o comando tar acima do comando build? Acho que porque você substituiria o diretório com o link real com o diretório real.
Alexander Mills
1
@AlexanderMills - a melhor maneira de ver o que acontece é experimentá-lo e ver a diferença. Além disso, o acima é uma construção de um contêiner que não está em execução, portanto não há montagem. stackoverflow.com/questions/37328370/… . Eu sugiro que você tente todas essas coisas, fará muito mais sentido.
Slm
1
Acabei de adicionar /bin/cp ../requirements.txt . && docker build ...a um Makefile para a construção do Docker, era mais fácil
user5359531