A versão TL; DR disso é: depende do aplicativo
Como uma boa referência sobre como o software moderno deve ser construído, recomendo a leitura do aplicativo de doze fatores .
Scripts e código não são replicados como tal, mas "liberados" para servidores de aplicativos (você também pode preparar os servidores liberando todos eles e mudando de código antigo para novo com outro mecanismo, como um symlink).
No entanto, os clientes frequentemente têm "estado" que os servidores de aplicativos talvez precisem lembrar para veicular solicitações corretamente.
De modo geral, para que os servidores de aplicativos sejam escaláveis horizontalmente, você deseja que eles fiquem o mais "sem estado" possível. Isso significa que não há nada para o servidor de aplicativos lembrar como tal, tudo é armazenado externamente e qualquer solicitação pode ser atendida apenas com os dados recebidos na solicitação. No entanto, seus clientes (navegadores da web) geralmente exigem estado, como estar logado, então você precisa ser capaz de lidar com os dados de estado de alguma forma.
Uma solução alternativa é usar "sessões fixas" que são implementadas no balanceador de carga. Geralmente, isso é implementado ao injetar um cookie que o balanceador de carga usa para lembrar para qual servidor ele deve enviar a solicitação. Isso é fácil de implementar e não requer alterações de código, mas tem a grande desvantagem de que o estado será perdido sempre que você reiniciar um servidor de aplicativos.
Outra forma é tornar o aplicativo sem estado, armazenando tudo em cookies. Eu não recomendo isso, porque os dados do estado serão enviados em todas as solicitações. Os clientes também podem modificar esses dados e fazer coisas inesperadas, e pode haver grandes implicações de privacidade caso alguém capture o cookie.
Nenhum deles soluciona o problema de arquivos em disco porque eles dependem de cookies, que o usuário pode perder, ou podem simplesmente fazer o login de algum outro lugar.
A maneira final e recomendada é armazenar o estado do cliente em um banco de dados (ou chave: valor armazenado) de modo que qualquer instância do aplicativo possa consultá-lo quando uma solicitação for recebida. Você ainda precisa que o cliente se lembre de um "id de sessão", mas é mais seguro, pois menos dados são armazenados pelo cliente. Tradicionalmente, um cluster de nós memcached com hashing consistente executaria essa função, mas atualmente existem soluções mais poderosas, como Redis .
Com relação aos arquivos no disco - não armazene nada nos discos do servidor de aplicativos, exceto o código do aplicativo e os recursos estáticos que podem ser "liberados" como parte de uma implantação. Logs são uma possível exceção, mas empurrá-los para um servidor syslog remoto ou algo parecido com logstash é sempre preferível.
Se o seu aplicativo precisar armazenar arquivos (como os enviados por clientes), armazene-os em um datastore de algum tipo (o Cassandra não é uma má escolha), um serviço de armazenamento de algum tipo como o Openstack
Se o aplicativo for de pequena escala e você manipular o bloqueio de arquivos corretamente, um compartilhamento de NFS ou de samba também poderá funcionar, mas eu recomendaria o Amazon S3 antes de seguir esse caminho.