{"id":16519820,"url":"https://github.com/zonca/jupyterhub-deploy-data301","last_synced_at":"2025-04-09T18:41:09.772Z","repository":{"id":138271496,"uuid":"48002116","full_name":"zonca/jupyterhub-deploy-data301","owner":"zonca","description":"Deploy JupyterHub for teaching DATA 301","archived":false,"fork":false,"pushed_at":"2015-12-14T22:18:25.000Z","size":33,"stargazers_count":1,"open_issues_count":0,"forks_count":7,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-23T20:43:18.698Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zonca.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-12-14T21:26:41.000Z","updated_at":"2017-08-12T14:01:46.000Z","dependencies_parsed_at":"2023-05-06T12:32:03.205Z","dependency_job_id":null,"html_url":"https://github.com/zonca/jupyterhub-deploy-data301","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zonca%2Fjupyterhub-deploy-data301","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zonca%2Fjupyterhub-deploy-data301/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zonca%2Fjupyterhub-deploy-data301/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zonca%2Fjupyterhub-deploy-data301/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zonca","download_url":"https://codeload.github.com/zonca/jupyterhub-deploy-data301/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248089802,"owners_count":21045968,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-11T16:48:32.737Z","updated_at":"2025-04-09T18:41:09.739Z","avatar_url":"https://github.com/zonca.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Deploy JupyterHub for teaching DATA 301\n\nThis repository contains the code being used to deploy JupyterHub for DATA 301,\n\"Introduction to Data Science,\" at Cal Poly. This is designed to be a simple\nand reusable JupyterHub deployment, while still following best practices.\n\nThe main usage case targted is small to medium groups of trusted users working\non a single server.\n\n## Design\n\nIndividuals using this repo to deploy JupyterHub should be able to:\n\n* Start from:\n  - An empty Ubuntu latest stable server with SSH key based access.\n  - A valid DNS name.\n  - A formatted and mounted directory to use for user home directories.\n  - The assumption that all users of the system will be \"trusted,\" meaning that\n    you would given them a user-level shell account on the server.\n* Always have SSL/TLS enabled.\n* Optionally monitor the state of the server and set email alerts using NewRelic.\n  The builtin monitoring of your cloud provider can also be used.\n* Specify admin users of JupyterHub.\n* Manager users and authentication using either:\n  - Regular Unix users and PAM.\n  - GitHub OAuth\n* Manage the running of jupyterhub and nbgrader using supervisor.\n* Specify local drives to be mounted.\n* Add the public SSH keys of GitHub users who need to be able to SSH to the server\n  as `root` for administration.\n* Have a deployment that is as simple as possible:\n  - No Docker.\n  - Nginx as a frontend proxy, serving static assets, and a termination point for SSL/TLS.\n  - A single server.\n  - Ansible for config.\n  - Optionally use https://letsencrypt.org/ for generating SSL certificates.\n* Configure and run nbgrader:\n  - The course name.\n  - The location of the nbgrader config.\n  - The instructors username.\n  - Graders' usernames.\n\nEnd users of the deployment should be able to:\n\n* Use the following Jupyter kernels:\n  - Python 3 IPython kernel with the main Python libraries for data science.\n  - Bash (https://github.com/takluyver/bash_kernel).\n* Sign in using their GitHub or Unix credentials.\n* Have a persistent home directory.\n* Have outbound network access.\n\n# Instructions\n\n1. Before deploying, for each host:\n  - Start the server running latest Ubuntu.\n  - Enable passwordless SSH access as `root`.\n  - Partition and format any local disks you want to mount.\n  - Make sure the server's hostname matches the fully qualified domain name (FQDN).\n  - Make sure there is a valid DNS entry for the server.\n  - If you not going to use letsencrypt, obtain a trusted SSL certificate and\n    key for the server at that FQDN.\n2. Edit the `./hosts` file to lists the FQDN's of the hosts in the jupyterhub_hosts\n   group.\n2. For each host, create a file in `./host_vars` with the name of the host, starting\n   from `./host_vars/hostname.example`.\n3. Create a `./security/cookie_secret` file by doing:\n\n\topenssl rand -hex 1024 \u003e ./security/cookie_secret\n\n4. If you are not using letsencrypt, install your SSL private key and certificate as\n   `./security/ssl.crt` and `./security/ssl.key`.\n5. Run `ansible-playbook` for the main deployment:\n\n\tansible-playbook deploy.yml\n\n6. SSH to the server and reload supervisor:\n\n\tsupervisorctl reload\n\n# To run nbgrader\n\nThe main nbgrader package will be installed in the above deployment. However, to run\nnbgrader's formgrade application or use its notebook extensions, additional steps are\nneeded.\n\nEach user who wants to use the notebook extension will need to run:\n\n\tnbgrader extension activate\n\t\nAfter the main instructor (`nbgrader_owner`) has logged into the system, run the\nfollowing command to deploy formgrade:\n\n\tansible-playbook deploy_formgrade.yml\n\nThen SSH to the server and restart jupyterhub and nbgrader by doing:\n\n\tsupervisorctl reload\n\n## Notes\n\n* To limit the deployment to certain hosts, add the `-l hostname` to these commands:\n\n    ansible-playbook -l hostname deploy.yml\n\n* The logs for `jupyterhub` are in `/var/log/jupyterhub`.\n* The logs for `nbgrader` are in `/var/log/nbgrader`.\n* If you are not using GitHub OAuth, you will need to manually create users using\n  `adduser`: `adduser --gecos \"\" username`.\n* Change the ansible configuration by editing `./ansible_cfg`.\n* To manage the jupyterhub and nbgrader services by SSH to the server and run\n  `supervisorctl jupyterhub [start|stop|restart]`\n\n## Saving and restoring users\n\nIn some situations, you may remount your user's home directories into a new instance that\ndoesn't have their user accounts, but has their home directories. When recreating the\nsame users it is important that they all have the same uids so the new users have\nownership of the home directories.\n\n**This is only relevant when using GitHub OAuth for users and authentication.**\n\nTo save the list of usernames and uids in `{{homedir}}/saved_users.txt`:\n\nansible-playbook saveusers.yml\n\nThen, when you run deploy.yml, it will look for this file and if it exists, will create\nthose users with those exact uids and home directories.\n\nYou can also manually create the users by running:\n\n\tpython3 create_users.py\n\nin the home directory.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzonca%2Fjupyterhub-deploy-data301","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzonca%2Fjupyterhub-deploy-data301","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzonca%2Fjupyterhub-deploy-data301/lists"}