The discussion revolves around running commands inside a Discourse container. Initially, ryanerwin struggled to pass commands from the host to the container but later discovered a solution by implementing a ./launcher exec command. He created a PR to make this feature available to others and shared an example script that automates a nightly restore of a live database to a staging server.
itsbhanusharma questioned the advantage of using ./launcher exec over running commands directly inside the container using ./launcher enter app. ryanerwin explained that the benefits include shorter commands, avoiding redundant steps, and the ability to automate tasks on the host that operate on the container.
pfaffman shared an example of using docker exec to run commands inside the container, but acknowledged that having the launcher facilitate this process is a great idea.
I would like to script discourse restore... but I don’t understand how to easily pass commands from the host to the discourse docker container. I tried:
sudo docker run local_discourse/app discourse enable_restore
but that didn’t work…
Ideally I could do something like ./launcher run app discourse enable_restore and then ./launcher run app discourse enable_restore and ./launcher rebuild app
In case you’re curious, the reason to automate the discourse restore is so that I can do a nightly restore of the most recent live database on to our staging server.
With this, I was able to very easily grab my latest S3 backup from live and load it our testing server:
#!/bin/bash -x
SITE="forum-example-com" # the way site name shows up in your backup files...
BUCKET="forum-example-backups"
DATE=$(date --date="-1 day" +%Y-%m-%d)
FILE=$(aws s3api list-objects-v2 --bucket $BUCKET --query "reverse(sort_by(Contents[?starts_with(Key, \`$SITE\`) == \`true\`]|[?LastModified > \`$DATE\`].{Key: Key, Size: Size, LastModified: LastModified},&LastModified))" | jq -r '.[0] | .Key')
aws s3 cp s3://$BUCKET/$FILE /var/discourse/shared/standalone/backups/default/$FILE
cd /var/discourse
sudo ./launcher exec app discourse enable_restore
sudo ./launcher exec app discourse restore $FILE
sudo ./launcher rebuild app
Note that at the end of my app.yml I also find it handy to reset several site settings
- exec: rails r "SiteSetting.long_polling_base_url=''"
- exec: rails r "SiteSetting.title='dev.example.com'"
- exec: rails r "SiteSetting.invite_only=true"
- exec: rails r "SiteSetting.login_required=true"
- exec: rails r "SiteSetting.disable_digest_emails=true"
- exec: rails r "SiteSetting.allow_index_in_robots_txt=false"
- exec: rails r "SiteSetting.reply_by_email_enabled=false"
- exec: rails r "SiteSetting.pop3_polling_enabled=false"
# if you have categories that you don't want to show on your staging site...
# exec: rails r "Category.find_by_slug('SiteDevelopment').destroy"
Shorter commands removing redundant steps (./launcher enter app is just ./launcher exec app bash except you’re stuck in bash without the defaults that you’re accustomed to, and then you still need to run the command you actually wanted to run (ie, discourse restore. Also, inside the container’s bash you constantly (every rebuilt) loose all your shell history and the history settings inside the container are probably not what you’re used to. You’re also forced to use bash instead of zsh or whatever shell you might normally use.
How do you automate anything on the host that operates on your container without this? For example, the script I outlined above that we run on our staging site each night… grabs our database from live and restores it onto dev. I imagine you don’t want to write expect scripts to automate a terminal session…