LMS originating from Timberline Secondary School's Digital Hackerspace
Although bytedeck uses several tools, you only need to set up two of them thanks to docker!
The instructions below will help you get bytedeck running using docker, and then help you set up a development environment with VS Code.
The instructions assume you are using Ubuntu (or another Debian based linux distro), although it is possible to get it working anywhere you can install docker.
Follow the instructions the for installing Docker CE (community edition, i.e. free edition) using the repository: https://docs.docker.com/install/linux/docker-ce/ubuntu/#install-using-the-repository
By the end, you should be able to run docker's test image:
$ sudo docker run hello-world
sudo apt install docker-compose
Add yourself to the docker group:
sudo usermod -aG docker $USER
Using a different version of Python will probably give you errors when installing the dependencies due to slight changes between versions:
sudo apt install python3.8
- Create a Github account.
- Go to https://github.com/bytedeck/bytedeck
- The main branch of this repo is the
develop
branch, make sure you are on that branch. - Click the "Fork" button on the top right corner.
- This will allow you to have your own copy of the project on your GitHub account.
- Open the directory where you want to put the code. I like to create a new directory for my code projects called Developer:
mkdir ~/Developer
- Move into the parent directory of the project:
cd ~/Developer
- Go to your forked repository in GitHub
- Click "Clone or download" and copy the url, then paste it into the command:
git clone yoururlhere
- This will download the project into ~/Developer/bytedeck/
This will create your docker containers and initialize the database by running migrations and creating some initial data that is required:
- Open a terminal
- Move into the project directory:
cd ~/Developer/bytedeck
- Copy the example environment file to the one you'll be using. Docker-compose and django will both be looking for a .env files with various settings that you can customize. If you are not running the app locally (e.g. production), then be sure to set DOMAIN_ROOT to the FQDN.
cp .env.example .env
- Build the containers (db, redis, celery, and celery-beat):
docker-compose build
- Start the postgres database container (db) in the background/daemonized (-d)
docker-compose up -d db
- OPTIONAL: For development, we can run the django app in a local virtual environment (venv) instead of using the web container, however if this gives you any issues, just run everything in a container with docker-compose (explained below)
- Create a python virtual environment (we'll put ours in a venv directory):
python3.8 -m venv venv --prompt bytedeck
- Enter the virtual environment:
source venv/bin/activate
- Install wheel to prevent errors (why isn't this included in the new venv module?)
python -m pip install wheel
- Install our requirements:
python -m pip install -r requirements.txt
- Initialize pre-commit
pre-commit install
- Create a python virtual environment (we'll put ours in a venv directory):
- Run a management command to run initial migrations, create the public tenant, superuser, and some other stuff:
- using venv:
./src/manage.py initdb
- using docker:
docker-compose run web bash -c "./src/manage.py initdb"
- using venv:
- Now run the django development server:
- using venv:
./src/manage.py runserver
- using docker:
docker-compose up web
- using venv:
- You should now get the page at http://localhost:8000. Note that the ip/url output by the django server,
0.0.0.0
will not work in this project, because our multitenant architecture requires a domain name, so you need to uselocalhost
instead. - And you should be able to log in to the admin site at http://localhost:8000/admin/
- user: admin
- password: password (this is defined in the .env file under DEFAULT_SUPERUSER_PASSWORD)
- Run redis, celery and celery-beat containers (you can run in the background too if you want with
-d
, but you won't see any errors if they come up). the db container should already be running:docker-compose up -d redis celery celery-beat
- To view errors in the containers when they are running in the background, you can use:
docker-compose logs -f
If everything has worked so far, you should now be able to create your own bytedeck website (aka a new 'deck') as a new tenant:
- If the server isn't already running, run it with:
./src/manage.py runserver
ordocker-compose up web
(and ignore the link it tells you to access the page) - Go to django admin at http://localhost:8000/admin/ (this is known as the Public tenant, it's where we can control all the other sites or tenants)
- In the Tenants app near the bottom, create a new tenant by giving it a name, for example:
hackerspace
- This will create a new site at http://hackerspace.localhost:8000 go there and log in
- user: admin
- password: password (this is defined in TENANT_DEFAULT_SUPERUSER_PASSWORD in the .env file)
- Now you should be in your own bytedeck site!
- If you would like to stop the project, use
Ctrl + C
in the command lines, then wait for each of the containers to stop.
New tenants will come with some basic initial data already installed, but if you want masses of data to simulate a more realistic site in production:
-
Open a Python shell specific to your tenant (make sure your virtual environment is activated), enter your tenant's name (for example,
hackerspace
) and paste these commands:$ ./src/manage.py tenant_command shell Enter Tenant Schema ('?' to list schemas): hackerspace In [1]: from hackerspace_online.shell_utils import generate_content In [2]: generate_content()
You can also do this from docker with:
docker-compose exec web bash -c "./src/manage.py tenant_command shell"
-
This will create 100 fake students, and 5 campaigns of 10 quests each, and maybe some other stuff we've added since writing this! You should see the output of the objects being created. Go to your map page and regenerate the map to see them.
-
use Ctrl + D or
exit()
to close the Python shell.
Here are the steps, assuming that you now have a functional tenant:
- Obtain Google credentials: https://developers.google.com/workspace/guides/create-credentials#oauth-client-id
- In the OAuth Client ID's Authorized Redirect URIs, add
http://hackerspace.localhost.net:8000/accounts/google/login/callback/
. We will explain why we are usinglocalhost.net
later. - Go to Social Applications in the public tenant admin: http://localhost:8000/admin/socialaccount/socialapp/
- Click Add Social Application
- Fill in
Client Id
andSecret Key
from the Google OAuth Client ID, then add theAvailable Sites
toChosen Sites
- Click Save
- Go to Tenants on the public tenant admin: http://localhost:8000/admin/tenant/tenant/
- There should be a checkbox beside the tenant's schema name. Check the checkbox and choose
Enable google signin for tenant(s)
from the admin actions at the bottom, and clickGo
. - Done
When you are developing locally, Google won't allow you to add http://hackerspace.localhost:8000/accounts/google/login/callback/
in the Authorized URIs. So we need a way to bypass this in our local machine by mapping our localhost to localhost.net
so we can access our tenant via http://hackerspace.localhost.net:8000
.
-
You need to modify your hosts file by adding this to the bottom of
/etc/hosts
:127.0.0.1 localhost.net hackerspace.localhost.net
-
Update the
ALLOWED_HOSTS
in the project's.env
file:ALLOWED_HOSTS=.localhost,.localhost.net
-
Let
django-tenants
know thathackerspace.localhost.net
is also a valid domain. Run$ ./src/manage.py shell
and type in the following commands
from tenant.models import Tenant
tenant = Tenant.objects.get(schema_name='hackerspace')
tenant.domains.create(domain='hackerspace.localhost.net', is_primary=False)
- Done! You should now be able to access your site via
http://hackerspace.localhost.net:8000/
and use the Google Sign In. Note that Google Sign In will only work using the.net
url.
See CONTRIBUTING.md if you plan to contribute code to this project. It contains critical information for your pull request to be accepted and will save you a lot of time!