-
Notifications
You must be signed in to change notification settings - Fork 20
Deployment
All of the following commands should be done in the Conda Virtual Environment (after conda activate tbpweb-dev
).
This requires fabric, a Python SSH task runner, to be installed and accessible.
As it is listed as a dependency in the config/requirements.txt
, it is installed via Pip during while the Conda environment is set up.
Then, deploy a release with the following command in your Python:
fab deploy
If your SSH key to the apphost requires a password to unlock, the --prompt-for-passphrase
flag will allow you to input it:
fab --prompt-for-passphrase deploy
If you have no SSH key to the apphost (shame on you), and require password authentication, the --prompt-for-login-password
will allow you input it:
fab --prompt-for-login-password deploy
The prod
deploy config (in the fabfile) will fetch the TBP-IT/tbpweb
repo's master
branch over HTTPS, then extract it to a timestamped release folder under ~/tbpweb/prod/releases
.
Then the timestamped folder will be linked to ~/tbpweb/prod/current
and then restart the server (via systemctl
(see "Reloading"))
This means that, by default, your commits must be pushed to the "TBP-IT" repo under the "master" branch before deploying. It does not copy the code from your computer.
Note: this does not require SSH access to the Github repo, only SSH access to the apphost.
During the development of features to the Django website, the "fab" script is written where the tbpweb
website will always deploy to https://tbp.berkeley.edu
If you are, for some reason, deploying from a different branch, then you should edit the fabfile.py
targets
dict to specify a new deploy target, by overriding the defaults just above it:
targets = {
'prod': {
'deploy': {
'name': 'prod',
'branch': 'master',
},
},
'custom-target': {
'deploy': {
'name': 'custom',
'branch': 'my-branch',
'repo_url': 'my-fork-url',
},
},
}
Then select the custom target by using the custom made --target
flag (not part of fab) [By default, the prod
target is used]##
fab deploy --target custom-target
Use:
fab rollback --release <Timestamp of Folder>`
replacing the <Timestamp of Folder>
with only the Folder Name you want to rollback to in ~/tbpweb/prod/releases/
(you don't need the full path, just the name of the specific folder inside the "releases" folder)
-
SSH into the OCF Server at [email protected]
-
Get the full path of the folder that you want to link (currently, all past versions of the website is located inside
~/tbpweb/prod/releases/
). You may userealpath <file or folder name>
to get the full path, where<file or folder name>
is the name of the file starting from the current directory you are at on your terminal (replacing between and including the "<" and ">"). -
Get the path of the "current" folder (currently, all past versions of the website is located inside
~/hknweb/prod/current/
). You may also userealpath <file or folder name>
to get the full path, where<file or folder name>
is the name of the file starting from the current directory you are at on your terminal (replacing between and including the "<" and ">"). -
Run this command:
ln -sfn <Full Path of Release Timestamp Folder> <Full Path of the Current Symlink>
, replacing<Full Path of Release Timestamp Folder>
with the path you got in Step 1 and<Full Path of the Current Symlink>
with the path you got in Step 2 (with both replacing between and including the "<" and ">"). For example,ln -sfn /home/h/hk/hkn/hknweb/prod/releases/20210103_212211 /home/h/hk/hkn/hknweb/prod/current
-
Run
systemctl --user restart hknweb.service
to restart the Server
Deployment will be run using fabric, a Python SSH task runner.
Since the Django runserver
builtin server isn't actually a very good web server (it's designed
for one user, not hundreds), we use a different web server called gunicorn on the OCF.
Our deployment will be to the OCF's apphost server, https://apphost.ocf.berkeley.edu/. The OCF's documentation for running apps can be found here.
Our public-facing domains are:
- Production: https://hkn.eecs.berkeley.edu
- Test: https://dev-hkn.eecs.berkeley.edu
Nothing! You should have already installed everything in setup.
[NOTE: This command does not work as of January 3, 2021. This is an old command. Will post once an equivalent is found. For now, the above "fab deploy" and similar commands should suffice, and if another SSH destination is needed, edit the "user" and "host" part in hkn_defaults
inside fabfile.py
]
From the .venv Virtual Environment, run the command:
fab -R <environment> -H [email protected] deploy
We will have two environments:
-
prod
: production, publicly visible, contains important user data -
test
: testing, publicly visible, but may be wiped
We will push proposed changes to test
, and finally to prod
once the changes are confirmed working.
During Development, the "fab" script is written where the hknweb
website will always deploy to https://dev-hkn.eecs.berkeley.edu
So what do we need to get deployment working?
We download a copy of the code, from the Github master branch. This will allow us to control which version of code to deploy, and restrict push access to core developers.
We should download a copy, and not simply git pull
. This is because we want to allow rollbacks, and we don't
want rogue files laying around forever, and we want a controlled environment as much as possible.
The fake README describes the deploy process in detail, which follows the Capistrano model from Ruby:
- Inside a deploy_path, create a releases, shared, and repo directory.
- Clone a repository into the repo directory.
- Extract a configurable branch into a subdirectory of the releases directory.
- Symlink that subdirectory to a current folder in the deploy_path
- Symlink shared files/folders in shared into current.
What this means is that the folder structure in the deploy server (apphost.ocf.berkeley.edu) should look like this:
~/hknweb/
prod/
current/ -> <release symlink>
releases/
shared/
repo/
test/
current/ -> <release symlink>
releases/
shared/
repo/
<release symlink>
means that a website code timestamped folder is symlinked (similar to your conventional "shortcuts" or "alias") located inside releases/
Our website runs using gunicorn, and is managed by systemd (see the Ubuntu and Arch Linux docs). When we deploy a new version of the website, we have to restart it using systemd:
systemctl --user restart hknweb.service
This also means that when the OCF takes down their servers for maintenance, when they are turned on our website is also turned on automatically.
This depends on two files, a run
script in our repo and a systemd unit script on the apphost: ~/.config/systemd/user/hknweb.service
.
-
hknweb.service
describes how to run and restart our server -
run
describes the actualgunicorn
command to run an instance of our server
Gunicorn has a green-thread worker model. This means that it controls multiple worker processes to handle requests, from a single master process which distributes requests.
Green threads, or m-to-n threads, means that every process has its own thread scheduler, instead of using the OS (kernel) thread scheduler. The idea is that since we know what kind of task we need to do, I/O heavy web requests (which the OS can't assume), we can figure out how much CPU% to give to each task ourselves, and do so more efficiently.
More technically, it means that we map any m task threads to some n OS threads.
Homepage
Guide
- Basics
- Recommended Onboarding Pacing Schedule
- Comprehensive Setup (Forking, Cloning, and Dev Environment)
- Setup
- Django Development Tutorial
- Other Software Engineering Useful Topics
- Contribution Procedure
- Layout
- Deployment
- Server Administration
- Git Guide
- Style
- FAQ
- For Maintainers
Rails - unmaintained - leftover to serve as source of inspiration for other wiki pages