This also solves the roll-back problem mentioned elsewhere. Just checkout the previous version (as long as you don't make any side effects like DB updates that are incompatible).
I admit, this requires relatively simple software.
Then you could have any necessary restart or migration or whatever run in a post-receive hook.
I realise that's starting to get back in to tooling and config etc., but it's not that complex, and if you're already using git anyway...
> and probably very stupid) method is an Expect script that lets me supply a password to sudo.
The old school sysadmin way of doing this would be to have a dedicated deployment user (ssh pubkey auth only - possibly restricting only specific commands), with a sudoers[.d] configuration to allow that user to run an explicit group commands without a password (NOPASSWD)
Also you probably don't want your web under /var if its a partition and you fill it with lets say user content then you will lock up your server.
Alternatively, it's pretty easy to use git-archive (optionally, with an exclusions list to keep out files you don't want to serve publicly) to do something similar without ever cloning the remote repo. You can fetch a zip or tar.gz with a given commit's files, straight from a remote repo.
----------
Static website:
1. Setup NginX using a symlink to the current version
2. Copy the new files to a separate folder
3. Change the symlink to point to the new version
----------
REST service (behind NgninX reverse proxy):
1. Current version runs on port X.
2. Deploy new version and run it on port Y.
3. Update NginX config to use port Y and reload
4. If you need rollback, just reverse step 3.
This can be done using scripts or Ansible too if necessary.
It's pretty fantastic.
I've been writing some Ansible playbooks recently for the first time in years, and came upon geerlingguy's work. That guy is a powerhouse when it comes to writing Ansible roles/modules!
git checkout abcd1234
./build.sh && ./deploy.sh
I don't see the issue.Each schema migration should also come with its own rollback script.
The downside is that you might need three migrations for some operation, but at least you won't break stuff.
The assumption that you can do a schema migration while deploying new code is only valid when you have very limited database sizes. I've seen Flyway migrations break so many times, because developers assumed it was fine to just do complicated migrations on a 200GB database. Or a Django database migration just lock up everything for hours because no one cared to think about the difference between migrating 100MB and 100GB. And I've never seen anyone seriously considering rolling back a Flyway migration.
I never realised I was using spooky arcane oldhat stuff! I feel wizardly now.
My projects (for small clients and myself) basically use this.
- A "build.sh" script that does a local build of back end and front end
- A "deploy.sh" script that scp's everything to the server (either a digital ocean VPS or an EC2 instance), runs npm install, runs database migrations and restarts with pm2
So running my entire CI pipeline in terminal is: ./build.sh && ./deploy.sh