Executando comandos do rails a partir do Bash do host

Olá a todos,

Quero executar tarefas automatizadas de limpeza de usuários a partir do Bash do host. Manualmente, eu executo:

/var/discourse/launcher enter app
rails c
UserDestroyer.new(Discourse.system_user).destroy(User.find_by_username_or_email("user@example.com"), delete_posts: false)

Tenho uma lista longa de nomes de usuários em um arquivo de texto que precisam ser removidos. Executar isso manualmente não é viável. Tentei envolver o comando de exclusão em um script bash. Ao executar o rails c com o subcomando launcher app, a conexão com o Redis falha:

/var/discourse/launcher run app "echo \"User.find_by_username_or_email('user@example.com')\" | rails c"
Failed to report error: Error connecting to Redis on localhost:6379 (Errno::EADDRNOTAVAIL) 2 Error connecting to Redis on localhost:6379 (Errno::EADDRNOTAVAIL) subscribe failed, reconnecting in 1 second.

No entanto, ao comparar os ambientes com export entre launcher enter app e launcher run app, eles parecem praticamente idênticos. O que estou esquecendo? O launcher run inicia em /, enquanto o launcher enter entra diretamente em /var/www/discourse. Usar um cd antes de executar o rails não ajuda.

Alguma dica? Obrigado!

Acho que o docker run inicia um novo container.

Para coisas assim, eu uso docker exec em vez de launcher, que faz um monte de coisas que você não precisa.

1 curtida

Obrigado pela resposta. Achei que o comportamento do Rails com docker exec também é muito estranho. Manualmente, funciona perfeitamente:

docker exec -it de7f5f6f649c '/bin/bash'
root@discourse-app:/# rails c
[1] pry(main)> User.find_by_username_or_email('myname')

Mas quando tento executar rails c de fora do container, obtenho os seguintes problemas:

docker exec -it de7f5f6f649c "/usr/local/bin/rails console"
OCI runtime exec failed: exec failed: container_linux.go:367: starting container process caused: exec: "/usr/local/bin/rails console": stat /usr/local/bin/rails console: no such file or directory: unknown

Mas o mais interessante:

docker exec -it de7f5f6f649c '/bin/bash -c "/usr/local/bin/rails"'
OCI runtime exec failed: exec failed: container_linux.go:367: starting container process caused: exec: "/bin/bash -c \"/usr/local/bin/rails\"": stat /bin/bash -c "/usr/local/bin/rails": no such file or directory: unknown

Por que isso é diferente?

Isso é esperado; você está instruindo o Docker a executar o binário /usr/local/bin/rails console no contêiner. Ou seja, um único arquivo com um espaço incorporado. Esse arquivo não existe.

Considere o seguinte:

○ → docker run -i debian /bin/echo hello
hello

○ → docker run -i debian '/bin/echo hello'
docker: Error response from daemon: OCI runtime create failed: container_linux.go:367: starting container process caused: exec: "/bin/echo hello": stat /bin/echo hello: no such file or directory: unknown.
ERRO[0000] error waiting for container: context canceled 

Cite o comando da mesma forma como se estivesse executando de dentro do contêiner:

○ → docker exec -i app rails runner 'puts "hello"'
hello

Usando o exemplo do OP, isso deve funcionar:

docker exec -i app rails runner 'UserDestroyer.new(Discourse.system_user).destroy(User.find_by_username_or_email("user@example.com"), delete_posts: false)'
2 curtidas

Ok, foi inesperado para mim porque não li o RTFM. Obrigado pela ajuda rápida.

1 curtida