Выполнение команд Rails из Bash хоста

Всем привет,

Я хочу выполнять задачи по автоматической очистке пользователей с хоста через Bash. Вручную я запускаю:

/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)

У меня есть длинный список имён пользователей из текстового файла, которые нужно удалить. Выполнять это вручную нецелесообразно. Я попытался обернуть команду удаления в bash-скрипт. При выполнении rails c с подкомандой launcher app соединение с Redis не удаётся:

/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.

Однако при сравнении окружений через export между launcher enter app и launcher run app они выглядят практически идентичными. Что я упускаю? launcher run запускается в /, тогда как launcher enter сразу переходит в /var/www/discourse. Использование cd перед выполнением rails не помогает.

Есть какие-то подсказки? Спасибо!

Я думаю, что docker run запускает новый контейнер.

Для таких задач я использую docker exec, а не launcher, который выполняет множество ненужных действий.

Спасибо за ответ. Я заметил, что поведение Rails при использовании docker exec тоже очень странное. Вручную всё работает отлично:

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

Но когда я пытаюсь запустить rails c извне контейнера, возникают следующие проблемы:

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

Но что ещё интереснее:

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

Почему это вообще работает по-разному?

Это ожидаемо: вы просите Docker выполнить бинарный файл /usr/local/bin/rails console в контейнере. То есть один файл с пробелом внутри. Такой файл не существует.

Рассмотрим следующий пример:

○ → 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 

Кавычки вокруг команды используйте так же, как если бы вы выполняли её внутри контейнера:

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

Используя пример из исходного поста, это должно сработать:

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

Хорошо, это стало для меня неожиданностью, потому что я не читал документацию. Спасибо за быструю помощь.