Skip to content
This repository was archived by the owner on Jun 30, 2024. It is now read-only.

Commit 6a64102

Browse files
committed
Improve Docker setup:
- Refuse to install Docker under WSL. - Install tools in venv if it's activated. - Improve docs.
1 parent bd2c89f commit 6a64102

File tree

2 files changed

+47
-49
lines changed

2 files changed

+47
-49
lines changed

docker/README.rst

Lines changed: 22 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,21 @@ Docker Deployment
88
If you would prefer to install all the components directly on a server yourself,
99
see the `Manual Installation instructions <../docs/installation.html>`_.
1010

11-
1211
Using Docker, we can bring up the server without needing to install dependencies directly on
1312
the host. Instead, the software required to run the server will be installed in four separate
14-
docker containers (Runestone application, redis cache, postgres DB, jobe code compilation).
15-
13+
Docker containers (the Runestone application, redis cache, postgres DB, and Jobe code compilation).
1614

1715
.. note::
1816

1917
These instructions have been tested on Ubuntu 20.04 and should work on any version of Ubuntu 18.04+.
2018
Installation on older versions of Ubuntu or other Linux distributions may require adjustments.
21-
These instructions have also been tested on OS X. For Windows, use WSL, VirtualBox, or other similar virtualization software.
19+
These instructions have also been tested on OS X. For Windows, use `WSL2 <https://ubuntu.com/tutorials/install-ubuntu-on-wsl2-on-windows-10#1-overview>`_, VirtualBox, or other similar virtualization software.
20+
2221

22+
**Contents**
2323

24-
Contents
25-
--------
2624
.. contents::
25+
:local:
2726

2827

2928
Setup
@@ -40,18 +39,16 @@ To build a Docker application with the server and all its dependencies, download
4039
curl -fsSLO https://raw.githubusercontent.com/RunestoneInteractive/RunestoneServer/master/docker/docker_tools.py
4140
# See what build options are available.
4241
python3 docker_tools.py build --help
43-
# Run the build.
42+
# Run the build, choosing appropriate options for your case.
4443
python3 docker_tools.py build <your options here>
4544
46-
This will take a while. But once built, you will not need to rebuild the image unless you need to modify settings
47-
inside it. If you do need to modify a built image, you can either `shell into the built container <Shelling Inside>`_
48-
to make changes or rebuild the image.
45+
This will take a while. But once built, you will not need to rebuild the image unless you need to modify settings inside it. If you do need to modify a built image, you can either `shell into the built container <Shelling Inside>`_ to make changes or rebuild the image.
4946

5047
When this completes, **log out then back in** (reboot if using a VM) to update your group membership. Next, ``cd RunestoneServer``.
5148

5249
.. note::
5350

54-
All future commands should be run in the ``RunestoneServer`` directory unless instructions specify otherwise.
51+
All future commands should be run in the ``RunestoneServer`` directory unless instructions specify otherwise. After the first **successful** invocation of ``python3 docker_tools.py build``, use the (newly-installed) ``docker-tools`` command, instead of ``python3 docker_tools.py``. For example, ``docker-tools build <your options here>``.
5552

5653
.. note:: VirtualBox
5754

@@ -90,13 +87,11 @@ Python Settings
9087
You also will also likely want to configure some options in the Python code. These options
9188
will be in the file ``models/1.py`` (which is automatically created on the first build).
9289

93-
9490
Again, if you are installing for local development/testing you should not need to modify
9591
any of the settings. If you are installing for production, you will want/need to modify
9692
some of them (so that things like sending students emails for lost passwords work).
9793
See comments in the file for details.
9894

99-
10095
.. warning::
10196

10297
You will NOT want to check either ``.env`` or ``models/1.py`` into source control. The
@@ -128,45 +123,40 @@ To stop all containers use:
128123
129124
docker-compose stop
130125
131-
132126
To restart the containers, to reload configuration files or because you have added a new book,
133127
do:
134128

135129
.. code-block:: bash
136130
137131
docker-compose restart
138132
139-
140133
Or to just restart the Runestone container (which is generally the only one that needs to be updated):
141134

142135
.. code-block:: bash
143136
144137
docker-compose restart runestone
145138
146-
147139
If you ever want to completely wipe the containers, stop them and then do:
148140

149141
.. code-block:: bash
150142
151143
docker-compose rm
152144
153145
154-
4. Install `rsmanage`
155-
156-
The rsmanage command will run many useful commands inside the container for you. With rsmanage you can:
146+
Introducing `rsmanage`
147+
^^^^^^^^^^^^^^^^^^^^^^
148+
The ``rsmanage`` command will run many useful commands inside the container for you. With ``rsmanage`` you can:
157149

158150
* Add a course - ``rsmanage addcourse``
159151
* Add a user - ``rsmanage adduser``
160-
* Get infromation about a course ``rsmanage courseinfo``
152+
* Get information about a course ``rsmanage courseinfo``
161153
* Build a book - ``rsmanage build --course bookname``
162154
* Get a database shell in the current database ``rsmanage db``
163155

164-
And lots of other things. Just type ``rsmanage`` for a list of things it can do. For a list of options just type rsmanage and the subcommand you want followed by `--help`
156+
...and lots of other things. Just type ``rsmanage`` for a list of things it can do. For a list of options just type ``rsmanage`` and the subcommand you want followed by ``--help``; for example, ``rsmanage build --help``.
165157

166-
To install rsmanage type ``pip install -e /path/to/RunestoneServer/rsmanage``
167158

168-
169-
1. Add Books
159+
4. Add Books
170160
**************************
171161

172162
To add a book, you need to add its source code to the ``RunestoneServer/books/`` directory. For an existing
@@ -179,7 +169,6 @@ To add a book, you need to add its source code to the ``RunestoneServer/books/``
179169
git clone https://github.com/RunestoneInteractive/thinkcspy.git
180170
cd ..
181171
182-
183172
.. warning::
184173

185174
It is important that the folder name for the book matches the ``project_name`` set in its ``pavement.py``.
@@ -188,7 +177,7 @@ To add a book, you need to add its source code to the ``RunestoneServer/books/``
188177
If there is a mismatch, you will want to rename the folder you cloned the code into so that it
189178
matches the ``project_name``.
190179

191-
After cloning a book, you may need to add it to the database. Most of the standard books are already there, but you can use ``rsmanage addcourse`` to add it if needed.
180+
After cloning a book, you may need to add it to the database. Most of the standard books are already there, but you can use ``rsmanage addcourse`` to add it if needed.
192181
You also need to rebuild after making any edits/updates to a book.
193182

194183
.. code-block:: bash
@@ -201,7 +190,6 @@ You can also have ``rsmanage`` clone the book for you the first time you want to
201190
202191
rsmanage build --course thinkcspy --clone https://github.com/RunestoneInteractive/thinkcspy.git
203192
204-
205193
.. note::
206194

207195
Most Runestone books set ``master_url`` to ``get_master_url()`` in their ``pavement.py`` file. However, if the book
@@ -210,20 +198,19 @@ You can also have ``rsmanage`` clone the book for you the first time you want to
210198
If you are running docker on a remote host then make sure to set it to the name of the remote host.
211199

212200

213-
1. Add Courses
201+
5. Add Courses
214202
**************************
215203

216204
To add a course based on a book, run the ``rsmanage addcourse`` script. If you run it just like
217-
that it will prompt you for all of the necessary details. Probably the **most important** thing
205+
that it will prompt you for all of the necessary details. Probably the **most important** thing
218206
to point out is that if this is a new book the first time you add it you want to make sure that the
219-
basecourse and the course-name are the same. If you are creating your own course but want it
207+
basecourse and the course-name are the same. If you are creating your own course but want it
220208
based on an existing book then make sure to use the correct base course name.
221209

222210
.. code-block:: bash
223211
224212
rsmanage addcourse
225213
226-
227214
It will ask for:
228215

229216
**Course Name**: The short name to identify this course/section (do **NOT** include any spaces). e.g. ``yourname-cs1-fall2021``
@@ -243,7 +230,8 @@ You do not have to restart the server to make use of the course.
243230
Some of the default books already have "default" courses with the same name as the book. If you try to create
244231
a course with a name like ``thinkcspy`` you will be told that the course name is the same as the book.
245232

246-
1. Add a User
233+
234+
6. Add a User
247235
**************************
248236

249237
To add an initial instructor account to the course you have created, you can either create a new user or add
@@ -256,15 +244,13 @@ they should be made an instructor.
256244
257245
rsmanage adduser
258246
259-
260247
Or, if you already have an account that you want to add as an instructor to the new course, you can use the
261248
``rsmanage`` command to execute **addinstructor** which will prompt you for a username and course name:
262249

263250
.. code-block:: bash
264251
265252
rsmanage addinstructor
266253
267-
268254
Neither of these will require restarting the server.
269255

270256
Once you have logged in as an instructor, you can bulk add students through the web interface.
@@ -297,7 +283,6 @@ To re-build an image:
297283
# Actually run the build (add options as desired)
298284
docker-tools build
299285
300-
301286
To force a rebuild, make sure the containers are `stopped <4. Starting/Stopping>`_, then rerun the build
302287
command. The build process caches results from previous builds and should complete much more rapidly. However, the
303288
cache can cause issues if you modify a file that the system is checking for changes. If you need to force a
@@ -319,7 +304,6 @@ the RunestoneServer directory do:
319304
320305
docker-tools shell
321306
322-
323307
Remember that the folder under web2py applications/runestone is bound to your host,
324308
so **do not edit files from inside the container** otherwise they will have a change
325309
in permissions on the host.
@@ -399,10 +383,10 @@ If you are writing your own book you will want to get that book set up properly
399383
system. You need to do the following:
400384

401385
1. Run the command ``rsmanage addcourse`` Use the project name you configured in ``pavement.py`` as
402-
the name of BOTH the course and the basecourse when it asks.
386+
the name of BOTH the course and the basecourse when it asks.
403387

404388

405-
1. Now that your course is registered rebuild it using the command ``rsmanage build --course <book_name>`` command.
389+
1. Now that your course is registered rebuild it using the command ``rsmanage build --course <book_name>`` command.
406390

407391
2. If this book is a PreTeXt book you will need to navigate to the directory that contains the
408392
``runestone-manifest.xml`` file and run the command:

docker/docker_tools.py

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,7 @@
6666
# ---------------------------
6767
# Everything after this depends on Unix utilities.
6868
if sys.platform == "win32":
69-
print("Run this program in WSL/VirtualBox/VMWare/etc.")
70-
sys.exit()
69+
sys.exit("Run this program in WSL/VirtualBox/VMWare/etc.")
7170

7271
# See if we're root.
7372
is_root = (
@@ -111,13 +110,26 @@ def check_install_curl() -> None:
111110
check_install("curl --version", "curl")
112111

113112

113+
# Check if we're running in WSL -- don't install Docker if so.
114+
def check_in_wsl() -> None:
115+
if "WSL" in Path("/proc/version").read_text():
116+
sys.exit(
117+
"Docker for Windows not detected while running in WSL. You must install this before proceeding."
118+
)
119+
120+
121+
# Outside a venv, install locally.
122+
def pip_user() -> str:
123+
return "" if in_venv else "--user"
124+
125+
114126
# The working directory of this script.
115127
wd = Path(__file__).resolve().parent
116128
sys.path.append(str(wd / "../tests"))
117129
# fmt: off
118130
try:
119131
# This unused import triggers the script download if it's not present. This only happens outside the container.
120-
import ci_utils
132+
import ci_utils # noqa: F401
121133
except ImportError:
122134
assert not os.environ.get("IN_DOCKER")
123135
check_install_curl()
@@ -130,7 +142,7 @@ def check_install_curl() -> None:
130142
],
131143
check=True,
132144
)
133-
from ci_utils import chdir, env, is_darwin, is_linux, pushd, xqt
145+
from ci_utils import chdir, env, is_darwin, pushd, xqt # noqa: E402
134146
# fmt: on
135147

136148
# Third-party bootstrap
@@ -150,8 +162,8 @@ def check_install_curl() -> None:
150162
# Outside a venv, install locally.
151163
user = " " if in_venv else "--user "
152164
xqt(
153-
f"{sys.executable} -m pip install {user}--upgrade pip",
154-
f"{sys.executable} -m pip install {user}--upgrade click",
165+
f"{sys.executable} -m pip install {pip_user()} --upgrade pip",
166+
f"{sys.executable} -m pip install {pip_user()} --upgrade click",
155167
)
156168
# If pip is upgraded, it won't find click. `Re-load sys.path <https://stackoverflow.com/a/25384923/16038919>`_ to fix this.
157169
reload(site)
@@ -360,6 +372,7 @@ def _build_phase_0(
360372
try:
361373
xqt("docker --version")
362374
except subprocess.CalledProcessError as e:
375+
check_in_wsl()
363376
check_install_curl()
364377
print(f"Unable to run docker: {e} Installing Docker...")
365378
# Use the `convenience script <https://docs.docker.com/engine/install/ubuntu/#install-using-the-convenience-script>`_.
@@ -378,6 +391,7 @@ def _build_phase_0(
378391
try:
379392
xqt("docker-compose --version")
380393
except subprocess.CalledProcessError as e:
394+
check_in_wsl()
381395
print(f"Unable to run docker-compose: {e} Installing...")
382396
# This is from the `docker-compose install instructions <https://docs.docker.com/compose/install/#install-compose-on-linux-systems>`_.
383397
xqt(
@@ -395,7 +409,7 @@ def _build_phase_0(
395409
if clone_all != "RunestoneInteractive":
396410
# Print Warning and provide countdown to abort script
397411
click.secho(
398-
"Warning: Clone-all flag was initalized and will override any other clone flag specified!",
412+
"Warning: Clone-all flag was initialized and will override any other clone flag specified!",
399413
fg="red",
400414
)
401415
# Set each individual flag to the clone-all argument
@@ -555,19 +569,19 @@ def _build_phase_0(
555569
did_group_add = True
556570
docker_sudo = True
557571

558-
# Provide server-related CLIs.
572+
# Provide server-related CLIs. While installing this sooner would be great, we can't assume that the prereqs (the downloaded repo) are available.
559573
check_install(f"{sys.executable} -m pip --version", "python3-pip")
560574
xqt(
561-
f"{sys.executable} -m pip install --user -e docker",
562-
f"{sys.executable} -m pip install --user -e rsmanage",
575+
f"{sys.executable} -m pip install {pip_user()} -e docker",
576+
f"{sys.executable} -m pip install {pip_user()} -e rsmanage",
563577
)
564578

565579
# Run the Docker build.
566580
xqt(
567581
f'ENABLE_BUILDKIT=1{" sudo" if docker_sudo else ""} docker build -t runestone/server . --build-arg DOCKER_BUILD_ARGS="{" ".join(sys.argv[1:])}" --progress plain {" ".join(passthrough)}'
568582
)
569583

570-
# Print thesse messages last; otherwise, it will be lost in all the build noise.
584+
# Print these messages last; otherwise, it will be lost in all the build noise.
571585
if change_dir:
572586
print(
573587
"\n"

0 commit comments

Comments
 (0)